diff options
author | Jisi Liu <liujisi@google.com> | 2017-08-21 10:39:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-21 10:39:27 -0700 |
commit | ba4e54724d2e6a1881c4fe88664d81fbacaf8c08 (patch) | |
tree | 5451ab616f035b92d006e51ec01b4c0dabb3f6d0 | |
parent | 472f700884a2cd4e9b621c5e4b706a9b6de7c870 (diff) | |
parent | 139775ccc040a07e07c5407e34834dab27928cbc (diff) |
Merge pull request #3529 from pherl/merge3.4.x
Merge 3.4.x into master
310 files changed, 21043 insertions, 8291 deletions
@@ -97,6 +97,7 @@ cc_library( "src/google/protobuf/arena.cc", "src/google/protobuf/arenastring.cc", "src/google/protobuf/extension_set.cc", + "src/google/protobuf/generated_message_table_driven_lite.cc", "src/google/protobuf/generated_message_util.cc", "src/google/protobuf/io/coded_stream.cc", "src/google/protobuf/io/zero_copy_stream.cc", @@ -161,7 +162,6 @@ cc_library( "src/google/protobuf/service.cc", "src/google/protobuf/source_context.pb.cc", "src/google/protobuf/struct.pb.cc", - "src/google/protobuf/stubs/io_win32.cc", "src/google/protobuf/stubs/mathlimits.cc", "src/google/protobuf/stubs/substitute.cc", "src/google/protobuf/text_format.cc", @@ -229,7 +229,6 @@ 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", @@ -374,7 +373,6 @@ 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", @@ -473,7 +471,6 @@ COMMON_TEST_SRCS = [ # AUTOGEN(common_test_srcs) "src/google/protobuf/arena_test_util.cc", "src/google/protobuf/map_test_util.cc", - "src/google/protobuf/stubs/io_win32.cc", "src/google/protobuf/test_util.cc", "src/google/protobuf/testing/file.cc", "src/google/protobuf/testing/googletest.cc", @@ -513,6 +510,7 @@ cc_test( "src/google/protobuf/arenastring_unittest.cc", "src/google/protobuf/compiler/command_line_interface_unittest.cc", "src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc", + "src/google/protobuf/compiler/cpp/cpp_move_unittest.cc", "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", diff --git a/CHANGES.txt b/CHANGES.txt index ccc8ff94..c83da2d6 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,135 @@ +2017-08-14 version 3.4.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: We are going to bring unknown fields + back into proto3. In this release, some languages start to support + preserving unknown fields in proto3, controlled by flags/options. Some + languages also introduce explicit APIs to drop unknown fields for + migration. Please read the change log sections by languages for details. + For general timeline and plan: + + https://docs.google.com/document/d/1KMRX-G91Aa-Y2FkEaHeeviLRRNblgIahbsk4wA14gRk/view + + For issues and discussions: + + https://github.com/google/protobuf/issues/272 + + - Make C++ implementation C++11 only: we plan to require C++11 to build + protobuf code starting from 3.5.0 or 3.6.0 release, after unknown fields + semantic changes are finished. Please join this + github issue: + + https://github.com/google/protobuf/issues/2780 + + to provide your feedback. + + General + * Extension ranges now accept options and are customizable. + * "reserve" keyword now supports “max” in field number ranges, + e.g. reserve 1000 to max; + + C++ + * Proto3 messages are now able to preserve unknown fields. The default + behavior is still to drop unknowns, which will be flipped in a future + release. If you rely on unknowns fields being dropped. Please use + Message::DiscardUnknownFields() explicitly. + * Packable proto3 fields are now packed by default in serialization. + * Following C++11 features are introduced when C++11 is available: + - move-constructor and move-assignment are introduced to messages + - Repeated fields constructor now takes std::initializer_list + - rvalue setters are introduced for string fields + * Experimental Table-Driven parsing and serialization available to test. To + enable it, pass in table_driven_parsing table_driven_serialization protoc + generator flags for C++ + + $ protoc --cpp_out=table_driven_parsing,table_driven_serialization:./ \ + test.proto + + * lite generator parameter supported by the generator. Once set, all generated + files, use lite runtime regardless of the optimizer_for setting in the + .proto file. + * Various optimizations to make C++ code more performant on PowerPC platform + * Fixed maps data corruption when the maps are modified by both reflection API + and generated API. + * Deterministic serialization on maps reflection now uses stable sort. + * file() accessors are introduced to various *Descriptor classes to make + writing template function easier. + * ByteSize() and SpaceUsed() are deprecated.Use ByteSizeLong() and + SpaceUsedLong() instead + * Consistent hash function is used for maps in DEBUG and NDEBUG build. + * "using namespace std" is removed from stubs/common.h + * Various performance optimizations and bug fixes + + Java + * Introduced new parser API DiscardUnknownFieldsParser in preparation of + proto3 unknown fields preservation change. Users who want to drop unknown + fields should migrate to use this new parser API. For example: + + Parser<Foo> parser = DiscardUnknownFieldsParser.wrap(Foo.parser()); + Foo foo = parser.parseFrom(input); + + * Introduced new TextFormat API printUnicodeFieldValue() that prints field + value without escaping unicode characters. + * Added Durations.compare(Duration, Duration) and + Timestamps.compare(Timestamp, Timestamp). + * JsonFormat now accepts base64url encoded bytes fields. + * Optimized CodedInputStream to do less copies when parsing large bytes + fields. + * Optimized TextFormat to allocate less memory when printing. + + Python + * SerializeToString API is changed to SerializeToString(self, **kwargs), + deterministic parameter is accepted for deterministic serialization. + * Added sort_keys parameter in json format to make the output deterministic. + * Added indent parameter in json format. + * Added extension support in json format. + * Added __repr__ support for repeated field in cpp implementation. + * Added file in FieldDescriptor. + * Added pretty-print filter to text format. + * Services and method descriptors are always printed even if generic_service + option is turned off. + * Note: AppEngine 2.5 is deprecated on June 2017 that AppEngine 2.5 will + never update protobuf runtime. Users who depend on AppEngine 2.5 should use + old protoc. + + PHP + * Support PHP generic services. Specify file option php_generic_service=true + to enable generating service interface. + * Message, repeated and map fields setters take value instead of reference. + * Added map iterator in c extension. + * Support json encode/decode. + * Added more type info in getter/setter phpdoc + * Fixed the problem that c extension and php implementation cannot be used + together. + * Added file option php_namespace to use custom php namespace instead of + package. + * Added fluent setter. + * Added descriptor API in runtime for custom encode/decode. + * Various bug fixes. + + Objective-C + * Fix for GPBExtensionRegistry copying and add tests. + * Optimize GPBDictionary.m codegen to reduce size of overall library by 46K + per architecture. + * Fix some cases of reading of 64bit map values. + * Properly error on a tag with field number zero. + * Preserve unknown fields in proto3 syntax files. + * Document the exceptions on some of the writing apis. + + C# + * Implemented IReadOnlyDictionary<K,V> in MapField<K,V> + * Added TryUnpack method for Any message in addition to Unpack. + * Converted C# projects to MSBuild (csproj) format. + + Ruby + * Several bug fixes. + + Javascript + * Added support of field option js_type. Now one can specify the JS type of a + 64-bit integer field to be string in the generated code by adding option + [jstype = JS_STRING] on the field. + 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 diff --git a/Makefile.am b/Makefile.am index fafe1d25..52d7ce9d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -207,6 +207,7 @@ java_EXTRA_DIST= java/core/src/main/java/com/google/protobuf/ByteString.java \ java/core/src/main/java/com/google/protobuf/CodedInputStream.java \ java/core/src/main/java/com/google/protobuf/CodedOutputStream.java \ + java/core/src/main/java/com/google/protobuf/DiscardUnknownFieldsParser.java \ java/core/src/main/java/com/google/protobuf/Descriptors.java \ java/core/src/main/java/com/google/protobuf/DoubleArrayList.java \ java/core/src/main/java/com/google/protobuf/DynamicMessage.java \ @@ -281,6 +282,7 @@ java_EXTRA_DIST= java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java \ java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java \ java/core/src/test/java/com/google/protobuf/DescriptorsTest.java \ + java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java \ java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java \ java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java \ java/core/src/test/java/com/google/protobuf/EnumTest.java \ @@ -317,6 +319,7 @@ java_EXTRA_DIST= java/core/src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java \ java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java \ java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java \ + java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java \ java/core/src/test/java/com/google/protobuf/TestUtil.java \ java/core/src/test/java/com/google/protobuf/TestUtilLite.java \ java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java \ @@ -756,6 +759,7 @@ python_EXTRA_DIST= \ python/google/protobuf/json_format.py \ python/google/protobuf/message.py \ python/google/protobuf/message_factory.py \ + python/google/protobuf/python_protobuf.h \ python/google/protobuf/proto_builder.py \ python/google/protobuf/pyext/README \ python/google/protobuf/pyext/__init__.py \ @@ -785,13 +789,13 @@ python_EXTRA_DIST= \ 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 \ python/google/protobuf/symbol_database.py \ python/google/protobuf/text_encoding.py \ python/google/protobuf/text_format.py \ + python/release.sh \ python/mox.py \ python/setup.cfg \ python/setup.py \ @@ -911,6 +915,27 @@ js_EXTRA_DIST= \ js/compatibility_tests/v3.0.0/testempty.proto \ js/compatibility_tests/v3.0.0/test.proto \ js/compatibility_tests/v3.0.0/test.sh \ + js/compatibility_tests/v3.1.0/testempty.proto \ + js/compatibility_tests/v3.1.0/testbinary.proto \ + js/compatibility_tests/v3.1.0/test5.proto \ + js/compatibility_tests/v3.1.0/test4.proto \ + js/compatibility_tests/v3.1.0/test3.proto \ + js/compatibility_tests/v3.1.0/test2.proto \ + js/compatibility_tests/v3.1.0/test.proto \ + js/compatibility_tests/v3.1.0/proto3_test.proto \ + js/compatibility_tests/v3.1.0/proto3_test.js \ + js/compatibility_tests/v3.1.0/message_test.js \ + js/compatibility_tests/v3.1.0/maps_test.js \ + js/compatibility_tests/v3.1.0/debug_test.js \ + js/compatibility_tests/v3.1.0/data.proto \ + js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto \ + js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto \ + js/compatibility_tests/v3.1.0/binary/writer_test.js \ + js/compatibility_tests/v3.1.0/binary/utils_test.js \ + js/compatibility_tests/v3.1.0/binary/reader_test.js \ + js/compatibility_tests/v3.1.0/binary/proto_test.js \ + js/compatibility_tests/v3.1.0/binary/decoder_test.js \ + js/compatibility_tests/v3.1.0/binary/arith_test.js \ js/data.proto \ js/debug.js \ js/debug_test.js \ diff --git a/Protobuf.podspec b/Protobuf.podspec index 249911c5..88bd5b7d 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.3.2' + s.version = '3.4.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/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index a16081a2..deb6de3b 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -18,6 +18,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.h" include\google copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.pb.h" include\google\protobuf\any.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.pb.h" include\google\protobuf\api.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena.h" include\google\protobuf\arena.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena_impl.h" include\google\protobuf\arena_impl.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenastring.h" include\google\protobuf\arenastring.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h" include\google\protobuf\compiler\code_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h" include\google\protobuf\compiler\command_line_interface.h @@ -36,7 +37,6 @@ 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 @@ -52,7 +52,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven.h" include\google\protobuf\generated_message_table_driven.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven.h" include\google\protobuf\generated_message_table_driven.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h" include\google\protobuf\io\gzip_stream.h @@ -100,7 +99,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" includ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h" include\google\protobuf\stubs\fastmem.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\io_win32.h" include\google\protobuf\stubs\io_win32.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h" include\google\protobuf\stubs\mutex.h diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake index cf72e2fe..9e1fab0a 100644 --- a/cmake/libprotobuf-lite.cmake +++ b/cmake/libprotobuf-lite.cmake @@ -2,6 +2,7 @@ set(libprotobuf_lite_files ${protobuf_source_dir}/src/google/protobuf/arena.cc ${protobuf_source_dir}/src/google/protobuf/arenastring.cc ${protobuf_source_dir}/src/google/protobuf/extension_set.cc + ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven_lite.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_util.cc ${protobuf_source_dir}/src/google/protobuf/io/coded_stream.cc ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream.cc diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index 8ac8d479..9f2aa0c7 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -88,12 +88,10 @@ 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 ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/io_win32.cc ) set(libprotoc_headers @@ -105,7 +103,6 @@ set(libprotoc_headers ${protobuf_source_dir}/src/google/protobuf/compiler/parser.h ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.h ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.h - ${protobuf_source_dir}/src/google/protobuf/compiler/profile.pb.h ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.h ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.h ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_enum.h diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 31f22575..389f6a7b 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -123,6 +123,7 @@ set(tests_files ${protobuf_source_dir}/src/google/protobuf/arenastring_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/command_line_interface_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/metadata_test.cc @@ -160,7 +161,6 @@ set(tests_files ${protobuf_source_dir}/src/google/protobuf/stubs/bytestream_unittest.cc ${protobuf_source_dir}/src/google/protobuf/stubs/common_unittest.cc ${protobuf_source_dir}/src/google/protobuf/stubs/int128_unittest.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/io_win32.cc ${protobuf_source_dir}/src/google/protobuf/stubs/io_win32_unittest.cc ${protobuf_source_dir}/src/google/protobuf/stubs/once_unittest.cc ${protobuf_source_dir}/src/google/protobuf/stubs/status_test.cc @@ -200,7 +200,6 @@ target_link_libraries(tests libprotoc libprotobuf gmock_main) set(test_plugin_files ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc - ${protobuf_source_dir}/src/google/protobuf/stubs/io_win32.cc ${protobuf_source_dir}/src/google/protobuf/testing/file.cc ${protobuf_source_dir}/src/google/protobuf/testing/file.h ${protobuf_source_dir}/src/google/protobuf/compiler/test_plugin.cc diff --git a/configure.ac b/configure.ac index e75bdbaa..04f7eb7a 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.3.2],[protobuf@googlegroups.com],[protobuf]) +AC_INIT([Protocol Buffers],[3.4.0],[protobuf@googlegroups.com],[protobuf]) AM_MAINTAINER_MODE([enable]) diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index 4630729a..b1ff6883 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -1605,9 +1605,10 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, "BytesField", REQUIRED, R"({"optionalBytes": "AQI="})", R"(optional_bytes: "\x01\x02")"); - ExpectParseFailureForJson( - "BytesFieldInvalidBase64Characters", REQUIRED, - R"({"optionalBytes": "-_=="})"); + RunValidJsonTest( + "BytesFieldBase64Url", RECOMMENDED, + R"({"optionalBytes": "-_"})", + R"(optional_bytes: "\xfb")"); // Message fields. RunValidJsonTest( diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt index c8b0fecf..8c328890 100644 --- a/conformance/failure_list_cpp.txt +++ b/conformance/failure_list_cpp.txt @@ -12,6 +12,8 @@ Recommended.FieldMaskPathsDontRoundTrip.JsonOutput Recommended.FieldMaskTooManyUnderscore.JsonOutput Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedFalse Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedTrue +Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput +Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter Recommended.Proto3.JsonInput.FieldNameDuplicate Recommended.Proto3.JsonInput.FieldNameDuplicateDifferentCasing1 diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt index e69de29b..2a20aa78 100644 --- a/conformance/failure_list_csharp.txt +++ b/conformance/failure_list_csharp.txt @@ -0,0 +1,2 @@ +Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput +Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput diff --git a/conformance/failure_list_php.txt b/conformance/failure_list_php.txt index e06d07a1..2f91a3f5 100644 --- a/conformance/failure_list_php.txt +++ b/conformance/failure_list_php.txt @@ -1,6 +1,8 @@ Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput Recommended.FieldMaskPathsDontRoundTrip.JsonOutput Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput +Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator Recommended.Proto3.JsonInput.DurationHas9FractionalDigits.Validator diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index 7b010178..062c22a8 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -1,10 +1,11 @@ +Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput +Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.DoubleFieldInfinityNotQuoted Recommended.Proto3.JsonInput.DoubleFieldNanNotQuoted Recommended.Proto3.JsonInput.DoubleFieldNegativeInfinityNotQuoted Recommended.Proto3.JsonInput.FloatFieldInfinityNotQuoted Recommended.Proto3.JsonInput.FloatFieldNanNotQuoted Recommended.Proto3.JsonInput.FloatFieldNegativeInfinityNotQuoted -Required.Proto3.JsonInput.BytesFieldInvalidBase64Characters Required.Proto3.JsonInput.DoubleFieldTooSmall Required.Proto3.JsonInput.EnumFieldUnknownValue.Validator Required.Proto3.JsonInput.FloatFieldTooLarge diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt index ab946d9d..e2c258de 100644 --- a/conformance/failure_list_python_cpp.txt +++ b/conformance/failure_list_python_cpp.txt @@ -7,13 +7,14 @@ # TODO(haberman): insert links to corresponding bugs tracking the issue. # Should we use GitHub issues or the Google-internal bug tracker? +Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput +Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.DoubleFieldInfinityNotQuoted Recommended.Proto3.JsonInput.DoubleFieldNanNotQuoted Recommended.Proto3.JsonInput.DoubleFieldNegativeInfinityNotQuoted Recommended.Proto3.JsonInput.FloatFieldInfinityNotQuoted Recommended.Proto3.JsonInput.FloatFieldNanNotQuoted Recommended.Proto3.JsonInput.FloatFieldNegativeInfinityNotQuoted -Required.Proto3.JsonInput.BytesFieldInvalidBase64Characters Required.Proto3.JsonInput.DoubleFieldTooSmall Required.Proto3.JsonInput.EnumFieldUnknownValue.Validator Required.Proto3.JsonInput.FloatFieldTooLarge diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt index a8d2e3f5..45cfaca6 100644 --- a/conformance/failure_list_ruby.txt +++ b/conformance/failure_list_ruby.txt @@ -1,6 +1,8 @@ Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput Recommended.FieldMaskPathsDontRoundTrip.JsonOutput Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput +Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator Recommended.Proto3.JsonInput.DurationHas9FractionalDigits.Validator diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 95e6b04a..d32fd943 100644 --- a/csharp/Google.Protobuf.Tools.nuspec +++ b/csharp/Google.Protobuf.Tools.nuspec @@ -5,7 +5,7 @@ <title>Google Protocol Buffers tools</title> <summary>Tools for Protocol Buffers - Google's data interchange format.</summary> <description>See project site for more info.</description> - <version>3.3.2</version> + <version>3.4.0</version> <authors>Google Inc.</authors> <owners>protobuf-packages</owners> <licenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</licenseUrl> diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index 46418e39..1d21fdc5 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -4,7 +4,7 @@ <Description>C# runtime library for Protocol Buffers - Google's data interchange format.</Description> <Copyright>Copyright 2015, Google Inc.</Copyright> <AssemblyTitle>Google Protocol Buffers</AssemblyTitle> - <VersionPrefix>3.3.0</VersionPrefix> + <VersionPrefix>3.4.0</VersionPrefix> <Authors>Google Inc.</Authors> <TargetFrameworks>netstandard1.0;net451</TargetFrameworks> <GenerateDocumentationFile>true</GenerateDocumentationFile> diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs index 6c605f3c..8311a2c6 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs @@ -35,7 +35,7 @@ namespace Google.Protobuf.Reflection { "LnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvEi0KB29wdGlvbnMYCCAB", "KAsyHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMSOQoQc291cmNlX2Nv", "ZGVfaW5mbxgJIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5m", - "bxIOCgZzeW50YXgYDCABKAki8AQKD0Rlc2NyaXB0b3JQcm90bxIMCgRuYW1l", + "bxIOCgZzeW50YXgYDCABKAkiqQUKD0Rlc2NyaXB0b3JQcm90bxIMCgRuYW1l", "GAEgASgJEjQKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxk", "RGVzY3JpcHRvclByb3RvEjgKCWV4dGVuc2lvbhgGIAMoCzIlLmdvb2dsZS5w", "cm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90bxI1CgtuZXN0ZWRfdHlwZRgD", @@ -47,114 +47,119 @@ namespace Google.Protobuf.Reflection { "b3RvEjAKB29wdGlvbnMYByABKAsyHy5nb29nbGUucHJvdG9idWYuTWVzc2Fn", "ZU9wdGlvbnMSRgoOcmVzZXJ2ZWRfcmFuZ2UYCSADKAsyLi5nb29nbGUucHJv", "dG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2USFQoNcmVzZXJ2", - "ZWRfbmFtZRgKIAMoCRosCg5FeHRlbnNpb25SYW5nZRINCgVzdGFydBgBIAEo", - "BRILCgNlbmQYAiABKAUaKwoNUmVzZXJ2ZWRSYW5nZRINCgVzdGFydBgBIAEo", - "BRILCgNlbmQYAiABKAUivAUKFEZpZWxkRGVzY3JpcHRvclByb3RvEgwKBG5h", - "bWUYASABKAkSDgoGbnVtYmVyGAMgASgFEjoKBWxhYmVsGAQgASgOMisuZ29v", - "Z2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsEjgKBHR5", - "cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJv", - "dG8uVHlwZRIRCgl0eXBlX25hbWUYBiABKAkSEAoIZXh0ZW5kZWUYAiABKAkS", - "FQoNZGVmYXVsdF92YWx1ZRgHIAEoCRITCgtvbmVvZl9pbmRleBgJIAEoBRIR", - "Cglqc29uX25hbWUYCiABKAkSLgoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5w", - "cm90b2J1Zi5GaWVsZE9wdGlvbnMitgIKBFR5cGUSDwoLVFlQRV9ET1VCTEUQ", - "ARIOCgpUWVBFX0ZMT0FUEAISDgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlO", - "VDY0EAQSDgoKVFlQRV9JTlQzMhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZ", - "UEVfRklYRUQzMhAHEg0KCVRZUEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkS", - "DgoKVFlQRV9HUk9VUBAKEhAKDFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllU", - "RVMQDBIPCgtUWVBFX1VJTlQzMhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVf", - "U0ZJWEVEMzIQDxIRCg1UWVBFX1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQ", - "ERIPCgtUWVBFX1NJTlQ2NBASIkMKBUxhYmVsEhIKDkxBQkVMX09QVElPTkFM", - "EAESEgoOTEFCRUxfUkVRVUlSRUQQAhISCg5MQUJFTF9SRVBFQVRFRBADIlQK", - "FE9uZW9mRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSLgoHb3B0aW9u", - "cxgCIAEoCzIdLmdvb2dsZS5wcm90b2J1Zi5PbmVvZk9wdGlvbnMijAEKE0Vu", - "dW1EZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRI4CgV2YWx1ZRgCIAMo", - "CzIpLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8S", - "LQoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9u", - "cyJsChhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRIO", - "CgZudW1iZXIYAiABKAUSMgoHb3B0aW9ucxgDIAEoCzIhLmdvb2dsZS5wcm90", - "b2J1Zi5FbnVtVmFsdWVPcHRpb25zIpABChZTZXJ2aWNlRGVzY3JpcHRvclBy", - "b3RvEgwKBG5hbWUYASABKAkSNgoGbWV0aG9kGAIgAygLMiYuZ29vZ2xlLnBy", - "b3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bxIwCgdvcHRpb25zGAMgASgL", - "Mh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIsEBChVNZXRob2RE", - "ZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIg", - "ASgJEhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5n", - "b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFt", - "aW5nGAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVm", - "YWxzZSLwBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK", - "FGphdmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVf", - "ZmlsZXMYCiABKAg6BWZhbHNlEikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2Fu", - "ZF9oYXNoGBQgASgIQgIYARIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg", - "ASgIOgVmYWxzZRJGCgxvcHRpbWl6ZV9mb3IYCSABKA4yKS5nb29nbGUucHJv", - "dG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlOgVTUEVFRBISCgpnb19w", - "YWNrYWdlGAsgASgJEiIKE2NjX2dlbmVyaWNfc2VydmljZXMYECABKAg6BWZh", - "bHNlEiQKFWphdmFfZ2VuZXJpY19zZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoT", - "cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USIwoUcGhwX2dlbmVy", - "aWNfc2VydmljZXMYEyABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYFyABKAg6", - "BWZhbHNlEh8KEGNjX2VuYWJsZV9hcmVuYXMYHyABKAg6BWZhbHNlEhkKEW9i", - "amNfY2xhc3NfcHJlZml4GCQgASgJEhgKEGNzaGFycF9uYW1lc3BhY2UYJSAB", - "KAkSFAoMc3dpZnRfcHJlZml4GCcgASgJEhgKEHBocF9jbGFzc19wcmVmaXgY", - "KCABKAkSFQoNcGhwX25hbWVzcGFjZRgpIAEoCRJDChR1bmludGVycHJldGVk", - "X29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRl", - "ZE9wdGlvbiI6CgxPcHRpbWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJ", - "WkUQAhIQCgxMSVRFX1JVTlRJTUUQAyoJCOgHEICAgIACSgQIJhAnIvIBCg5N", - "ZXNzYWdlT3B0aW9ucxImChdtZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEo", - "CDoFZmFsc2USLgofbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgC", - "IAEoCDoFZmFsc2USGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFw", - "X2VudHJ5GAcgASgIEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIk", - "Lmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICA", - "gAJKBAgIEAlKBAgJEAoingMKDEZpZWxkT3B0aW9ucxI6CgVjdHlwZRgBIAEo", - "DjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklO", - "RxIOCgZwYWNrZWQYAiABKAgSPwoGanN0eXBlGAYgASgOMiQuZ29vZ2xlLnBy", - "b3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGU6CUpTX05PUk1BTBITCgRsYXp5", - "GAUgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRITCgR3", - "ZWFrGAogASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByAD", - "KAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiIvCgVD", - "VHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIi", - "NQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpT", - "X05VTUJFUhACKgkI6AcQgICAgAJKBAgEEAUiXgoMT25lb2ZPcHRpb25zEkMK", - "FHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1", - "Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIikwEKC0VudW1PcHRp", - "b25zEhMKC2FsbG93X2FsaWFzGAIgASgIEhkKCmRlcHJlY2F0ZWQYAyABKAg6", - "BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2ds", - "ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgF", - "EAYifQoQRW51bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVm", - "YWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUu", - "cHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACInsKDlNl", - "cnZpY2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVu", + "ZWRfbmFtZRgKIAMoCRplCg5FeHRlbnNpb25SYW5nZRINCgVzdGFydBgBIAEo", + "BRILCgNlbmQYAiABKAUSNwoHb3B0aW9ucxgDIAEoCzImLmdvb2dsZS5wcm90", + "b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnMaKwoNUmVzZXJ2ZWRSYW5nZRIN", + "CgVzdGFydBgBIAEoBRILCgNlbmQYAiABKAUiZwoVRXh0ZW5zaW9uUmFuZ2VP", + "cHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2ds", + "ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIivAUK", + "FEZpZWxkRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSDgoGbnVtYmVy", + "GAMgASgFEjoKBWxhYmVsGAQgASgOMisuZ29vZ2xlLnByb3RvYnVmLkZpZWxk", + "RGVzY3JpcHRvclByb3RvLkxhYmVsEjgKBHR5cGUYBSABKA4yKi5nb29nbGUu", + "cHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZRIRCgl0eXBlX25h", + "bWUYBiABKAkSEAoIZXh0ZW5kZWUYAiABKAkSFQoNZGVmYXVsdF92YWx1ZRgH", + "IAEoCRITCgtvbmVvZl9pbmRleBgJIAEoBRIRCglqc29uX25hbWUYCiABKAkS", + "LgoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlv", + "bnMitgIKBFR5cGUSDwoLVFlQRV9ET1VCTEUQARIOCgpUWVBFX0ZMT0FUEAIS", + "DgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlOVDY0EAQSDgoKVFlQRV9JTlQz", + "MhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZUEVfRklYRUQzMhAHEg0KCVRZ", + "UEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkSDgoKVFlQRV9HUk9VUBAKEhAK", + "DFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllURVMQDBIPCgtUWVBFX1VJTlQz", + "MhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVfU0ZJWEVEMzIQDxIRCg1UWVBF", + "X1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQERIPCgtUWVBFX1NJTlQ2NBAS", + "IkMKBUxhYmVsEhIKDkxBQkVMX09QVElPTkFMEAESEgoOTEFCRUxfUkVRVUlS", + "RUQQAhISCg5MQUJFTF9SRVBFQVRFRBADIlQKFE9uZW9mRGVzY3JpcHRvclBy", + "b3RvEgwKBG5hbWUYASABKAkSLgoHb3B0aW9ucxgCIAEoCzIdLmdvb2dsZS5w", + "cm90b2J1Zi5PbmVvZk9wdGlvbnMijAEKE0VudW1EZXNjcmlwdG9yUHJvdG8S", + "DAoEbmFtZRgBIAEoCRI4CgV2YWx1ZRgCIAMoCzIpLmdvb2dsZS5wcm90b2J1", + "Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SLQoHb3B0aW9ucxgDIAEoCzIc", + "Lmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyJsChhFbnVtVmFsdWVEZXNj", + "cmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRIOCgZudW1iZXIYAiABKAUSMgoH", + "b3B0aW9ucxgDIAEoCzIhLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRp", + "b25zIpABChZTZXJ2aWNlRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkS", + "NgoGbWV0aG9kGAIgAygLMiYuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2Ny", + "aXB0b3JQcm90bxIwCgdvcHRpb25zGAMgASgLMh8uZ29vZ2xlLnByb3RvYnVm", + "LlNlcnZpY2VPcHRpb25zIsEBChVNZXRob2REZXNjcmlwdG9yUHJvdG8SDAoE", + "bmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIgASgJEhMKC291dHB1dF90eXBl", + "GAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29nbGUucHJvdG9idWYuTWV0", + "aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFtaW5nGAUgASgIOgVmYWxzZRIf", + "ChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVmYWxzZSLwBQoLRmlsZU9wdGlv", + "bnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwKFGphdmFfb3V0ZXJfY2xhc3Nu", + "YW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNl", + "EikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoGBQgASgIQgIYARIl", + "ChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsgASgIOgVmYWxzZRJGCgxvcHRp", + "bWl6ZV9mb3IYCSABKA4yKS5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMu", + "T3B0aW1pemVNb2RlOgVTUEVFRBISCgpnb19wYWNrYWdlGAsgASgJEiIKE2Nj", + "X2dlbmVyaWNfc2VydmljZXMYECABKAg6BWZhbHNlEiQKFWphdmFfZ2VuZXJp", + "Y19zZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoTcHlfZ2VuZXJpY19zZXJ2aWNl", + "cxgSIAEoCDoFZmFsc2USIwoUcGhwX2dlbmVyaWNfc2VydmljZXMYEyABKAg6", + "BWZhbHNlEhkKCmRlcHJlY2F0ZWQYFyABKAg6BWZhbHNlEh8KEGNjX2VuYWJs", + "ZV9hcmVuYXMYHyABKAg6BWZhbHNlEhkKEW9iamNfY2xhc3NfcHJlZml4GCQg", + "ASgJEhgKEGNzaGFycF9uYW1lc3BhY2UYJSABKAkSFAoMc3dpZnRfcHJlZml4", + "GCcgASgJEhgKEHBocF9jbGFzc19wcmVmaXgYKCABKAkSFQoNcGhwX25hbWVz", + "cGFjZRgpIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n", + "b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6", + "ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJ", + "TUUQAyoJCOgHEICAgIACSgQIJhAnIvIBCg5NZXNzYWdlT3B0aW9ucxImChdt", + "ZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9fc3Rh", + "bmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoKZGVw", + "cmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMKFHVu", "aW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5V", - "bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIirQIKDU1ldGhvZE9wdGlv", - "bnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USXwoRaWRlbXBvdGVuY3lf", - "bGV2ZWwYIiABKA4yLy5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5J", - "ZGVtcG90ZW5jeUxldmVsOhNJREVNUE9URU5DWV9VTktOT1dOEkMKFHVuaW50", - "ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu", - "dGVycHJldGVkT3B0aW9uIlAKEElkZW1wb3RlbmN5TGV2ZWwSFwoTSURFTVBP", - "VEVOQ1lfVU5LTk9XThAAEhMKD05PX1NJREVfRUZGRUNUUxABEg4KCklERU1Q", - "T1RFTlQQAioJCOgHEICAgIACIp4CChNVbmludGVycHJldGVkT3B0aW9uEjsK", - "BG5hbWUYAiADKAsyLS5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9w", - "dGlvbi5OYW1lUGFydBIYChBpZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBv", - "c2l0aXZlX2ludF92YWx1ZRgEIAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUY", - "BSABKAMSFAoMZG91YmxlX3ZhbHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgH", - "IAEoDBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJ", - "bmFtZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVuc2lvbhgCIAIoCCLVAQoOU291", - "cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9i", - "dWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEKCExvY2F0aW9uEhAKBHBh", - "dGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhABEhgKEGxlYWRpbmdfY29t", - "bWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVudHMYBCABKAkSIQoZbGVh", - "ZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKnAQoRR2VuZXJhdGVkQ29k", - "ZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5H", - "ZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFubm90YXRpb24SEAoE", - "cGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4Y", - "AyABKAUSCwoDZW5kGAQgASgFQowBChNjb20uZ29vZ2xlLnByb3RvYnVmQhBE", - "ZXNjcmlwdG9yUHJvdG9zSAFaPmdpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVm", - "L3Byb3RvYy1nZW4tZ28vZGVzY3JpcHRvcjtkZXNjcmlwdG9yogIDR1BCqgIa", - "R29vZ2xlLlByb3RvYnVmLlJlZmxlY3Rpb24=")); + "bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgIEAlKBAgJEAoingMK", + "DEZpZWxkT3B0aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1", + "Zi5GaWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgS", + "PwoGanN0eXBlGAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9u", + "cy5KU1R5cGU6CUpTX05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpk", + "ZXByZWNhdGVkGAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJD", + "ChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9i", + "dWYuVW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABII", + "CgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05P", + "Uk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICA", + "gAJKBAgEEAUiXgoMT25lb2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0", + "aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0", + "aW9uKgkI6AcQgICAgAIikwEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFz", + "GAIgASgIEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJw", + "cmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVy", + "cHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgFEAYifQoQRW51bVZhbHVlT3B0", + "aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZRJDChR1bmludGVycHJl", + "dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy", + "ZXRlZE9wdGlvbioJCOgHEICAgIACInsKDlNlcnZpY2VPcHRpb25zEhkKCmRl", + "cHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u", + "GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u", + "KgkI6AcQgICAgAIirQIKDU1ldGhvZE9wdGlvbnMSGQoKZGVwcmVjYXRlZBgh", + "IAEoCDoFZmFsc2USXwoRaWRlbXBvdGVuY3lfbGV2ZWwYIiABKA4yLy5nb29n", + "bGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5JZGVtcG90ZW5jeUxldmVsOhNJ", + "REVNUE9URU5DWV9VTktOT1dOEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcH", + "IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIlAK", + "EElkZW1wb3RlbmN5TGV2ZWwSFwoTSURFTVBPVEVOQ1lfVU5LTk9XThAAEhMK", + "D05PX1NJREVfRUZGRUNUUxABEg4KCklERU1QT1RFTlQQAioJCOgHEICAgIAC", + "Ip4CChNVbmludGVycHJldGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5nb29n", + "bGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIYChBp", + "ZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1ZRgE", + "IAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91YmxlX3Zh", + "bHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVf", + "dmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQK", + "DGlzX2V4dGVuc2lvbhgCIAIoCCLVAQoOU291cmNlQ29kZUluZm8SOgoIbG9j", + "YXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8u", + "TG9jYXRpb24ahgEKCExvY2F0aW9uEhAKBHBhdGgYASADKAVCAhABEhAKBHNw", + "YW4YAiADKAVCAhABEhgKEGxlYWRpbmdfY29tbWVudHMYAyABKAkSGQoRdHJh", + "aWxpbmdfY29tbWVudHMYBCABKAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21t", + "ZW50cxgGIAMoCSKnAQoRR2VuZXJhdGVkQ29kZUluZm8SQQoKYW5ub3RhdGlv", + "bhgBIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5B", + "bm5vdGF0aW9uGk8KCkFubm90YXRpb24SEAoEcGF0aBgBIAMoBUICEAESEwoL", + "c291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4YAyABKAUSCwoDZW5kGAQgASgF", + "QowBChNjb20uZ29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFa", + "PmdpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvYy1nZW4tZ28vZGVz", + "Y3JpcHRvcjtkZXNjcmlwdG9yogIDR1BCqgIaR29vZ2xlLlByb3RvYnVmLlJl", + "ZmxlY3Rpb24=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), global::Google.Protobuf.Reflection.FileDescriptorProto.Parser, new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End", "Options" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser, new[]{ "Start", "End" }, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ExtensionRangeOptions), global::Google.Protobuf.Reflection.ExtensionRangeOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser, new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "JsonName", "Options" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser, new[]{ "Name", "Options" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto), global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser, new[]{ "Name", "Value", "Options" }, null, null, null), @@ -1052,6 +1057,7 @@ namespace Google.Protobuf.Reflection { public ExtensionRange(ExtensionRange other) : this() { start_ = other.start_; end_ = other.end_; + Options = other.options_ != null ? other.Options.Clone() : null; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1081,6 +1087,17 @@ namespace Google.Protobuf.Reflection { } } + /// <summary>Field number for the "options" field.</summary> + public const int OptionsFieldNumber = 3; + private global::Google.Protobuf.Reflection.ExtensionRangeOptions options_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Google.Protobuf.Reflection.ExtensionRangeOptions Options { + get { return options_; } + set { + options_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as ExtensionRange); @@ -1096,6 +1113,7 @@ namespace Google.Protobuf.Reflection { } if (Start != other.Start) return false; if (End != other.End) return false; + if (!object.Equals(Options, other.Options)) return false; return true; } @@ -1104,6 +1122,7 @@ namespace Google.Protobuf.Reflection { int hash = 1; if (Start != 0) hash ^= Start.GetHashCode(); if (End != 0) hash ^= End.GetHashCode(); + if (options_ != null) hash ^= Options.GetHashCode(); return hash; } @@ -1122,6 +1141,10 @@ namespace Google.Protobuf.Reflection { output.WriteRawTag(16); output.WriteInt32(End); } + if (options_ != null) { + output.WriteRawTag(26); + output.WriteMessage(Options); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1133,6 +1156,9 @@ namespace Google.Protobuf.Reflection { if (End != 0) { size += 1 + pb::CodedOutputStream.ComputeInt32Size(End); } + if (options_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options); + } return size; } @@ -1147,6 +1173,12 @@ namespace Google.Protobuf.Reflection { if (other.End != 0) { End = other.End; } + if (other.options_ != null) { + if (options_ == null) { + options_ = new global::Google.Protobuf.Reflection.ExtensionRangeOptions(); + } + Options.MergeFrom(other.Options); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1165,6 +1197,13 @@ namespace Google.Protobuf.Reflection { End = input.ReadInt32(); break; } + case 26: { + if (options_ == null) { + options_ = new global::Google.Protobuf.Reflection.ExtensionRangeOptions(); + } + input.ReadMessage(options_); + break; + } } } } @@ -1332,6 +1371,118 @@ namespace Google.Protobuf.Reflection { } + internal sealed partial class ExtensionRangeOptions : pb::IMessage<ExtensionRangeOptions> { + private static readonly pb::MessageParser<ExtensionRangeOptions> _parser = new pb::MessageParser<ExtensionRangeOptions>(() => new ExtensionRangeOptions()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser<ExtensionRangeOptions> Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[3]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ExtensionRangeOptions() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ExtensionRangeOptions(ExtensionRangeOptions other) : this() { + uninterpretedOption_ = other.uninterpretedOption_.Clone(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ExtensionRangeOptions Clone() { + return new ExtensionRangeOptions(this); + } + + /// <summary>Field number for the "uninterpreted_option" field.</summary> + public const int UninterpretedOptionFieldNumber = 999; + private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec + = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser); + private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>(); + /// <summary> + /// The parser stores options it doesn't recognize here. See above. + /// </summary> + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption { + get { return uninterpretedOption_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as ExtensionRangeOptions); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(ExtensionRangeOptions other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + hash ^= uninterpretedOption_.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(ExtensionRangeOptions other) { + if (other == null) { + return; + } + uninterpretedOption_.Add(other.uninterpretedOption_); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 7994: { + uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); + break; + } + } + } + } + + } + /// <summary> /// Describes a field within a message. /// </summary> @@ -1342,7 +1493,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[3]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[4]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1819,7 +1970,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[4]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[5]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1973,7 +2124,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[5]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[6]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2147,7 +2298,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[6]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[7]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2329,7 +2480,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[7]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[8]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2503,7 +2654,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[8]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[9]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2776,7 +2927,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[9]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[10]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3503,7 +3654,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[10]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[11]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3783,7 +3934,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[11]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[12]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3857,13 +4008,15 @@ namespace Google.Protobuf.Reflection { /// <summary> /// The jstype option determines the JavaScript type used for values of the /// field. The option is permitted only for 64 bit integral and fixed types - /// (int64, uint64, sint64, fixed64, sfixed64). By default these types are - /// represented as JavaScript strings. This avoids loss of precision that can - /// happen when a large value is converted to a floating point JavaScript - /// numbers. Specifying JS_NUMBER for the jstype causes the generated - /// JavaScript code to use the JavaScript "number" type instead of strings. - /// This option is an enum to permit additional types to be added, - /// e.g. goog.math.Integer. + /// (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + /// is represented as JavaScript string, which avoids loss of precision that + /// can happen when a large value is converted to a floating point JavaScript. + /// Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + /// use the JavaScript "number" type. The behavior of the default option + /// JS_NORMAL is implementation dependent. + /// + /// This option is an enum to permit additional types to be added, e.g. + /// goog.math.Integer. /// </summary> [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.Reflection.FieldOptions.Types.JSType Jstype { @@ -4158,7 +4311,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[12]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[13]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4272,7 +4425,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[13]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[14]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4452,7 +4605,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[14]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[15]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4600,7 +4753,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[15]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[16]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4748,7 +4901,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[16]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[17]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4956,7 +5109,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[17]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[18]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5400,7 +5553,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[18]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[19]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5854,7 +6007,7 @@ namespace Google.Protobuf.Reflection { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[19]; } + get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[20]; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs index b90c9a2a..5b39b809 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs @@ -73,6 +73,16 @@ namespace Google.Protobuf.WellKnownTypes { /// any.Unpack(foo) /// ... /// + /// Example 4: Pack and unpack a message in Go + /// + /// foo := &pb.Foo{...} + /// any, err := ptypes.MarshalAny(foo) + /// ... + /// foo := &pb.Foo{} + /// if err := ptypes.UnmarshalAny(any, foo); err != nil { + /// ... + /// } + /// /// The pack methods provided by protobuf library will by default use /// 'type.googleapis.com/full.type.name' as the type URL and the unpack /// methods only use the fully qualified type name after the last '/' diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs index aeeb8e73..6705e092 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs @@ -52,7 +52,15 @@ namespace Google.Protobuf.WellKnownTypes { } #region Messages /// <summary> - /// Api is a light-weight descriptor for a protocol buffer service. + /// Api is a light-weight descriptor for an API Interface. + /// + /// Interfaces are also described as "protocol buffer services" in some contexts, + /// such as by the "service" keyword in a .proto file, but they are different + /// from API Services, which represent a concrete implementation of an interface + /// as opposed to simply a description of methods and bindings. They are also + /// sometimes simply referred to as "APIs" in other contexts, such as the name of + /// this message itself. See https://cloud.google.com/apis/design/glossary for + /// detailed terminology. /// </summary> public sealed partial class Api : pb::IMessage<Api> { private static readonly pb::MessageParser<Api> _parser = new pb::MessageParser<Api>(() => new Api()); @@ -96,8 +104,8 @@ namespace Google.Protobuf.WellKnownTypes { public const int NameFieldNumber = 1; private string name_ = ""; /// <summary> - /// The fully qualified name of this api, including package name - /// followed by the api's simple name. + /// The fully qualified name of this interface, including package name + /// followed by the interface's simple name. /// </summary> [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Name { @@ -113,7 +121,7 @@ namespace Google.Protobuf.WellKnownTypes { = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Method.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Method> methods_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Method>(); /// <summary> - /// The methods of this api, in unspecified order. + /// The methods of this interface, in unspecified order. /// </summary> [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Method> Methods { @@ -126,7 +134,7 @@ namespace Google.Protobuf.WellKnownTypes { = pb::FieldCodec.ForMessage(26, global::Google.Protobuf.WellKnownTypes.Option.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>(); /// <summary> - /// Any metadata attached to the API. + /// Any metadata attached to the interface. /// </summary> [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options { @@ -137,13 +145,12 @@ namespace Google.Protobuf.WellKnownTypes { public const int VersionFieldNumber = 4; private string version_ = ""; /// <summary> - /// A version string for this api. If specified, must have the form - /// `major-version.minor-version`, as in `1.10`. If the minor version - /// is omitted, it defaults to zero. If the entire version field is - /// empty, the major version is derived from the package name, as - /// outlined below. If the field is not empty, the version in the - /// package name will be verified to be consistent with what is - /// provided here. + /// A version string for this interface. If specified, must have the form + /// `major-version.minor-version`, as in `1.10`. If the minor version is + /// omitted, it defaults to zero. If the entire version field is empty, the + /// major version is derived from the package name, as outlined below. If the + /// field is not empty, the version in the package name will be verified to be + /// consistent with what is provided here. /// /// The versioning schema uses [semantic /// versioning](http://semver.org) where the major version number @@ -153,10 +160,10 @@ namespace Google.Protobuf.WellKnownTypes { /// chosen based on the product plan. /// /// The major version is also reflected in the package name of the - /// API, which must end in `v<major-version>`, as in + /// interface, which must end in `v<major-version>`, as in /// `google.feature.v1`. For major versions 0 and 1, the suffix can /// be omitted. Zero major versions must only be used for - /// experimental, none-GA apis. + /// experimental, non-GA interfaces. /// </summary> [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Version { @@ -187,7 +194,7 @@ namespace Google.Protobuf.WellKnownTypes { = pb::FieldCodec.ForMessage(50, global::Google.Protobuf.WellKnownTypes.Mixin.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Mixin> mixins_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Mixin>(); /// <summary> - /// Included APIs. See [Mixin][]. + /// Included interfaces. See [Mixin][]. /// </summary> [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Mixin> Mixins { @@ -364,7 +371,7 @@ namespace Google.Protobuf.WellKnownTypes { } /// <summary> - /// Method represents a method of an api. + /// Method represents a method of an API interface. /// </summary> public sealed partial class Method : pb::IMessage<Method> { private static readonly pb::MessageParser<Method> _parser = new pb::MessageParser<Method>(() => new Method()); @@ -665,9 +672,9 @@ namespace Google.Protobuf.WellKnownTypes { } /// <summary> - /// Declares an API to be included in this API. The including API must - /// redeclare all the methods from the included API, but documentation - /// and options are inherited as follows: + /// Declares an API Interface to be included in this interface. The including + /// interface must redeclare all the methods from the included interface, but + /// documentation and options are inherited as follows: /// /// - If after comment and whitespace stripping, the documentation /// string of the redeclared method is empty, it will be inherited @@ -679,7 +686,8 @@ namespace Google.Protobuf.WellKnownTypes { /// /// - If an http annotation is inherited, the path pattern will be /// modified as follows. Any version prefix will be replaced by the - /// version of the including API plus the [root][] path if specified. + /// version of the including interface plus the [root][] path if + /// specified. /// /// Example of a simple mixin: /// @@ -780,7 +788,7 @@ namespace Google.Protobuf.WellKnownTypes { public const int NameFieldNumber = 1; private string name_ = ""; /// <summary> - /// The fully qualified name of the API which is included. + /// The fully qualified name of the interface which is included. /// </summary> [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public string Name { diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh index 229bec43..8a5ed48a 100755 --- a/generate_descriptor_proto.sh +++ b/generate_descriptor_proto.sh @@ -42,12 +42,23 @@ declare -a RUNTIME_PROTO_FILES=(\ google/protobuf/wrappers.proto) declare -a COMPILER_PROTO_FILES=(\ - google/protobuf/compiler/plugin.proto \ - google/protobuf/compiler/profile.proto \ -) + google/protobuf/compiler/plugin.proto) CORE_PROTO_IS_CORRECT=0 PROCESS_ROUND=1 +BOOTSTRAP_PROTOC="" +while [ $# -gt 0 ]; do + case $1 in + --bootstrap_protoc) + BOOTSTRAP_PROTOC=$2 + shift + ;; + *) + break + ;; + esac + shift +done TMP=$(mktemp -d) echo "Updating descriptor protos..." while [ $CORE_PROTO_IS_CORRECT -ne 1 ] @@ -55,14 +66,20 @@ do echo "Round $PROCESS_ROUND" CORE_PROTO_IS_CORRECT=1 - make $@ protoc - if test $? -ne 0; then - echo "Failed to build protoc." - exit 1 + if [ "$BOOTSTRAP_PROTOC" != "" ]; then + PROTOC=$BOOTSTRAP_PROTOC + BOOTSTRAP_PROTOC="" + else + make $@ protoc + if test $? -ne 0; then + echo "Failed to build protoc." + exit 1 + fi + PROTOC="./protoc" fi - ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \ - ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP ${COMPILER_PROTO_FILES[@]} + $PROTOC --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \ + $PROTOC --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP ${COMPILER_PROTO_FILES[@]} for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]} ${COMPILER_PROTO_FILES[@]}; do BASE_NAME=${PROTO_FILE%.*} diff --git a/java/core/generate-test-sources-build.xml b/java/core/generate-test-sources-build.xml index ab415db6..68951747 100644 --- a/java/core/generate-test-sources-build.xml +++ b/java/core/generate-test-sources-build.xml @@ -5,6 +5,7 @@ <arg value="--proto_path=${protobuf.source.dir}"/> <arg value="--proto_path=${test.proto.dir}"/> <arg value="${protobuf.source.dir}/google/protobuf/unittest.proto"/> + <arg value="${protobuf.source.dir}/google/protobuf/unittest_proto3.proto"/> <arg value="${protobuf.source.dir}/google/protobuf/unittest_import.proto"/> <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public.proto"/> <arg value="${protobuf.source.dir}/google/protobuf/unittest_mset.proto"/> @@ -40,4 +41,4 @@ <arg value="${test.proto.dir}/com/google/protobuf/map_test.proto"/> <arg value="${test.proto.dir}/com/google/protobuf/map_initialization_order_test.proto"/> </exec> -</project>
\ No newline at end of file +</project> diff --git a/java/core/pom.xml b/java/core/pom.xml index e4f50dd1..4608fce6 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-parent</artifactId> - <version>3.3.2</version> + <version>3.4.0</version> </parent> <artifactId>protobuf-java</artifactId> 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 b5043eb5..065fa1a9 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java @@ -32,6 +32,7 @@ package com.google.protobuf; import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.Descriptors.FileDescriptor.Syntax; import com.google.protobuf.Descriptors.OneofDescriptor; import com.google.protobuf.Internal.EnumLite; import java.io.IOException; @@ -162,7 +163,7 @@ public abstract class AbstractMessage } return hash; } - + private static ByteString toByteString(Object value) { if (value instanceof byte[]) { return ByteString.copyFrom((byte[]) value); @@ -170,7 +171,7 @@ public abstract class AbstractMessage return (ByteString) value; } } - + /** * Compares two bytes fields. The parameters must be either a byte array or a * ByteString object. They can be of different type though. @@ -181,7 +182,7 @@ public abstract class AbstractMessage } return toByteString(a).equals(toByteString(b)); } - + /** * Converts a list of MapEntry messages into a Map used for equals() and * hashCode(). @@ -212,7 +213,7 @@ public abstract class AbstractMessage } return result; } - + /** * Compares two map fields. The parameters must be a list of MapEntry * messages. @@ -223,13 +224,13 @@ public abstract class AbstractMessage Map mb = convertMapEntryListToMap((List) b); return MapFieldLite.equals(ma, mb); } - + /** * Compares two set of fields. * This method is used to implement {@link AbstractMessage#equals(Object)} * and {@link AbstractMutableMessage#equals(Object)}. It takes special care * of bytes fields because immutable messages and mutable messages use - * different Java type to reprensent a bytes field and this method should be + * different Java type to represent a bytes field and this method should be * able to compare immutable messages, mutable messages and also an immutable * message to a mutable message. */ @@ -275,7 +276,7 @@ public abstract class AbstractMessage } return true; } - + /** * Calculates the hash code of a map field. {@code value} must be a list of * MapEntry messages. @@ -371,7 +372,7 @@ public abstract class AbstractMessage public String getInitializationErrorString() { return MessageReflection.delimitWithCommas(findInitializationErrors()); } - + @Override protected BuilderType internalMergeFrom(AbstractMessageLite other) { return mergeFrom((Message) other); @@ -432,8 +433,12 @@ public abstract class AbstractMessage final CodedInputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException { + boolean discardUnknown = + getDescriptorForType().getFile().getSyntax() == Syntax.PROTO3 + ? input.shouldDiscardUnknownFieldsProto3() + : input.shouldDiscardUnknownFields(); final UnknownFieldSet.Builder unknownFields = - UnknownFieldSet.newBuilder(getUnknownFields()); + discardUnknown ? null : UnknownFieldSet.newBuilder(getUnknownFields()); while (true) { final int tag = input.readTag(); if (tag == 0) { @@ -451,7 +456,9 @@ public abstract class AbstractMessage break; } } - setUnknownFields(unknownFields.build()); + if (unknownFields != null) { + setUnknownFields(unknownFields.build()); + } return (BuilderType) this; } 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 99787fcc..24830c0a 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java @@ -36,7 +36,9 @@ import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; /** * A partial implementation of the {@link MessageLite} interface which @@ -118,8 +120,13 @@ public abstract class AbstractMessageLite< } } - protected static <T> void addAll(final Iterable<T> values, - final Collection<? super T> list) { + // For binary compatibility + @Deprecated + protected static <T> void addAll(final Iterable<T> values, final Collection<? super T> list) { + Builder.addAll(values, (List) list); + } + + protected static <T> void addAll(final Iterable<T> values, final List<? super T> list) { Builder.addAll(values, list); } @@ -334,6 +341,25 @@ public abstract class AbstractMessageLite< + " threw an IOException (should never happen)."; } + // We check nulls as we iterate to avoid iterating over values twice. + private static <T> void addAllCheckingNulls(Iterable<T> values, List<? super T> list) { + if (list instanceof ArrayList && values instanceof Collection) { + ((ArrayList<T>) list).ensureCapacity(list.size() + ((Collection<T>) values).size()); + } + int begin = list.size(); + for (T value : values) { + if (value == null) { + // encountered a null value so we must undo our modifications prior to throwing + String message = "Element at index " + (list.size() - begin) + " is null."; + for (int i = list.size() - 1; i >= begin; i--) { + list.remove(i); + } + throw new NullPointerException(message); + } + list.add(value); + } + } + /** * Construct an UninitializedMessageException reporting missing fields in * the given message. @@ -343,16 +369,20 @@ public abstract class AbstractMessageLite< return new UninitializedMessageException(message); } + // For binary compatibility. + @Deprecated + protected static <T> void addAll(final Iterable<T> values, final Collection<? super T> list) { + addAll(values, (List<T>) list); + } + /** - * Adds the {@code values} to the {@code list}. This is a helper method - * used by generated code. Users should ignore it. + * Adds the {@code values} to the {@code list}. This is a helper method used by generated code. + * Users should ignore it. * - * @throws NullPointerException if {@code values} or any of the elements of - * {@code values} is null. When that happens, some elements of - * {@code values} may have already been added to the result {@code list}. + * @throws NullPointerException if {@code values} or any of the elements of {@code values} is + * null. */ - protected static <T> void addAll(final Iterable<T> values, - final Collection<? super T> list) { + protected static <T> void addAll(final Iterable<T> values, final List<? super T> list) { checkNotNull(values); if (values instanceof LazyStringList) { // For StringOrByteStringLists, check the underlying elements to avoid @@ -360,25 +390,31 @@ public abstract class AbstractMessageLite< // 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<T>) values); - } else if (values instanceof Collection) { - if (!(values instanceof PrimitiveNonBoxingCollection)) { - checkForNullValues(values); + List<?> lazyValues = ((LazyStringList) values).getUnderlyingElements(); + LazyStringList lazyList = (LazyStringList) list; + int begin = list.size(); + for (Object value : lazyValues) { + if (value == null) { + // encountered a null value so we must undo our modifications prior to throwing + String message = "Element at index " + (lazyList.size() - begin) + " is null."; + for (int i = lazyList.size() - 1; i >= begin; i--) { + lazyList.remove(i); + } + throw new NullPointerException(message); + } + if (value instanceof ByteString) { + lazyList.add((ByteString) value); + } else { + lazyList.add((String) value); + } } - list.addAll((Collection<T>) values); } else { - for (final T value : values) { - checkNotNull(value); - list.add(value); + if (values instanceof PrimitiveNonBoxingCollection) { + list.addAll((Collection<T>) values); + } else { + addAllCheckingNulls(values, list); } } } - - private static void checkForNullValues(final Iterable<?> values) { - for (final Object value : values) { - checkNotNull(value); - } - } } } 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 3dfbcb0a..d6a941b1 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -34,8 +34,8 @@ import static com.google.protobuf.Internal.EMPTY_BYTE_ARRAY; import static com.google.protobuf.Internal.EMPTY_BYTE_BUFFER; import static com.google.protobuf.Internal.UTF_8; import static com.google.protobuf.Internal.checkNotNull; -import static com.google.protobuf.WireFormat.FIXED_32_SIZE; -import static com.google.protobuf.WireFormat.FIXED_64_SIZE; +import static com.google.protobuf.WireFormat.FIXED32_SIZE; +import static com.google.protobuf.WireFormat.FIXED64_SIZE; import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE; import java.io.ByteArrayOutputStream; @@ -372,6 +372,64 @@ public abstract class CodedInputStream { return oldLimit; } + + private boolean explicitDiscardUnknownFields = false; + + /** TODO(liujisi): flip the default.*/ + private static volatile boolean proto3DiscardUnknownFieldsDefault = true; + + static void setProto3DiscardUnknownsByDefaultForTest() { + proto3DiscardUnknownFieldsDefault = true; + } + + static void setProto3KeepUnknownsByDefaultForTest() { + proto3DiscardUnknownFieldsDefault = false; + } + + static boolean getProto3DiscardUnknownFieldsDefault() { + return proto3DiscardUnknownFieldsDefault; + } + + /** + * Sets this {@code CodedInputStream} to discard unknown fields. Only applies to full runtime + * messages; lite messages will always preserve unknowns. + * + * <p>Note calling this function alone will have NO immediate effect on the underlying input data. + * The unknown fields will be discarded during parsing. This affects both Proto2 and Proto3 full + * runtime. + */ + final void discardUnknownFields() { + explicitDiscardUnknownFields = true; + } + + /** + * Reverts the unknown fields preservation behavior for Proto2 and Proto3 full runtime to their + * default. + */ + final void unsetDiscardUnknownFields() { + explicitDiscardUnknownFields = false; + } + + /** + * Whether unknown fields in this input stream should be discarded during parsing into full + * runtime messages. + */ + final boolean shouldDiscardUnknownFields() { + return explicitDiscardUnknownFields; + } + + /** + * Whether unknown fields in this input stream should be discarded during parsing for proto3 full + * runtime messages. + * + * <p>This function was temporarily introduced before proto3 unknown fields behavior is changed. + * TODO(liujisi): remove this and related code in GeneratedMessage after proto3 unknown + * fields migration is done. + */ + final boolean shouldDiscardUnknownFieldsProto3() { + return explicitDiscardUnknownFields ? true : proto3DiscardUnknownFieldsDefault; + } + /** * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). Only valid for {@link * InputStream}-backed streams. @@ -572,7 +630,7 @@ public abstract class CodedInputStream { skipRawVarint(); return true; case WireFormat.WIRETYPE_FIXED64: - skipRawBytes(FIXED_64_SIZE); + skipRawBytes(FIXED64_SIZE); return true; case WireFormat.WIRETYPE_LENGTH_DELIMITED: skipRawBytes(readRawVarint32()); @@ -585,7 +643,7 @@ public abstract class CodedInputStream { case WireFormat.WIRETYPE_END_GROUP: return false; case WireFormat.WIRETYPE_FIXED32: - skipRawBytes(FIXED_32_SIZE); + skipRawBytes(FIXED32_SIZE); return true; default: throw InvalidProtocolBufferException.invalidWireType(); @@ -1064,12 +1122,12 @@ public abstract class CodedInputStream { public int readRawLittleEndian32() throws IOException { int tempPos = pos; - if (limit - tempPos < FIXED_32_SIZE) { + if (limit - tempPos < FIXED32_SIZE) { throw InvalidProtocolBufferException.truncatedMessage(); } final byte[] buffer = this.buffer; - pos = tempPos + FIXED_32_SIZE; + pos = tempPos + FIXED32_SIZE; return (((buffer[tempPos] & 0xff)) | ((buffer[tempPos + 1] & 0xff) << 8) | ((buffer[tempPos + 2] & 0xff) << 16) @@ -1080,12 +1138,12 @@ public abstract class CodedInputStream { public long readRawLittleEndian64() throws IOException { int tempPos = pos; - if (limit - tempPos < FIXED_64_SIZE) { + if (limit - tempPos < FIXED64_SIZE) { throw InvalidProtocolBufferException.truncatedMessage(); } final byte[] buffer = this.buffer; - pos = tempPos + FIXED_64_SIZE; + pos = tempPos + FIXED64_SIZE; return (((buffer[tempPos] & 0xffL)) | ((buffer[tempPos + 1] & 0xffL) << 8) | ((buffer[tempPos + 2] & 0xffL) << 16) @@ -1290,7 +1348,7 @@ public abstract class CodedInputStream { skipRawVarint(); return true; case WireFormat.WIRETYPE_FIXED64: - skipRawBytes(FIXED_64_SIZE); + skipRawBytes(FIXED64_SIZE); return true; case WireFormat.WIRETYPE_LENGTH_DELIMITED: skipRawBytes(readRawVarint32()); @@ -1303,7 +1361,7 @@ public abstract class CodedInputStream { case WireFormat.WIRETYPE_END_GROUP: return false; case WireFormat.WIRETYPE_FIXED32: - skipRawBytes(FIXED_32_SIZE); + skipRawBytes(FIXED32_SIZE); return true; default: throw InvalidProtocolBufferException.invalidWireType(); @@ -1429,7 +1487,9 @@ public abstract class CodedInputStream { final int size = readRawVarint32(); if (size > 0 && size <= remaining()) { // TODO(nathanmittler): Is there a way to avoid this copy? - byte[] bytes = copyToArray(pos, pos + size); + // The same as readBytes' logic + byte[] bytes = new byte[size]; + UnsafeUtil.copyMemory(pos, bytes, 0, size); String result = new String(bytes, UTF_8); pos += size; return result; @@ -1449,7 +1509,9 @@ public abstract class CodedInputStream { final int size = readRawVarint32(); if (size >= 0 && size <= remaining()) { // TODO(nathanmittler): Is there a way to avoid this copy? - byte[] bytes = copyToArray(pos, pos + size); + // The same as readBytes' logic + byte[] bytes = new byte[size]; + UnsafeUtil.copyMemory(pos, bytes, 0, size); // TODO(martinrb): We could save a pass by validating while decoding. if (!Utf8.isValidUtf8(bytes)) { throw InvalidProtocolBufferException.invalidUtf8(); @@ -1545,14 +1607,17 @@ public abstract class CodedInputStream { public ByteString readBytes() throws IOException { final int size = readRawVarint32(); if (size > 0 && size <= remaining()) { - ByteBuffer result; if (immutable && enableAliasing) { - result = slice(pos, pos + size); + final ByteBuffer result = slice(pos, pos + size); + pos += size; + return ByteString.wrap(result); } else { - result = copy(pos, pos + size); + // Use UnsafeUtil to copy the memory to bytes instead of using ByteBuffer ways. + byte[] bytes = new byte[size]; + UnsafeUtil.copyMemory(pos, bytes, 0, size); + pos += size; + return ByteString.wrap(bytes); } - pos += size; - return ByteString.wrap(result); } if (size == 0) { @@ -1573,18 +1638,21 @@ public abstract class CodedInputStream { public ByteBuffer readByteBuffer() throws IOException { final int size = readRawVarint32(); if (size > 0 && size <= remaining()) { - ByteBuffer result; // "Immutable" implies that buffer is backing a ByteString. // Disallow slicing in this case to prevent the caller from modifying the contents // of the ByteString. if (!immutable && enableAliasing) { - result = slice(pos, pos + size); + final ByteBuffer result = slice(pos, pos + size); + pos += size; + return result; } else { - result = copy(pos, pos + size); + // The same as readBytes' logic + byte[] bytes = new byte[size]; + UnsafeUtil.copyMemory(pos, bytes, 0, size); + pos += size; + return ByteBuffer.wrap(bytes); } - pos += size; // TODO(nathanmittler): Investigate making the ByteBuffer be made read-only - return result; } if (size == 0) { @@ -1785,11 +1853,11 @@ public abstract class CodedInputStream { public int readRawLittleEndian32() throws IOException { long tempPos = pos; - if (limit - tempPos < FIXED_32_SIZE) { + if (limit - tempPos < FIXED32_SIZE) { throw InvalidProtocolBufferException.truncatedMessage(); } - pos = tempPos + FIXED_32_SIZE; + pos = tempPos + FIXED32_SIZE; return (((UnsafeUtil.getByte(tempPos) & 0xff)) | ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8) | ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16) @@ -1800,11 +1868,11 @@ public abstract class CodedInputStream { public long readRawLittleEndian64() throws IOException { long tempPos = pos; - if (limit - tempPos < FIXED_64_SIZE) { + if (limit - tempPos < FIXED64_SIZE) { throw InvalidProtocolBufferException.truncatedMessage(); } - pos = tempPos + FIXED_64_SIZE; + pos = tempPos + FIXED64_SIZE; return (((UnsafeUtil.getByte(tempPos) & 0xffL)) | ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8) | ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16) @@ -1943,27 +2011,6 @@ public abstract class CodedInputStream { buffer.limit(prevLimit); } } - - private ByteBuffer copy(long begin, long end) throws IOException { - return ByteBuffer.wrap(copyToArray(begin, end)); - } - - private byte[] copyToArray(long begin, long end) throws IOException { - int prevPos = buffer.position(); - int prevLimit = buffer.limit(); - try { - buffer.position(bufferPos(begin)); - buffer.limit(bufferPos(end)); - byte[] bytes = new byte[(int) (end - begin)]; - buffer.get(bytes); - return bytes; - } catch (IllegalArgumentException e) { - throw InvalidProtocolBufferException.truncatedMessage(); - } finally { - buffer.position(prevPos); - buffer.limit(prevLimit); - } - } } /** @@ -2034,7 +2081,7 @@ public abstract class CodedInputStream { skipRawVarint(); return true; case WireFormat.WIRETYPE_FIXED64: - skipRawBytes(FIXED_64_SIZE); + skipRawBytes(FIXED64_SIZE); return true; case WireFormat.WIRETYPE_LENGTH_DELIMITED: skipRawBytes(readRawVarint32()); @@ -2047,7 +2094,7 @@ public abstract class CodedInputStream { case WireFormat.WIRETYPE_END_GROUP: return false; case WireFormat.WIRETYPE_FIXED32: - skipRawBytes(FIXED_32_SIZE); + skipRawBytes(FIXED32_SIZE); return true; default: throw InvalidProtocolBufferException.invalidWireType(); @@ -2332,8 +2379,7 @@ public abstract class CodedInputStream { if (size == 0) { return ByteString.EMPTY; } - // Slow path: Build a byte array first then copy it. - return ByteString.wrap(readRawBytesSlowPath(size)); + return readBytesSlowPath(size); } @Override @@ -2558,13 +2604,13 @@ public abstract class CodedInputStream { public int readRawLittleEndian32() throws IOException { int tempPos = pos; - if (bufferSize - tempPos < FIXED_32_SIZE) { - refillBuffer(FIXED_32_SIZE); + if (bufferSize - tempPos < FIXED32_SIZE) { + refillBuffer(FIXED32_SIZE); tempPos = pos; } final byte[] buffer = this.buffer; - pos = tempPos + FIXED_32_SIZE; + pos = tempPos + FIXED32_SIZE; return (((buffer[tempPos] & 0xff)) | ((buffer[tempPos + 1] & 0xff) << 8) | ((buffer[tempPos + 2] & 0xff) << 16) @@ -2575,13 +2621,13 @@ public abstract class CodedInputStream { public long readRawLittleEndian64() throws IOException { int tempPos = pos; - if (bufferSize - tempPos < FIXED_64_SIZE) { - refillBuffer(FIXED_64_SIZE); + if (bufferSize - tempPos < FIXED64_SIZE) { + refillBuffer(FIXED64_SIZE); tempPos = pos; } final byte[] buffer = this.buffer; - pos = tempPos + FIXED_64_SIZE; + pos = tempPos + FIXED64_SIZE; return (((buffer[tempPos] & 0xffL)) | ((buffer[tempPos + 1] & 0xffL) << 8) | ((buffer[tempPos + 2] & 0xffL) << 16) @@ -2675,7 +2721,13 @@ public abstract class CodedInputStream { */ private void refillBuffer(int n) throws IOException { if (!tryRefillBuffer(n)) { - throw InvalidProtocolBufferException.truncatedMessage(); + // We have to distinguish the exception between sizeLimitExceeded and truncatedMessage. So + // we just throw an sizeLimitExceeded exception here if it exceeds the sizeLimit + if (n > sizeLimit - totalBytesRetired - pos) { + throw InvalidProtocolBufferException.sizeLimitExceeded(); + } else { + throw InvalidProtocolBufferException.truncatedMessage(); + } } } @@ -2684,8 +2736,8 @@ public abstract class CodedInputStream { * buffer. Caller must ensure that the requested space is not yet available, and that the * requested space is less than BUFFER_SIZE. * - * @return {@code true} if the bytes could be made available; {@code false} if the end of the - * stream or the current limit was reached. + * @return {@code true} If the bytes could be made available; {@code false} 1. Current at the + * end of the stream 2. The current limit was reached 3. The total size limit was reached */ private boolean tryRefillBuffer(int n) throws IOException { if (pos + n <= bufferSize) { @@ -2693,6 +2745,14 @@ public abstract class CodedInputStream { "refillBuffer() called when " + n + " bytes were already available in buffer"); } + // Check whether the size of total message needs to read is bigger than the size limit. + // We shouldn't throw an exception here as isAtEnd() function needs to get this function's + // return as the result. + if (n > sizeLimit - totalBytesRetired - pos) { + return false; + } + + // Shouldn't throw the exception here either. if (totalBytesRetired + pos + n > currentLimit) { // Oops, we hit a limit. return false; @@ -2712,7 +2772,16 @@ public abstract class CodedInputStream { pos = 0; } - int bytesRead = input.read(buffer, bufferSize, buffer.length - bufferSize); + // Here we should refill the buffer as many bytes as possible. + int bytesRead = + input.read( + buffer, + bufferSize, + Math.min( + // the size of allocated but unused bytes in the buffer + buffer.length - bufferSize, + // do not exceed the total bytes limit + sizeLimit - totalBytesRetired - bufferSize)); if (bytesRead == 0 || bytesRead < -1 || bytesRead > buffer.length) { throw new IllegalStateException( "InputStream#read(byte[]) returned invalid result: " @@ -2721,10 +2790,6 @@ public abstract class CodedInputStream { } if (bytesRead > 0) { bufferSize += bytesRead; - // Integer-overflow-conscious check against sizeLimit - if (totalBytesRetired + n - sizeLimit > 0) { - throw InvalidProtocolBufferException.sizeLimitExceeded(); - } recomputeBufferSizeAfterLimit(); return (bufferSize >= n) ? true : tryRefillBuffer(n); } @@ -2756,6 +2821,49 @@ public abstract class CodedInputStream { * (bufferSize - pos) && size > 0) */ private byte[] readRawBytesSlowPath(final int size) throws IOException { + // Attempt to read the data in one byte array when it's safe to do. + byte[] result = readRawBytesSlowPathOneChunk(size); + if (result != null) { + return result; + } + + final int originalBufferPos = pos; + final int bufferedBytes = bufferSize - pos; + + // Mark the current buffer consumed. + totalBytesRetired += bufferSize; + pos = 0; + bufferSize = 0; + + // Determine the number of bytes we need to read from the input stream. + int sizeLeft = size - bufferedBytes; + + // The size is very large. For security reasons we read them in small + // chunks. + List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft); + + // OK, got everything. Now concatenate it all into one buffer. + final byte[] bytes = new byte[size]; + + // Start by copying the leftover bytes from this.buffer. + System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes); + + // And now all the chunks. + int tempPos = bufferedBytes; + for (final byte[] chunk : chunks) { + System.arraycopy(chunk, 0, bytes, tempPos, chunk.length); + tempPos += chunk.length; + } + + // Done. + return bytes; + } + + /** + * Attempts to read the data in one byte array when it's safe to do. Returns null if the size to + * read is too large and needs to be allocated in smaller chunks for security reasons. + */ + private byte[] readRawBytesSlowPathOneChunk(final int size) throws IOException { if (size == 0) { return Internal.EMPTY_BYTE_ARRAY; } @@ -2776,14 +2884,7 @@ public abstract class CodedInputStream { throw InvalidProtocolBufferException.truncatedMessage(); } - final int originalBufferPos = pos; final int bufferedBytes = bufferSize - pos; - - // Mark the current buffer consumed. - totalBytesRetired += bufferSize; - pos = 0; - bufferSize = 0; - // Determine the number of bytes we need to read from the input stream. int sizeLeft = size - bufferedBytes; // TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE. @@ -2793,7 +2894,10 @@ public abstract class CodedInputStream { final byte[] bytes = new byte[size]; // Copy all of the buffered bytes to the result buffer. - System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes); + System.arraycopy(buffer, pos, bytes, 0, bufferedBytes); + totalBytesRetired += bufferSize; + pos = 0; + bufferSize = 0; // Fill the remaining bytes from the input stream. int tempPos = bufferedBytes; @@ -2809,6 +2913,11 @@ public abstract class CodedInputStream { return bytes; } + return null; + } + + /** Reads the remaining data in small chunks from the input stream. */ + private List<byte[]> readRawBytesSlowPathRemainingChunks(int sizeLeft) throws IOException { // The size is very large. For security reasons, we can't allocate the // entire byte array yet. The size comes directly from the input, so a // maliciously-crafted message could provide a bogus very large size in @@ -2834,21 +2943,41 @@ public abstract class CodedInputStream { chunks.add(chunk); } - // OK, got everything. Now concatenate it all into one buffer. - final byte[] bytes = new byte[size]; - - // Start by copying the leftover bytes from this.buffer. - System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes); + return chunks; + } - // And now all the chunks. - int tempPos = bufferedBytes; - for (final byte[] chunk : chunks) { - System.arraycopy(chunk, 0, bytes, tempPos, chunk.length); - tempPos += chunk.length; + /** + * Like readBytes, but caller must have already checked the fast path: (size <= (bufferSize - + * pos) && size > 0 || size == 0) + */ + private ByteString readBytesSlowPath(final int size) throws IOException { + final byte[] result = readRawBytesSlowPathOneChunk(size); + if (result != null) { + return ByteString.wrap(result); } - // Done. - return bytes; + final int originalBufferPos = pos; + final int bufferedBytes = bufferSize - pos; + + // Mark the current buffer consumed. + totalBytesRetired += bufferSize; + pos = 0; + bufferSize = 0; + + // Determine the number of bytes we need to read from the input stream. + int sizeLeft = size - bufferedBytes; + + // The size is very large. For security reasons we read them in small + // chunks. + List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft); + + // Wrap the byte arrays into a single ByteString. + List<ByteString> byteStrings = new ArrayList<ByteString>(1 + chunks.size()); + byteStrings.add(ByteString.copyFrom(buffer, originalBufferPos, bufferedBytes)); + for (byte[] chunk : chunks) { + byteStrings.add(ByteString.wrap(chunk)); + } + return ByteString.copyFrom(byteStrings); } @Override 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 da0e9b12..093a5f61 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java @@ -30,8 +30,8 @@ package com.google.protobuf; -import static com.google.protobuf.WireFormat.FIXED_32_SIZE; -import static com.google.protobuf.WireFormat.FIXED_64_SIZE; +import static com.google.protobuf.WireFormat.FIXED32_SIZE; +import static com.google.protobuf.WireFormat.FIXED64_SIZE; import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE; import static java.lang.Math.max; @@ -59,13 +59,12 @@ import java.util.logging.Logger; public abstract class CodedOutputStream extends ByteOutput { private static final Logger logger = Logger.getLogger(CodedOutputStream.class.getName()); private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = UnsafeUtil.hasUnsafeArrayOperations(); - private static final long ARRAY_BASE_OFFSET = UnsafeUtil.getArrayBaseOffset(); /** * @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead. */ @Deprecated - public static final int LITTLE_ENDIAN_32_SIZE = FIXED_32_SIZE; + public static final int LITTLE_ENDIAN_32_SIZE = FIXED32_SIZE; /** * The buffer size used in {@link #newInstance(OutputStream)}. @@ -755,7 +754,7 @@ public abstract class CodedOutputStream extends ByteOutput { * {@code fixed32} field. */ public static int computeFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) { - return FIXED_32_SIZE; + return FIXED32_SIZE; } /** @@ -763,7 +762,7 @@ public abstract class CodedOutputStream extends ByteOutput { * {@code sfixed32} field. */ public static int computeSFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) { - return FIXED_32_SIZE; + return FIXED32_SIZE; } /** @@ -813,7 +812,7 @@ public abstract class CodedOutputStream extends ByteOutput { * {@code fixed64} field. */ public static int computeFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) { - return FIXED_64_SIZE; + return FIXED64_SIZE; } /** @@ -821,7 +820,7 @@ public abstract class CodedOutputStream extends ByteOutput { * {@code sfixed64} field. */ public static int computeSFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) { - return FIXED_64_SIZE; + return FIXED64_SIZE; } /** @@ -829,7 +828,7 @@ public abstract class CodedOutputStream extends ByteOutput { * {@code float} field, including tag. */ public static int computeFloatSizeNoTag(@SuppressWarnings("unused") final float unused) { - return FIXED_32_SIZE; + return FIXED32_SIZE; } /** @@ -837,7 +836,7 @@ public abstract class CodedOutputStream extends ByteOutput { * {@code double} field, including tag. */ public static int computeDoubleSizeNoTag(@SuppressWarnings("unused") final double unused) { - return FIXED_64_SIZE; + return FIXED64_SIZE; } /** @@ -1321,15 +1320,12 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public final void writeUInt32NoTag(int value) throws IOException { if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) { - long pos = ARRAY_BASE_OFFSET + position; while (true) { if ((value & ~0x7F) == 0) { - UnsafeUtil.putByte(buffer, pos++, (byte) value); - position++; + UnsafeUtil.putByte(buffer, position++, (byte) value); return; } else { - UnsafeUtil.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80)); - position++; + UnsafeUtil.putByte(buffer, position++, (byte) ((value & 0x7F) | 0x80)); value >>>= 7; } } @@ -1367,15 +1363,12 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public final void writeUInt64NoTag(long value) throws IOException { if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) { - long pos = ARRAY_BASE_OFFSET + position; while (true) { if ((value & ~0x7FL) == 0) { - UnsafeUtil.putByte(buffer, pos++, (byte) value); - position++; + UnsafeUtil.putByte(buffer, position++, (byte) value); return; } else { - UnsafeUtil.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80)); - position++; + UnsafeUtil.putByte(buffer, position++, (byte) (((int) value & 0x7F) | 0x80)); value >>>= 7; } } @@ -1854,7 +1847,7 @@ public abstract class CodedOutputStream extends ByteOutput { } static boolean isSupported() { - return UnsafeUtil.hasUnsafeByteBufferOperations() && UnsafeUtil.hasUnsafeCopyMemory(); + return UnsafeUtil.hasUnsafeByteBufferOperations(); } @Override @@ -2030,7 +2023,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed32NoTag(int value) throws IOException { buffer.putInt(bufferPos(position), value); - position += FIXED_32_SIZE; + position += FIXED32_SIZE; } @Override @@ -2064,7 +2057,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed64NoTag(long value) throws IOException { buffer.putLong(bufferPos(position), value); - position += FIXED_64_SIZE; + position += FIXED64_SIZE; } @Override @@ -2081,8 +2074,7 @@ public abstract class CodedOutputStream extends ByteOutput { String.format("Pos: %d, limit: %d, len: %d", position, limit, length)); } - UnsafeUtil.copyMemory( - value, UnsafeUtil.getArrayBaseOffset() + offset, null, position, length); + UnsafeUtil.copyMemory(value, offset, position, length); position += length; } @@ -2249,19 +2241,17 @@ public abstract class CodedOutputStream extends ByteOutput { */ final void bufferUInt32NoTag(int value) { if (HAS_UNSAFE_ARRAY_OPERATIONS) { - final long originalPos = ARRAY_BASE_OFFSET + position; - long pos = originalPos; + final long originalPos = position; while (true) { if ((value & ~0x7F) == 0) { - UnsafeUtil.putByte(buffer, pos++, (byte) value); + UnsafeUtil.putByte(buffer, position++, (byte) value); break; } else { - UnsafeUtil.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80)); + UnsafeUtil.putByte(buffer, position++, (byte) ((value & 0x7F) | 0x80)); value >>>= 7; } } - int delta = (int) (pos - originalPos); - position += delta; + int delta = (int) (position - originalPos); totalBytesWritten += delta; } else { while (true) { @@ -2284,19 +2274,17 @@ public abstract class CodedOutputStream extends ByteOutput { */ final void bufferUInt64NoTag(long value) { if (HAS_UNSAFE_ARRAY_OPERATIONS) { - final long originalPos = ARRAY_BASE_OFFSET + position; - long pos = originalPos; + final long originalPos = position; while (true) { if ((value & ~0x7FL) == 0) { - UnsafeUtil.putByte(buffer, pos++, (byte) value); + UnsafeUtil.putByte(buffer, position++, (byte) value); break; } else { - UnsafeUtil.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80)); + UnsafeUtil.putByte(buffer, position++, (byte) (((int) value & 0x7F) | 0x80)); value >>>= 7; } } - int delta = (int) (pos - originalPos); - position += delta; + int delta = (int) (position - originalPos); totalBytesWritten += delta; } else { while (true) { @@ -2322,7 +2310,7 @@ public abstract class CodedOutputStream extends ByteOutput { buffer[position++] = (byte) ((value >> 8) & 0xFF); buffer[position++] = (byte) ((value >> 16) & 0xFF); buffer[position++] = (byte) ((value >> 24) & 0xFF); - totalBytesWritten += FIXED_32_SIZE; + totalBytesWritten += FIXED32_SIZE; } /** @@ -2338,7 +2326,7 @@ public abstract class CodedOutputStream extends ByteOutput { buffer[position++] = (byte) ((int) (value >> 40) & 0xFF); buffer[position++] = (byte) ((int) (value >> 48) & 0xFF); buffer[position++] = (byte) ((int) (value >> 56) & 0xFF); - totalBytesWritten += FIXED_64_SIZE; + totalBytesWritten += FIXED64_SIZE; } } @@ -2379,7 +2367,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed32(final int fieldNumber, final int value) throws IOException { - flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_32_SIZE); + flushIfNotAvailable(MAX_VARINT_SIZE + FIXED32_SIZE); bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32); bufferFixed32NoTag(value); } @@ -2393,7 +2381,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed64(final int fieldNumber, final long value) throws IOException { - flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_64_SIZE); + flushIfNotAvailable(MAX_VARINT_SIZE + FIXED64_SIZE); bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64); bufferFixed64NoTag(value); } @@ -2519,7 +2507,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed32NoTag(final int value) throws IOException { - flushIfNotAvailable(FIXED_32_SIZE); + flushIfNotAvailable(FIXED32_SIZE); bufferFixed32NoTag(value); } @@ -2531,7 +2519,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed64NoTag(final long value) throws IOException { - flushIfNotAvailable(FIXED_64_SIZE); + flushIfNotAvailable(FIXED64_SIZE); bufferFixed64NoTag(value); } @@ -2682,7 +2670,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed32(final int fieldNumber, final int value) throws IOException { - flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_32_SIZE); + flushIfNotAvailable(MAX_VARINT_SIZE + FIXED32_SIZE); bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32); bufferFixed32NoTag(value); } @@ -2696,7 +2684,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed64(final int fieldNumber, final long value) throws IOException { - flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_64_SIZE); + flushIfNotAvailable(MAX_VARINT_SIZE + FIXED64_SIZE); bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64); bufferFixed64NoTag(value); } @@ -2822,7 +2810,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed32NoTag(final int value) throws IOException { - flushIfNotAvailable(FIXED_32_SIZE); + flushIfNotAvailable(FIXED32_SIZE); bufferFixed32NoTag(value); } @@ -2834,7 +2822,7 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public void writeFixed64NoTag(final long value) throws IOException { - flushIfNotAvailable(FIXED_64_SIZE); + flushIfNotAvailable(FIXED64_SIZE); bufferFixed64NoTag(value); } diff --git a/java/core/src/main/java/com/google/protobuf/DiscardUnknownFieldsParser.java b/java/core/src/main/java/com/google/protobuf/DiscardUnknownFieldsParser.java new file mode 100644 index 00000000..7ae94349 --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/DiscardUnknownFieldsParser.java @@ -0,0 +1,71 @@ +// 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; + +/** + * Parsers to discard unknown fields during parsing. + */ +public final class DiscardUnknownFieldsParser { + + /** + * Warps a given {@link Parser} into a new {@link Parser} that discards unknown fields during + * parsing. + * + * <p>Usage example: + * <pre>{@code + * private final static Parser<Foo> FOO_PARSER = DiscardUnknownFieldsParser.wrap(Foo.parser()); + * Foo parseFooDiscardUnknown(ByteBuffer input) throws IOException { + * return FOO_PARSER.parseFrom(input); + * } + * }</pre> + * + * <p>Like all other implementations of {@code Parser}, this parser is stateless and thread-safe. + * + * @param parser The delegated parser that parses messages. + * @return a {@link Parser} that will discard unknown fields during parsing. + */ + public static final <T extends Message> Parser<T> wrap(final Parser<T> parser) { + return new AbstractParser<T>() { + @Override + public T parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + try { + input.discardUnknownFields(); + return parser.parsePartialFrom(input, extensionRegistry); + } finally { + input.unsetDiscardUnknownFields(); + } + } + }; + } + + private DiscardUnknownFieldsParser() {} +} 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 2631db74..ba532021 100644 --- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java +++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java @@ -590,9 +590,8 @@ public final class DynamicMessage extends AbstractMessage { @Override public Builder setUnknownFields(UnknownFieldSet unknownFields) { - if (getDescriptorForType().getFile().getSyntax() - == Descriptors.FileDescriptor.Syntax.PROTO3) { - // Proto3 discards unknown fields. + if (getDescriptorForType().getFile().getSyntax() == Descriptors.FileDescriptor.Syntax.PROTO3 + && CodedInputStream.getProto3DiscardUnknownFieldsDefault()) { return this; } this.unknownFields = unknownFields; @@ -601,9 +600,8 @@ public final class DynamicMessage extends AbstractMessage { @Override public Builder mergeUnknownFields(UnknownFieldSet unknownFields) { - if (getDescriptorForType().getFile().getSyntax() - == Descriptors.FileDescriptor.Syntax.PROTO3) { - // Proto3 discards unknown fields. + if (getDescriptorForType().getFile().getSyntax() == Descriptors.FileDescriptor.Syntax.PROTO3 + && CodedInputStream.getProto3DiscardUnknownFieldsDefault()) { return this; } this.unknownFields = diff --git a/java/core/src/main/java/com/google/protobuf/Extension.java b/java/core/src/main/java/com/google/protobuf/Extension.java index 08ec5b45..5df12e64 100644 --- a/java/core/src/main/java/com/google/protobuf/Extension.java +++ b/java/core/src/main/java/com/google/protobuf/Extension.java @@ -58,10 +58,7 @@ public abstract class Extension<ContainingType extends MessageLite, Type> PROTO1, } - protected ExtensionType getExtensionType() { - // TODO(liujisi): make this abstract after we fix proto1. - return ExtensionType.IMMUTABLE; - } + protected abstract ExtensionType getExtensionType(); /** * Type of a message extension. @@ -70,7 +67,7 @@ public abstract class Extension<ContainingType extends MessageLite, Type> PROTO1, PROTO2, } - + /** * If the extension is a message extension (i.e., getLiteType() == MESSAGE), * returns the type of the message, otherwise undefined. diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java index 23174e24..89f7ab9b 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java @@ -34,7 +34,7 @@ import static com.google.protobuf.ExtensionRegistryLite.EMPTY_REGISTRY_LITE; /** * A factory object to create instances of {@link ExtensionRegistryLite}. - * + * * <p> * This factory detects (via reflection) if the full (non-Lite) protocol buffer libraries * are available, and if so, the instances returned are actually {@link ExtensionRegistry}. @@ -82,6 +82,7 @@ final class ExtensionRegistryFactory { return EMPTY_REGISTRY_LITE; } + static boolean isFullRegistry(ExtensionRegistryLite registry) { return EXTENSION_REGISTRY_CLASS != null && EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass()); @@ -90,6 +91,6 @@ final class ExtensionRegistryFactory { private static final ExtensionRegistryLite invokeSubclassFactory(String methodName) throws Exception { return (ExtensionRegistryLite) EXTENSION_REGISTRY_CLASS - .getMethod(methodName).invoke(null); + .getDeclaredMethod(methodName).invoke(null); } } 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 cf3486e1..7116ae1c 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -107,11 +107,12 @@ public abstract class GeneratedMessageLite< @SuppressWarnings("unchecked") // Guaranteed by runtime @Override public int hashCode() { - if (memoizedHashCode == 0) { - HashCodeVisitor visitor = new HashCodeVisitor(); - visit(visitor, (MessageType) this); - memoizedHashCode = visitor.hashCode; + if (memoizedHashCode != 0) { + return memoizedHashCode; } + HashCodeVisitor visitor = new HashCodeVisitor(); + visit(visitor, (MessageType) this); + memoizedHashCode = visitor.hashCode; return memoizedHashCode; } @@ -331,7 +332,7 @@ public abstract class GeneratedMessageLite< if (isBuilt) { MessageType newInstance = (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE); - newInstance.visit(MergeFromVisitor.INSTANCE, instance); + mergeFromInstance(newInstance, instance); instance = newInstance; isBuilt = false; } @@ -386,10 +387,14 @@ public abstract class GeneratedMessageLite< /** All subclasses implement this. */ public BuilderType mergeFrom(MessageType message) { copyOnWrite(); - instance.visit(MergeFromVisitor.INSTANCE, message); + mergeFromInstance(instance, message); return (BuilderType) this; } + private void mergeFromInstance(MessageType dest, MessageType src) { + dest.visit(MergeFromVisitor.INSTANCE, src); + } + @Override public MessageType getDefaultInstanceForType() { return defaultInstance; @@ -1713,7 +1718,6 @@ public abstract class GeneratedMessageLite< Object visitOneofLong(boolean minePresent, Object mine, Object other); Object visitOneofString(boolean minePresent, Object mine, Object other); Object visitOneofByteString(boolean minePresent, Object mine, Object other); - Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other); Object visitOneofMessage(boolean minePresent, Object mine, Object other); void visitOneofNotSet(boolean minePresent); @@ -1721,7 +1725,6 @@ public abstract class GeneratedMessageLite< * Message fields use null sentinals. */ <T extends MessageLite> T visitMessage(T mine, T other); - LazyFieldLite visitLazyMessage(LazyFieldLite mine, LazyFieldLite other); <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other); BooleanList visitBooleanList(BooleanList mine, BooleanList other); @@ -1865,14 +1868,6 @@ public abstract class GeneratedMessageLite< } @Override - public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) { - if (minePresent && mine.equals(other)) { - return mine; - } - throw NOT_EQUALS; - } - - @Override public Object visitOneofMessage(boolean minePresent, Object mine, Object other) { if (minePresent && ((GeneratedMessageLite<?, ?>) mine).equals(this, (MessageLite) other)) { return mine; @@ -1903,21 +1898,6 @@ public abstract class GeneratedMessageLite< } @Override - public LazyFieldLite visitLazyMessage( - LazyFieldLite mine, LazyFieldLite other) { - if (mine == null && other == null) { - return null; - } - if (mine == null || other == null) { - throw NOT_EQUALS; - } - if (mine.equals(other)) { - return mine; - } - throw NOT_EQUALS; - } - - @Override public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) { if (!mine.equals(other)) { throw NOT_EQUALS; @@ -2094,12 +2074,6 @@ public abstract class GeneratedMessageLite< } @Override - public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) { - hashCode = (53 * hashCode) + mine.hashCode(); - return mine; - } - - @Override public Object visitOneofMessage(boolean minePresent, Object mine, Object other) { return visitMessage((MessageLite) mine, (MessageLite) other); } @@ -2128,18 +2102,6 @@ public abstract class GeneratedMessageLite< } @Override - public LazyFieldLite visitLazyMessage(LazyFieldLite mine, LazyFieldLite other) { - final int protoHash; - if (mine != null) { - protoHash = mine.hashCode(); - } else { - protoHash = 37; - } - hashCode = (53 * hashCode) + protoHash; - return mine; - } - - @Override public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) { hashCode = (53 * hashCode) + mine.hashCode(); return mine; @@ -2282,13 +2244,6 @@ public abstract class GeneratedMessageLite< } @Override - public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) { - LazyFieldLite lazy = minePresent ? (LazyFieldLite) mine : new LazyFieldLite(); - lazy.merge((LazyFieldLite) other); - return lazy; - } - - @Override public Object visitOneofMessage(boolean minePresent, Object mine, Object other) { if (minePresent) { return visitMessage((MessageLite) mine, (MessageLite) other); @@ -2312,17 +2267,6 @@ public abstract class GeneratedMessageLite< } @Override - public LazyFieldLite visitLazyMessage(LazyFieldLite mine, LazyFieldLite other) { - if (other != null) { - if (mine == null) { - mine = new LazyFieldLite(); - } - mine.merge(other); - } - return mine; - } - - @Override public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) { int size = mine.size(); int otherSize = other.size(); 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 b949cd17..592869a1 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java @@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.protobuf.Internal.checkNotNull; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; @@ -47,7 +49,6 @@ import com.google.protobuf.Descriptors.OneofDescriptor; // to be able to use GeneratedMessage.GeneratedExtension. The GeneratedExtension definition in // this file is also excluded from opensource to avoid conflict. import com.google.protobuf.GeneratedMessage.GeneratedExtension; - import java.io.IOException; import java.io.InputStream; import java.io.ObjectStreamException; @@ -277,13 +278,30 @@ public abstract class GeneratedMessageV3 extends AbstractMessage /** * Called by subclasses to parse an unknown field. + * * @return {@code true} unless the tag is an end-group tag. */ protected boolean parseUnknownField( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, - int tag) throws IOException { + int tag) + throws IOException { + if (input.shouldDiscardUnknownFields()) { + return input.skipField(tag); + } + return unknownFields.mergeFieldFrom(tag, input); + } + + protected boolean parseUnknownFieldProto3( + CodedInputStream input, + UnknownFieldSet.Builder unknownFields, + ExtensionRegistryLite extensionRegistry, + int tag) + throws IOException { + if (input.shouldDiscardUnknownFieldsProto3()) { + return input.skipField(tag); + } return unknownFields.mergeFieldFrom(tag, input); } @@ -619,15 +637,22 @@ public abstract class GeneratedMessageV3 extends AbstractMessage return (BuilderType) this; } + protected BuilderType setUnknownFieldsProto3(final UnknownFieldSet unknownFields) { + if (CodedInputStream.getProto3DiscardUnknownFieldsDefault()) { + return (BuilderType) this; + } + this.unknownFields = unknownFields; + onChanged(); + return (BuilderType) this; + } + @Override public BuilderType mergeUnknownFields( final UnknownFieldSet unknownFields) { - this.unknownFields = + return setUnknownFields( UnknownFieldSet.newBuilder(this.unknownFields) .mergeFrom(unknownFields) - .build(); - onChanged(); - return (BuilderType) this; + .build()); } @Override @@ -666,18 +691,6 @@ public abstract class GeneratedMessageV3 extends AbstractMessage } /** - * Called by subclasses to parse an unknown field. - * @return {@code true} unless the tag is an end-group tag. - */ - protected boolean parseUnknownField( - final CodedInputStream input, - final UnknownFieldSet.Builder unknownFields, - final ExtensionRegistryLite extensionRegistry, - final int tag) throws IOException { - return unknownFields.mergeFieldFrom(tag, input); - } - - /** * Implementation of {@link BuilderParent} for giving to our children. This * small inner class makes it so we don't publicly expose the BuilderParent * methods. @@ -987,8 +1000,23 @@ public abstract class GeneratedMessageV3 extends AbstractMessage ExtensionRegistryLite extensionRegistry, int tag) throws IOException { return MessageReflection.mergeFieldFrom( - input, unknownFields, extensionRegistry, getDescriptorForType(), - new MessageReflection.ExtensionAdapter(extensions), tag); + input, input.shouldDiscardUnknownFields() ? null : unknownFields, extensionRegistry, + getDescriptorForType(), new MessageReflection.ExtensionAdapter(extensions), tag); + } + + @Override + protected boolean parseUnknownFieldProto3( + CodedInputStream input, + UnknownFieldSet.Builder unknownFields, + ExtensionRegistryLite extensionRegistry, + int tag) throws IOException { + return MessageReflection.mergeFieldFrom( + input, + input.shouldDiscardUnknownFieldsProto3() ? null : unknownFields, + extensionRegistry, + getDescriptorForType(), + new MessageReflection.ExtensionAdapter(extensions), + tag); } @@ -1458,21 +1486,6 @@ public abstract class GeneratedMessageV3 extends AbstractMessage return super.isInitialized() && extensionsAreInitialized(); } - /** - * Called by subclasses to parse an unknown field or an extension. - * @return {@code true} unless the tag is an end-group tag. - */ - @Override - protected boolean parseUnknownField( - final CodedInputStream input, - final UnknownFieldSet.Builder unknownFields, - final ExtensionRegistryLite extensionRegistry, - final int tag) throws IOException { - return MessageReflection.mergeFieldFrom( - input, unknownFields, extensionRegistry, getDescriptorForType(), - new MessageReflection.BuilderAdapter(this), tag); - } - // --------------------------------------------------------------- // Reflection @@ -2277,7 +2290,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage public Object getRepeatedRaw(Builder builder, int index) { return getRepeated(builder, index); } - + @Override public void setRepeated(Builder builder, int index, Object value) { getMutableMapField(builder).getMutableList().set(index, coerceType((Message) value)); @@ -2678,7 +2691,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage return (Extension<MessageType, T>) extension; } - + protected static int computeStringSize(final int fieldNumber, final Object value) { if (value instanceof String) { return CodedOutputStream.computeStringSize(fieldNumber, (String) value); @@ -2686,7 +2699,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage return CodedOutputStream.computeBytesSize(fieldNumber, (ByteString) value); } } - + protected static int computeStringSizeNoTag(final Object value) { if (value instanceof String) { return CodedOutputStream.computeStringSizeNoTag((String) value); @@ -2694,7 +2707,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage return CodedOutputStream.computeBytesSizeNoTag((ByteString) value); } } - + protected static void writeString( CodedOutputStream output, final int fieldNumber, final Object value) throws IOException { if (value instanceof String) { @@ -2703,7 +2716,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage output.writeBytes(fieldNumber, (ByteString) value); } } - + protected static void writeStringNoTag( CodedOutputStream output, final Object value) throws IOException { if (value instanceof String) { 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 36bdece3..848cad03 100644 --- a/java/core/src/main/java/com/google/protobuf/Internal.java +++ b/java/core/src/main/java/com/google/protobuf/Internal.java @@ -414,9 +414,8 @@ public final class Internal { } } - /** - * An empty byte array constant used in generated code. - */ + + /** An empty byte array constant used in generated code. */ public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; /** diff --git a/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java b/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java index 55e33d21..510c6aac 100644 --- a/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java +++ b/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java @@ -50,6 +50,10 @@ public class InvalidProtocolBufferException extends IOException { super(e.getMessage(), e); } + public InvalidProtocolBufferException(final String description, IOException e) { + super(description, e); + } + /** * Attaches an unfinished message to the exception to support best-effort * parsing in {@code Parser} interface. diff --git a/java/core/src/main/java/com/google/protobuf/MessageReflection.java b/java/core/src/main/java/com/google/protobuf/MessageReflection.java index 3d73efb3..69ad7ddf 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageReflection.java +++ b/java/core/src/main/java/com/google/protobuf/MessageReflection.java @@ -31,7 +31,6 @@ package com.google.protobuf; import com.google.protobuf.Descriptors.FieldDescriptor; - import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -714,12 +713,14 @@ class MessageReflection { } /** - * Parses a single field into MergeTarget. The target can be Message.Builder, - * FieldSet or MutableMessage. + * Parses a single field into MergeTarget. The target can be Message.Builder, FieldSet or + * MutableMessage. * - * Package-private because it is used by GeneratedMessage.ExtendableMessage. + * <p>Package-private because it is used by GeneratedMessage.ExtendableMessage. * * @param tag The tag, which should have already been read. + * @param unknownFields If not null, unknown fields will be merged to this {@link + * UnknownFieldSet}, otherwise unknown fields will be discarded. * @return {@code true} unless the tag is an end-group tag. */ static boolean mergeFieldFrom( @@ -728,7 +729,8 @@ class MessageReflection { ExtensionRegistryLite extensionRegistry, Descriptors.Descriptor type, MergeTarget target, - int tag) throws IOException { + int tag) + throws IOException { if (type.getOptions().getMessageSetWireFormat() && tag == WireFormat.MESSAGE_SET_ITEM_TAG) { mergeMessageSetExtensionFromCodedStream( @@ -792,7 +794,11 @@ class MessageReflection { } if (unknown) { // Unknown field or wrong wire type. Skip. - return unknownFields.mergeFieldFrom(tag, input); + if (unknownFields != null) { + return unknownFields.mergeFieldFrom(tag, input); + } else { + return input.skipField(tag); + } } if (packed) { @@ -844,7 +850,9 @@ class MessageReflection { // If the number isn't recognized as a valid value for this enum, // drop it. if (value == null) { - unknownFields.mergeVarintField(fieldNumber, rawValue); + if (unknownFields != null) { + unknownFields.mergeVarintField(fieldNumber, rawValue); + } return true; } } @@ -947,7 +955,7 @@ class MessageReflection { mergeMessageSetExtensionFromBytes( rawBytes, extension, extensionRegistry, target); } else { // We don't know how to parse this. Ignore it. - if (rawBytes != null) { + if (rawBytes != null && unknownFields != null) { unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder() .addLengthDelimited(rawBytes).build()); } 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 53dead80..64094d09 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -34,7 +34,6 @@ import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; - import java.io.IOException; import java.math.BigInteger; import java.nio.CharBuffer; @@ -56,14 +55,7 @@ import java.util.regex.Pattern; public final class TextFormat { private TextFormat() {} - private static final Logger logger = - Logger.getLogger(TextFormat.class.getName()); - - private static final Printer DEFAULT_PRINTER = new Printer(); - private static final Printer SINGLE_LINE_PRINTER = - (new Printer()).setSingleLineMode(true); - private static final Printer UNICODE_PRINTER = - (new Printer()).setEscapeNonAscii(false); + private static final Logger logger = Logger.getLogger(TextFormat.class.getName()); /** * Outputs a textual representation of the Protocol Message supplied into @@ -73,14 +65,14 @@ public final class TextFormat { public static void print( final MessageOrBuilder message, final Appendable output) throws IOException { - DEFAULT_PRINTER.print(message, new TextGenerator(output)); + Printer.DEFAULT.print(message, multiLineOutput(output)); } /** Outputs a textual representation of {@code fields} to {@code output}. */ public static void print(final UnknownFieldSet fields, final Appendable output) throws IOException { - DEFAULT_PRINTER.printUnknownFields(fields, new TextGenerator(output)); + Printer.DEFAULT.printUnknownFields(fields, multiLineOutput(output)); } /** @@ -90,7 +82,7 @@ public final class TextFormat { public static void printUnicode( final MessageOrBuilder message, final Appendable output) throws IOException { - UNICODE_PRINTER.print(message, new TextGenerator(output)); + Printer.UNICODE.print(message, multiLineOutput(output)); } /** @@ -100,7 +92,7 @@ public final class TextFormat { public static void printUnicode(final UnknownFieldSet fields, final Appendable output) throws IOException { - UNICODE_PRINTER.printUnknownFields(fields, new TextGenerator(output)); + Printer.UNICODE.printUnknownFields(fields, multiLineOutput(output)); } /** @@ -109,10 +101,9 @@ public final class TextFormat { */ public static String shortDebugString(final MessageOrBuilder message) { try { - final StringBuilder sb = new StringBuilder(); - SINGLE_LINE_PRINTER.print(message, new TextGenerator(sb)); - // Single line mode currently might have an extra space at the end. - return sb.toString().trim(); + final StringBuilder text = new StringBuilder(); + Printer.DEFAULT.print(message, singleLineOutput(text)); + return text.toString(); } catch (IOException e) { throw new IllegalStateException(e); } @@ -125,11 +116,11 @@ public final class TextFormat { public static String shortDebugString(final FieldDescriptor field, final Object value) { try { - final StringBuilder sb = new StringBuilder(); - SINGLE_LINE_PRINTER.printField(field, value, new TextGenerator(sb)); - return sb.toString().trim(); + final StringBuilder text = new StringBuilder(); + Printer.DEFAULT.printField(field, value, singleLineOutput(text)); + return text.toString(); } catch (IOException e) { - throw new IllegalStateException(e); + throw new IllegalStateException(e); } } @@ -139,10 +130,9 @@ public final class TextFormat { */ public static String shortDebugString(final UnknownFieldSet fields) { try { - final StringBuilder sb = new StringBuilder(); - SINGLE_LINE_PRINTER.printUnknownFields(fields, new TextGenerator(sb)); - // Single line mode currently might have an extra space at the end. - return sb.toString().trim(); + final StringBuilder text = new StringBuilder(); + Printer.DEFAULT.printUnknownFields(fields, singleLineOutput(text)); + return text.toString(); } catch (IOException e) { throw new IllegalStateException(e); } @@ -183,7 +173,7 @@ public final class TextFormat { public static String printToUnicodeString(final MessageOrBuilder message) { try { final StringBuilder text = new StringBuilder(); - UNICODE_PRINTER.print(message, new TextGenerator(text)); + Printer.UNICODE.print(message, multiLineOutput(text)); return text.toString(); } catch (IOException e) { throw new IllegalStateException(e); @@ -197,7 +187,7 @@ public final class TextFormat { public static String printToUnicodeString(final UnknownFieldSet fields) { try { final StringBuilder text = new StringBuilder(); - UNICODE_PRINTER.printUnknownFields(fields, new TextGenerator(text)); + Printer.UNICODE.printUnknownFields(fields, multiLineOutput(text)); return text.toString(); } catch (IOException e) { throw new IllegalStateException(e); @@ -208,7 +198,7 @@ public final class TextFormat { final Object value, final Appendable output) throws IOException { - DEFAULT_PRINTER.printField(field, value, new TextGenerator(output)); + Printer.DEFAULT.printField(field, value, multiLineOutput(output)); } public static String printFieldToString(final FieldDescriptor field, @@ -223,6 +213,23 @@ public final class TextFormat { } /** + * Outputs a unicode textual representation of the value of given field value. + * + * <p>Same as {@code printFieldValue()}, except that non-ASCII characters in string type fields + * are not escaped in backslash+octals. + * + * @param field the descriptor of the field + * @param value the value of the field + * @param output the output to which to append the formatted value + * @throws ClassCastException if the value is not appropriate for the given field descriptor + * @throws IOException if there is an exception writing to the output + */ + public static void printUnicodeFieldValue( + final FieldDescriptor field, final Object value, final Appendable output) throws IOException { + Printer.UNICODE.printFieldValue(field, value, multiLineOutput(output)); + } + + /** * Outputs a textual representation of the value of given field value. * * @param field the descriptor of the field @@ -236,7 +243,7 @@ public final class TextFormat { final Object value, final Appendable output) throws IOException { - DEFAULT_PRINTER.printFieldValue(field, value, new TextGenerator(output)); + Printer.DEFAULT.printFieldValue(field, value, multiLineOutput(output)); } /** @@ -253,7 +260,7 @@ public final class TextFormat { final Object value, final Appendable output) throws IOException { - printUnknownFieldValue(tag, value, new TextGenerator(output)); + printUnknownFieldValue(tag, value, multiLineOutput(output)); } private static void printUnknownFieldValue(final int tag, @@ -277,7 +284,7 @@ public final class TextFormat { generator.print("\""); break; case WireFormat.WIRETYPE_START_GROUP: - DEFAULT_PRINTER.printUnknownFields((UnknownFieldSet) value, generator); + Printer.DEFAULT.printUnknownFields((UnknownFieldSet) value, generator); break; default: throw new IllegalArgumentException("Bad tag: " + tag); @@ -286,24 +293,16 @@ public final class TextFormat { /** Helper class for converting protobufs to text. */ private static final class Printer { - /** Whether to omit newlines from the output. */ - boolean singleLineMode = false; + // Printer instance which escapes non-ASCII characters. + static final Printer DEFAULT = new Printer(true); + // Printer instance which emits Unicode (it still escapes newlines and quotes in strings). + static final Printer UNICODE = new Printer(false); /** Whether to escape non ASCII characters with backslash and octal. */ - boolean escapeNonAscii = true; - - private Printer() {} + private final boolean escapeNonAscii; - /** Setter of singleLineMode */ - private Printer setSingleLineMode(boolean singleLineMode) { - this.singleLineMode = singleLineMode; - return this; - } - - /** Setter of escapeNonAscii */ - private Printer setEscapeNonAscii(boolean escapeNonAscii) { + private Printer(boolean escapeNonAscii) { this.escapeNonAscii = escapeNonAscii; - return this; } private void print( @@ -355,12 +354,9 @@ public final class TextFormat { } if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { - if (singleLineMode) { - generator.print(" { "); - } else { - generator.print(" {\n"); - generator.indent(); - } + generator.print(" {"); + generator.eol(); + generator.indent(); } else { generator.print(": "); } @@ -368,19 +364,10 @@ public final class TextFormat { printFieldValue(field, value, generator); if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { - if (singleLineMode) { - generator.print("} "); - } else { - generator.outdent(); - generator.print("}\n"); - } - } else { - if (singleLineMode) { - generator.print(" "); - } else { - generator.print("\n"); - } + generator.outdent(); + generator.print("}"); } + generator.eol(); } private void printFieldValue(final FieldDescriptor field, @@ -469,19 +456,13 @@ public final class TextFormat { field.getLengthDelimitedList(), generator); for (final UnknownFieldSet value : field.getGroupList()) { generator.print(entry.getKey().toString()); - if (singleLineMode) { - generator.print(" { "); - } else { - generator.print(" {\n"); - generator.indent(); - } + generator.print(" {"); + generator.eol(); + generator.indent(); printUnknownFields(value, generator); - if (singleLineMode) { - generator.print("} "); - } else { - generator.outdent(); - generator.print("}\n"); - } + generator.outdent(); + generator.print("}"); + generator.eol(); } } } @@ -495,7 +476,7 @@ public final class TextFormat { generator.print(String.valueOf(number)); generator.print(": "); printUnknownFieldValue(wireType, value, generator); - generator.print(singleLineMode ? " " : "\n"); + generator.eol(); } } } @@ -521,16 +502,29 @@ public final class TextFormat { } } - /** + private static TextGenerator multiLineOutput(Appendable output) { + return new TextGenerator(output, false); + } + + private static TextGenerator singleLineOutput(Appendable output) { + return new TextGenerator(output, true); + } + + /** * An inner class for writing text to the output stream. */ private static final class TextGenerator { private final Appendable output; private final StringBuilder indent = new StringBuilder(); - private boolean atStartOfLine = true; + private final boolean singleLineMode; + // While technically we are "at the start of a line" at the very beginning of the output, all + // we would do in response to this is emit the (zero length) indentation, so it has no effect. + // Setting it false here does however suppress an unwanted leading space in single-line mode. + private boolean atStartOfLine = false; - private TextGenerator(final Appendable output) { + private TextGenerator(final Appendable output, boolean singleLineMode) { this.output = output; + this.singleLineMode = singleLineMode; } /** @@ -552,35 +546,31 @@ public final class TextFormat { throw new IllegalArgumentException( " Outdent() without matching Indent()."); } - indent.delete(length - 2, length); + indent.setLength(length - 2); } /** - * Print text to the output stream. + * Print text to the output stream. Bare newlines are never expected to be passed to this + * method; to indicate the end of a line, call "eol()". */ public void print(final CharSequence text) throws IOException { - final int size = text.length(); - int pos = 0; - - for (int i = 0; i < size; i++) { - if (text.charAt(i) == '\n') { - write(text.subSequence(pos, i + 1)); - pos = i + 1; - atStartOfLine = true; - } + if (atStartOfLine) { + atStartOfLine = false; + output.append(singleLineMode ? " " : indent); } - write(text.subSequence(pos, size)); + output.append(text); } - private void write(final CharSequence data) throws IOException { - if (data.length() == 0) { - return; - } - if (atStartOfLine) { - atStartOfLine = false; - output.append(indent); + /** + * Signifies reaching the "end of the current line" in the output. In single-line mode, this + * does not result in a newline being emitted, but ensures that a separating space is written + * before the next output. + */ + public void eol() throws IOException { + if (!singleLineMode) { + output.append("\n"); } - output.append(data); + atStartOfLine = true; } } @@ -1469,9 +1459,15 @@ public final class TextFormat { extensionRegistry, name.toString()); if (extension == null) { - unknownFields.add((tokenizer.getPreviousLine() + 1) + ":" + - (tokenizer.getPreviousColumn() + 1) + ":\t" + - type.getFullName() + ".[" + name + "]"); + unknownFields.add( + (tokenizer.getPreviousLine() + 1) + + ":" + + (tokenizer.getPreviousColumn() + 1) + + ":\t" + + type.getFullName() + + ".[" + + name + + "]"); } else { if (extension.descriptor.getContainingType() != type) { throw tokenizer.parseExceptionPreviousToken( @@ -1506,9 +1502,14 @@ public final class TextFormat { } if (field == null) { - unknownFields.add((tokenizer.getPreviousLine() + 1) + ":" + - (tokenizer.getPreviousColumn() + 1) + ":\t" + - type.getFullName() + "." + name); + unknownFields.add( + (tokenizer.getPreviousLine() + 1) + + ":" + + (tokenizer.getPreviousColumn() + 1) + + ":\t" + + type.getFullName() + + "." + + name); } } 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 d9381135..37d64633 100644 --- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java +++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java @@ -715,7 +715,7 @@ public final class UnknownFieldSet implements MessageLite { * @see UnknownFieldSet */ public static final class Field { - Field() {} + private 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 ca80d946..acc03a7c 100644 --- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java +++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java @@ -47,8 +47,29 @@ final class UnsafeUtil { 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 BYTE_ARRAY_BASE_OFFSET = arrayBaseOffset(byte[].class); + // Micro-optimization: we can assume a scale of 1 and skip the multiply + // private static final long BYTE_ARRAY_INDEX_SCALE = 1; + + private static final long BOOLEAN_ARRAY_BASE_OFFSET = arrayBaseOffset(boolean[].class); + private static final long BOOLEAN_ARRAY_INDEX_SCALE = arrayIndexScale(boolean[].class); + + private static final long INT_ARRAY_BASE_OFFSET = arrayBaseOffset(int[].class); + private static final long INT_ARRAY_INDEX_SCALE = arrayIndexScale(int[].class); + + private static final long LONG_ARRAY_BASE_OFFSET = arrayBaseOffset(long[].class); + private static final long LONG_ARRAY_INDEX_SCALE = arrayIndexScale(long[].class); + + private static final long FLOAT_ARRAY_BASE_OFFSET = arrayBaseOffset(float[].class); + private static final long FLOAT_ARRAY_INDEX_SCALE = arrayIndexScale(float[].class); + + private static final long DOUBLE_ARRAY_BASE_OFFSET = arrayBaseOffset(double[].class); + private static final long DOUBLE_ARRAY_INDEX_SCALE = arrayIndexScale(double[].class); + + private static final long OBJECT_ARRAY_BASE_OFFSET = arrayBaseOffset(Object[].class); + private static final long OBJECT_ARRAY_INDEX_SCALE = arrayIndexScale(Object[].class); + private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(bufferAddressField()); private UnsafeUtil() {} @@ -57,10 +78,6 @@ final class UnsafeUtil { return HAS_UNSAFE_ARRAY_OPERATIONS; } - static boolean hasUnsafeCopyMemory() { - return HAS_UNSAFE_COPY_MEMORY; - } - static boolean hasUnsafeByteBufferOperations() { return HAS_UNSAFE_BYTEBUFFER_OPERATIONS; } @@ -69,8 +86,12 @@ final class UnsafeUtil { return MEMORY_ACCESSOR.objectFieldOffset(field); } - static long getArrayBaseOffset() { - return ARRAY_BASE_OFFSET; + private static int arrayBaseOffset(Class<?> clazz) { + return HAS_UNSAFE_ARRAY_OPERATIONS ? MEMORY_ACCESSOR.arrayBaseOffset(clazz) : -1; + } + + private static int arrayIndexScale(Class<?> clazz) { + return HAS_UNSAFE_ARRAY_OPERATIONS ? MEMORY_ACCESSOR.arrayIndexScale(clazz) : -1; } static byte getByte(Object target, long offset) { @@ -129,9 +150,82 @@ final class UnsafeUtil { MEMORY_ACCESSOR.putObject(target, offset, value); } - static void copyMemory( - Object src, long srcOffset, Object target, long targetOffset, long length) { - MEMORY_ACCESSOR.copyMemory(src, srcOffset, target, targetOffset, length); + static byte getByte(byte[] target, long index) { + return MEMORY_ACCESSOR.getByte(target, BYTE_ARRAY_BASE_OFFSET + index); + } + + static void putByte(byte[] target, long index, byte value) { + MEMORY_ACCESSOR.putByte(target, BYTE_ARRAY_BASE_OFFSET + index, value); + } + + static int getInt(int[] target, long index) { + return MEMORY_ACCESSOR.getInt(target, INT_ARRAY_BASE_OFFSET + (index * INT_ARRAY_INDEX_SCALE)); + } + + static void putInt(int[] target, long index, int value) { + MEMORY_ACCESSOR.putInt(target, INT_ARRAY_BASE_OFFSET + (index * INT_ARRAY_INDEX_SCALE), value); + } + + static long getLong(long[] target, long index) { + return MEMORY_ACCESSOR.getLong( + target, LONG_ARRAY_BASE_OFFSET + (index * LONG_ARRAY_INDEX_SCALE)); + } + + static void putLong(long[] target, long index, long value) { + MEMORY_ACCESSOR.putLong( + target, LONG_ARRAY_BASE_OFFSET + (index * LONG_ARRAY_INDEX_SCALE), value); + } + + static boolean getBoolean(boolean[] target, long index) { + return MEMORY_ACCESSOR.getBoolean( + target, BOOLEAN_ARRAY_BASE_OFFSET + (index * BOOLEAN_ARRAY_INDEX_SCALE)); + } + + static void putBoolean(boolean[] target, long index, boolean value) { + MEMORY_ACCESSOR.putBoolean( + target, BOOLEAN_ARRAY_BASE_OFFSET + (index * BOOLEAN_ARRAY_INDEX_SCALE), value); + } + + static float getFloat(float[] target, long index) { + return MEMORY_ACCESSOR.getFloat( + target, FLOAT_ARRAY_BASE_OFFSET + (index * FLOAT_ARRAY_INDEX_SCALE)); + } + + static void putFloat(float[] target, long index, float value) { + MEMORY_ACCESSOR.putFloat( + target, FLOAT_ARRAY_BASE_OFFSET + (index * FLOAT_ARRAY_INDEX_SCALE), value); + } + + static double getDouble(double[] target, long index) { + return MEMORY_ACCESSOR.getDouble( + target, DOUBLE_ARRAY_BASE_OFFSET + (index * DOUBLE_ARRAY_INDEX_SCALE)); + } + + static void putDouble(double[] target, long index, double value) { + MEMORY_ACCESSOR.putDouble( + target, DOUBLE_ARRAY_BASE_OFFSET + (index * DOUBLE_ARRAY_INDEX_SCALE), value); + } + + static Object getObject(Object[] target, long index) { + return MEMORY_ACCESSOR.getObject( + target, OBJECT_ARRAY_BASE_OFFSET + (index * OBJECT_ARRAY_INDEX_SCALE)); + } + + static void putObject(Object[] target, long index, Object value) { + MEMORY_ACCESSOR.putObject( + target, OBJECT_ARRAY_BASE_OFFSET + (index * OBJECT_ARRAY_INDEX_SCALE), value); + } + + static void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) { + MEMORY_ACCESSOR.copyMemory(src, srcIndex, targetOffset, length); + } + + static void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) { + MEMORY_ACCESSOR.copyMemory(srcOffset, target, targetIndex, length); + } + + static void copyMemory(byte[] src, long srcIndex, byte[] target, long targetIndex, long length) { + System.arraycopy(src, (int) srcIndex, target, (int) targetIndex, (int) length); } static byte getByte(long address) { @@ -221,6 +315,7 @@ final class UnsafeUtil { Class<?> clazz = UNSAFE.getClass(); clazz.getMethod("objectFieldOffset", Field.class); clazz.getMethod("arrayBaseOffset", Class.class); + clazz.getMethod("arrayIndexScale", 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); @@ -245,27 +340,6 @@ final class UnsafeUtil { 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() { if (UNSAFE == null) { return false; @@ -283,6 +357,7 @@ final class UnsafeUtil { clazz.getMethod("getLong", long.class); clazz.getMethod("putLong", long.class, long.class); clazz.getMethod("copyMemory", long.class, long.class, long.class); + clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class); return true; } catch (Throwable e) { logger.log( @@ -308,13 +383,6 @@ final class UnsafeUtil { } /** - * 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 ? MEMORY_ACCESSOR.arrayBaseOffset(byte[].class) : -1; - } - - /** * Returns the offset of the provided field, or {@code -1} if {@code sun.misc.Unsafe} is not * available. */ @@ -394,6 +462,10 @@ final class UnsafeUtil { return unsafe.arrayBaseOffset(clazz); } + public final int arrayIndexScale(Class<?> clazz) { + return unsafe.arrayIndexScale(clazz); + } + public abstract byte getByte(long address); public abstract void putByte(long address, byte value); @@ -408,10 +480,11 @@ final class UnsafeUtil { 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); + + public abstract void copyMemory(long srcOffset, byte[] target, long targetIndex, long length); + + public abstract void copyMemory(byte[] src, long srcIndex, long targetOffset, long length); } private static final class JvmMemoryAccessor extends MemoryAccessor { @@ -491,15 +564,19 @@ final class UnsafeUtil { } @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 void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) { + unsafe.copyMemory(null, srcOffset, target, BYTE_ARRAY_BASE_OFFSET + targetIndex, length); + } + + @Override + public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) { + unsafe.copyMemory(src, BYTE_ARRAY_BASE_OFFSET + srcIndex, null, targetOffset, length); + } @Override public Object getStaticObject(Field 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 d98e914d..1b136144 100644 --- a/java/core/src/main/java/com/google/protobuf/Utf8.java +++ b/java/core/src/main/java/com/google/protobuf/Utf8.java @@ -31,7 +31,6 @@ package com.google.protobuf; import static com.google.protobuf.UnsafeUtil.addressOffset; -import static com.google.protobuf.UnsafeUtil.getArrayBaseOffset; import static com.google.protobuf.UnsafeUtil.hasUnsafeArrayOperations; import static com.google.protobuf.UnsafeUtil.hasUnsafeByteBufferOperations; import static java.lang.Character.MAX_SURROGATE; @@ -1001,8 +1000,8 @@ final class Utf8 { throw new ArrayIndexOutOfBoundsException( String.format("Array length=%d, index=%d, limit=%d", bytes.length, index, limit)); } - long offset = getArrayBaseOffset() + index; - final long offsetLimit = getArrayBaseOffset() + limit; + long offset = index; + final long offsetLimit = limit; if (state != COMPLETE) { // The previous decoding operation was incomplete (or malformed). // We look for a well-formed sequence consisting of bytes from @@ -1187,7 +1186,7 @@ final class Utf8 { @Override int encodeUtf8(final CharSequence in, final byte[] out, final int offset, final int length) { - long outIx = getArrayBaseOffset() + offset; + long outIx = offset; final long outLimit = outIx + length; final int inLimit = in.length(); if (inLimit > length || out.length - length < offset) { @@ -1204,7 +1203,7 @@ final class Utf8 { } if (inIx == inLimit) { // We're done, it was ASCII encoded. - return (int) (outIx - getArrayBaseOffset()); + return (int) outIx; } for (char c; inIx < inLimit; ++inIx) { @@ -1243,7 +1242,7 @@ final class Utf8 { } // All bytes have been encoded. - return (int) (outIx - getArrayBaseOffset()); + return (int) outIx; } @Override @@ -1321,31 +1320,17 @@ final class Utf8 { */ private static int unsafeEstimateConsecutiveAscii( byte[] bytes, long offset, final int maxChars) { - int remaining = maxChars; - if (remaining < UNSAFE_COUNT_ASCII_THRESHOLD) { + if (maxChars < UNSAFE_COUNT_ASCII_THRESHOLD) { // Don't bother with small strings. return 0; } - // Read bytes until 8-byte aligned so that we can read longs in the loop below. - // Byte arrays are already either 8 or 16-byte aligned, so we just need to make sure that - // 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 = 8 - ((int) offset & 7); - for (int j = unaligned; j > 0; j--) { + for (int i = 0; i < maxChars; i++) { if (UnsafeUtil.getByte(bytes, offset++) < 0) { - return unaligned - j; + return i; } } - - // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII). - // To speed things up further, we're reading longs instead of bytes so we use a mask to - // determine if any byte in the current long is non-ASCII. - remaining -= unaligned; - for (; remaining >= 8 && (UnsafeUtil.getLong(bytes, offset) & ASCII_MASK_LONG) == 0; - offset += 8, remaining -= 8) {} - return maxChars - remaining; + return maxChars; } /** diff --git a/java/core/src/main/java/com/google/protobuf/WireFormat.java b/java/core/src/main/java/com/google/protobuf/WireFormat.java index 0b0cdb7d..8b837ee5 100644 --- a/java/core/src/main/java/com/google/protobuf/WireFormat.java +++ b/java/core/src/main/java/com/google/protobuf/WireFormat.java @@ -47,8 +47,10 @@ public final class WireFormat { // Do not allow instantiation. private WireFormat() {} - static final int FIXED_32_SIZE = 4; - static final int FIXED_64_SIZE = 8; + static final int FIXED32_SIZE = 4; + static final int FIXED64_SIZE = 8; + static final int MAX_VARINT32_SIZE = 5; + static final int MAX_VARINT64_SIZE = 10; static final int MAX_VARINT_SIZE = 10; public static final int WIRETYPE_VARINT = 0; diff --git a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java index e440c7db..da2c067e 100644 --- a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java +++ b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java @@ -41,6 +41,7 @@ import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; +import java.util.Arrays; import junit.framework.TestCase; /** @@ -613,6 +614,82 @@ public class CodedInputStreamTest extends TestCase { checkSizeLimitExceeded(expected); } } + + public void testRefillBufferWithCorrectSize() throws Exception { + // NOTE: refillBuffer only applies to the stream-backed CIS. + byte[] bytes = "123456789".getBytes("UTF-8"); + ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length); + + int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); + output.writeRawVarint32(tag); + output.writeRawVarint32(bytes.length); + output.writeRawBytes(bytes); + output.writeRawVarint32(tag); + output.writeRawVarint32(bytes.length); + output.writeRawBytes(bytes); + output.writeRawByte(4); + output.flush(); + + // Input is two string with length 9 and one raw byte. + byte[] rawInput = rawOutput.toByteArray(); + for (int inputStreamBufferLength = 8; + inputStreamBufferLength <= rawInput.length + 1; inputStreamBufferLength++) { + CodedInputStream input = CodedInputStream.newInstance( + new ByteArrayInputStream(rawInput), inputStreamBufferLength); + input.setSizeLimit(rawInput.length - 1); + input.readString(); + input.readString(); + try { + input.readRawByte(); // Hits limit. + fail("Should have thrown an exception!"); + } catch (InvalidProtocolBufferException expected) { + checkSizeLimitExceeded(expected); + } + } + } + + public void testIsAtEnd() throws Exception { + CodedInputStream input = CodedInputStream.newInstance( + new ByteArrayInputStream(new byte[5])); + try { + for (int i = 0; i < 5; i++) { + assertEquals(false, input.isAtEnd()); + input.readRawByte(); + } + assertEquals(true, input.isAtEnd()); + } catch (Exception e) { + fail("Catch exception in the testIsAtEnd"); + } + } + + public void testCurrentLimitExceeded() throws Exception { + byte[] bytes = "123456789".getBytes("UTF-8"); + ByteArrayOutputStream rawOutput = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length); + + int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED); + output.writeRawVarint32(tag); + output.writeRawVarint32(bytes.length); + output.writeRawBytes(bytes); + output.flush(); + + byte[] rawInput = rawOutput.toByteArray(); + CodedInputStream input = CodedInputStream.newInstance( + new ByteArrayInputStream(rawInput)); + // The length of the whole rawInput + input.setSizeLimit(11); + // Some number that is smaller than the rawInput's length + // but larger than 2 + input.pushLimit(5); + try { + input.readString(); + fail("Should have thrown an exception"); + } catch (InvalidProtocolBufferException expected) { + assertEquals(expected.getMessage(), + InvalidProtocolBufferException.truncatedMessage().getMessage()); + } + } public void testSizeLimitMultipleMessages() throws Exception { // NOTE: Size limit only applies to the stream-backed CIS. @@ -807,6 +884,52 @@ public class CodedInputStreamTest extends TestCase { } } + public void testReadLargeByteStringFromInputStream() throws Exception { + byte[] bytes = new byte[1024 * 1024]; + for (int i = 0; i < bytes.length; i++) { + bytes[i] = (byte) (i & 0xFF); + } + ByteString.Output rawOutput = ByteString.newOutput(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); + output.writeRawVarint32(bytes.length); + output.writeRawBytes(bytes); + output.flush(); + byte[] data = rawOutput.toByteString().toByteArray(); + + CodedInputStream input = CodedInputStream.newInstance( + new ByteArrayInputStream(data) { + @Override + public synchronized int available() { + return 0; + } + }); + ByteString result = input.readBytes(); + assertEquals(ByteString.copyFrom(bytes), result); + } + + public void testReadLargeByteArrayFromInputStream() throws Exception { + byte[] bytes = new byte[1024 * 1024]; + for (int i = 0; i < bytes.length; i++) { + bytes[i] = (byte) (i & 0xFF); + } + ByteString.Output rawOutput = ByteString.newOutput(); + CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); + output.writeRawVarint32(bytes.length); + output.writeRawBytes(bytes); + output.flush(); + byte[] data = rawOutput.toByteString().toByteArray(); + + CodedInputStream input = CodedInputStream.newInstance( + new ByteArrayInputStream(data) { + @Override + public synchronized int available() { + return 0; + } + }); + byte[] result = input.readByteArray(); + assertTrue(Arrays.equals(bytes, result)); + } + public void testReadByteBuffer() throws Exception { ByteString.Output rawOutput = ByteString.newOutput(); CodedOutputStream output = CodedOutputStream.newInstance(rawOutput); diff --git a/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java b/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java new file mode 100644 index 00000000..0f09a51b --- /dev/null +++ b/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java @@ -0,0 +1,157 @@ +// 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; + +import static org.junit.Assert.assertEquals; + +import protobuf_unittest.UnittestProto; +import proto3_unittest.UnittestProto3; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for discard or preserve unknown fields. */ +@RunWith(JUnit4.class) +public class DiscardUnknownFieldsTest { + @Test + public void testProto2() throws Exception { + testProto2Message( + UnittestProto.TestEmptyMessage.getDefaultInstance()); + testProto2Message( + UnittestProto.TestEmptyMessageWithExtensions.getDefaultInstance()); + testProto2Message( + DynamicMessage.getDefaultInstance(UnittestProto.TestEmptyMessage.getDescriptor())); + testProto2Message( + DynamicMessage.getDefaultInstance( + UnittestProto.TestEmptyMessageWithExtensions.getDescriptor())); + } + + @Test + public void testProto3() throws Exception { + testProto3Message(UnittestProto3.TestEmptyMessage.getDefaultInstance()); + testProto3Message( + DynamicMessage.getDefaultInstance(UnittestProto3.TestEmptyMessage.getDescriptor())); + } + + private static void testProto2Message(Message message) throws Exception { + assertUnknownFieldsDefaultPreserved(message); + assertUnknownFieldsExplicitlyDiscarded(message); + assertReuseCodedInputStreamPreserve(message); + assertUnknownFieldsInUnknownFieldSetArePreserve(message); + } + + private static void testProto3Message(Message message) throws Exception { + CodedInputStream.setProto3KeepUnknownsByDefaultForTest(); + assertUnknownFieldsDefaultPreserved(message); + assertUnknownFieldsExplicitlyDiscarded(message); + assertReuseCodedInputStreamPreserve(message); + assertUnknownFieldsInUnknownFieldSetArePreserve(message); + CodedInputStream.setProto3DiscardUnknownsByDefaultForTest(); + assertUnknownFieldsDefaultDiscarded(message); + assertUnknownFieldsExplicitlyDiscarded(message); + assertUnknownFieldsInUnknownFieldSetAreDiscarded(message); + } + + private static void assertReuseCodedInputStreamPreserve(Message message) throws Exception { + final int messageSize = payload.size(); + byte[] copied = new byte[messageSize * 2]; + payload.copyTo(copied, 0); + payload.copyTo(copied, messageSize); + CodedInputStream input = CodedInputStream.newInstance(copied); + { + // Use DiscardUnknownFieldsParser to parse the first payload. + int oldLimit = input.pushLimit(messageSize); + Message parsed = DiscardUnknownFieldsParser.wrap(message.getParserForType()).parseFrom(input); + assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize()); + input.popLimit(oldLimit); + } + { + // Use the normal parser to parse the remaining payload should have unknown fields preserved. + Message parsed = message.getParserForType().parseFrom(input); + assertEquals(message.getClass().getName(), payload, parsed.toByteString()); + } + } + + /** + * {@link Message.Builder#setUnknownFields(UnknownFieldSet)} and {@link + * Message.Builder#mergeUnknownFields(UnknownFieldSet)} should preserve the unknown fields. + */ + private static void assertUnknownFieldsInUnknownFieldSetArePreserve(Message message) + throws Exception { + UnknownFieldSet unknownFields = UnknownFieldSet.newBuilder().mergeFrom(payload).build(); + Message built = message.newBuilderForType().setUnknownFields(unknownFields).build(); + assertEquals(message.getClass().getName(), payload, built.toByteString()); + + } + /** + * {@link Message.Builder#setUnknownFields(UnknownFieldSet)} and {@link + * Message.Builder#mergeUnknownFields(UnknownFieldSet)} should discard the unknown fields. + */ + private static void assertUnknownFieldsInUnknownFieldSetAreDiscarded(Message message) + throws Exception { + UnknownFieldSet unknownFields = UnknownFieldSet.newBuilder().mergeFrom(payload).build(); + Message built = message.newBuilderForType().setUnknownFields(unknownFields).build(); + assertEquals(message.getClass().getName(), 0, built.getSerializedSize()); + } + + private static void assertUnknownFieldsDefaultPreserved(MessageLite message) throws Exception { + { + MessageLite parsed = message.getParserForType().parseFrom(payload); + assertEquals(message.getClass().getName(), payload, parsed.toByteString()); + } + + { + MessageLite parsed = message.newBuilderForType().mergeFrom(payload).build(); + assertEquals(message.getClass().getName(), payload, parsed.toByteString()); + } + } + + private static void assertUnknownFieldsDefaultDiscarded(MessageLite message) throws Exception { + { + MessageLite parsed = message.getParserForType().parseFrom(payload); + assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize()); + } + + { + MessageLite parsed = message.newBuilderForType().mergeFrom(payload).build(); + assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize()); + } + } + + private static void assertUnknownFieldsExplicitlyDiscarded(Message message) throws Exception { + Message parsed = + DiscardUnknownFieldsParser.wrap(message.getParserForType()).parseFrom(payload); + assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize()); + } + + private static final ByteString payload = + TestUtilLite.getAllLiteSetBuilder().build().toByteString(); +} diff --git a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java index 4a42c897..ff686a0c 100644 --- a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java +++ b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java @@ -108,7 +108,7 @@ public class FieldPresenceTest extends TestCase { assertFalse(TestAllTypes.newBuilder().build().hasOptionalNestedMessage()); assertFalse(TestAllTypes.newBuilder().hasOptionalNestedMessage()); - // oneof fields don't have hasFoo() methods (even for message types). + // oneof fields don't have hasFoo() methods for non-message types. assertHasMethodRemoved( UnittestProto.TestAllTypes.class, TestAllTypes.class, @@ -121,10 +121,8 @@ public class FieldPresenceTest extends TestCase { UnittestProto.TestAllTypes.class, TestAllTypes.class, "OneofBytes"); - assertHasMethodRemoved( - UnittestProto.TestAllTypes.class, - TestAllTypes.class, - "OneofNestedMessage"); + assertFalse(TestAllTypes.newBuilder().build().hasOneofNestedMessage()); + assertFalse(TestAllTypes.newBuilder().hasOneofNestedMessage()); assertHasMethodRemoved( UnittestProto.TestAllTypes.Builder.class, @@ -138,10 +136,6 @@ public class FieldPresenceTest extends TestCase { UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OneofBytes"); - assertHasMethodRemoved( - UnittestProto.TestAllTypes.Builder.class, - TestAllTypes.Builder.class, - "OneofNestedMessage"); } public void testOneofEquals() throws Exception { diff --git a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java index 3eece26a..a4311d17 100644 --- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java @@ -923,15 +923,9 @@ public class GeneratedMessageTest extends TestCase { } public void testEnumValues() { - assertEquals( - TestAllTypes.NestedEnum.BAR.getNumber(), - TestAllTypes.NestedEnum.BAR_VALUE); - assertEquals( - TestAllTypes.NestedEnum.BAZ.getNumber(), - TestAllTypes.NestedEnum.BAZ_VALUE); - assertEquals( - TestAllTypes.NestedEnum.FOO.getNumber(), - TestAllTypes.NestedEnum.FOO_VALUE); + assertEquals(TestAllTypes.NestedEnum.BAR_VALUE, TestAllTypes.NestedEnum.BAR.getNumber()); + assertEquals(TestAllTypes.NestedEnum.BAZ_VALUE, TestAllTypes.NestedEnum.BAZ.getNumber()); + assertEquals(TestAllTypes.NestedEnum.FOO_VALUE, TestAllTypes.NestedEnum.FOO.getNumber()); } public void testNonNestedExtensionInitialization() { @@ -1319,51 +1313,51 @@ public class GeneratedMessageTest extends TestCase { assertFalse(builder.clearFooInt().hasFooInt()); TestOneof2 message2 = builder.build(); assertFalse(message2.hasFooInt()); - assertEquals(message2.getFooInt(), 0); + assertEquals(0, message2.getFooInt()); } // Enum { TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals(builder.getFooEnum(), TestOneof2.NestedEnum.FOO); + assertEquals(TestOneof2.NestedEnum.FOO, builder.getFooEnum()); assertTrue(builder.setFooEnum(TestOneof2.NestedEnum.BAR).hasFooEnum()); - assertEquals(builder.getFooEnum(), TestOneof2.NestedEnum.BAR); + assertEquals(TestOneof2.NestedEnum.BAR, builder.getFooEnum()); TestOneof2 message = builder.buildPartial(); assertTrue(message.hasFooEnum()); - assertEquals(message.getFooEnum(), TestOneof2.NestedEnum.BAR); + assertEquals(TestOneof2.NestedEnum.BAR, message.getFooEnum()); assertFalse(builder.clearFooEnum().hasFooEnum()); TestOneof2 message2 = builder.build(); assertFalse(message2.hasFooEnum()); - assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.FOO); + assertEquals(TestOneof2.NestedEnum.FOO, message2.getFooEnum()); } // String { TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals(builder.getFooString(), ""); + assertEquals("", builder.getFooString()); builder.setFooString("foo"); assertTrue(builder.hasFooString()); - assertEquals(builder.getFooString(), "foo"); + assertEquals("foo", builder.getFooString()); TestOneof2 message = builder.buildPartial(); assertTrue(message.hasFooString()); - assertEquals(message.getFooString(), "foo"); + assertEquals("foo", message.getFooString()); assertEquals(message.getFooStringBytes(), TestUtil.toBytes("foo")); assertFalse(builder.clearFooString().hasFooString()); TestOneof2 message2 = builder.buildPartial(); assertFalse(message2.hasFooString()); - assertEquals(message2.getFooString(), ""); + assertEquals("", message2.getFooString()); assertEquals(message2.getFooStringBytes(), TestUtil.toBytes("")); // Get method should not change the oneof value. builder.setFooInt(123); - assertEquals(builder.getFooString(), ""); + assertEquals("", builder.getFooString()); assertEquals(builder.getFooStringBytes(), TestUtil.toBytes("")); assertEquals(123, builder.getFooInt()); message = builder.build(); - assertEquals(message.getFooString(), ""); + assertEquals("", message.getFooString()); assertEquals(message.getFooStringBytes(), TestUtil.toBytes("")); assertEquals(123, message.getFooInt()); } @@ -1371,38 +1365,38 @@ public class GeneratedMessageTest extends TestCase { // Cord { TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals(builder.getFooCord(), ""); + assertEquals("", builder.getFooCord()); builder.setFooCord("foo"); assertTrue(builder.hasFooCord()); - assertEquals(builder.getFooCord(), "foo"); + assertEquals("foo", builder.getFooCord()); TestOneof2 message = builder.buildPartial(); assertTrue(message.hasFooCord()); - assertEquals(message.getFooCord(), "foo"); + assertEquals("foo", message.getFooCord()); assertEquals(message.getFooCordBytes(), TestUtil.toBytes("foo")); assertFalse(builder.clearFooCord().hasFooCord()); TestOneof2 message2 = builder.build(); assertFalse(message2.hasFooCord()); - assertEquals(message2.getFooCord(), ""); + assertEquals("", message2.getFooCord()); assertEquals(message2.getFooCordBytes(), TestUtil.toBytes("")); } // StringPiece { TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals(builder.getFooStringPiece(), ""); + assertEquals("", builder.getFooStringPiece()); builder.setFooStringPiece("foo"); assertTrue(builder.hasFooStringPiece()); - assertEquals(builder.getFooStringPiece(), "foo"); + assertEquals("foo", builder.getFooStringPiece()); TestOneof2 message = builder.buildPartial(); assertTrue(message.hasFooStringPiece()); - assertEquals(message.getFooStringPiece(), "foo"); + assertEquals("foo", message.getFooStringPiece()); assertEquals(message.getFooStringPieceBytes(), TestUtil.toBytes("foo")); assertFalse(builder.clearFooStringPiece().hasFooStringPiece()); TestOneof2 message2 = builder.build(); assertFalse(message2.hasFooStringPiece()); - assertEquals(message2.getFooStringPiece(), ""); + assertEquals("", message2.getFooStringPiece()); assertEquals(message2.getFooStringPieceBytes(), TestUtil.toBytes("")); } @@ -1410,20 +1404,20 @@ public class GeneratedMessageTest extends TestCase { { // set TestOneof2.Builder builder = TestOneof2.newBuilder(); - assertEquals(builder.getFooMessage().getQuxInt(), 0); + assertEquals(0, builder.getFooMessage().getQuxInt()); builder.setFooMessage( TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()); assertTrue(builder.hasFooMessage()); - assertEquals(builder.getFooMessage().getQuxInt(), 234); + assertEquals(234, builder.getFooMessage().getQuxInt()); TestOneof2 message = builder.buildPartial(); assertTrue(message.hasFooMessage()); - assertEquals(message.getFooMessage().getQuxInt(), 234); + assertEquals(234, message.getFooMessage().getQuxInt()); // clear assertFalse(builder.clearFooMessage().hasFooString()); message = builder.build(); assertFalse(message.hasFooMessage()); - assertEquals(message.getFooMessage().getQuxInt(), 0); + assertEquals(0, message.getFooMessage().getQuxInt()); // nested builder builder = TestOneof2.newBuilder(); @@ -1432,10 +1426,10 @@ public class GeneratedMessageTest extends TestCase { assertFalse(builder.hasFooMessage()); builder.getFooMessageBuilder().setQuxInt(123); assertTrue(builder.hasFooMessage()); - assertEquals(builder.getFooMessage().getQuxInt(), 123); + assertEquals(123, builder.getFooMessage().getQuxInt()); message = builder.build(); assertTrue(message.hasFooMessage()); - assertEquals(message.getFooMessage().getQuxInt(), 123); + assertEquals(123, message.getFooMessage().getQuxInt()); } // LazyMessage is tested in LazyMessageLiteTest.java @@ -1448,7 +1442,7 @@ public class GeneratedMessageTest extends TestCase { TestOneof2 message = builder.setFooInt(123).build(); TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); assertTrue(message2.hasFooInt()); - assertEquals(message2.getFooInt(), 123); + assertEquals(123, message2.getFooInt()); } // String @@ -1457,7 +1451,7 @@ public class GeneratedMessageTest extends TestCase { TestOneof2 message = builder.setFooString("foo").build(); TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); assertTrue(message2.hasFooString()); - assertEquals(message2.getFooString(), "foo"); + assertEquals("foo", message2.getFooString()); } // Enum @@ -1466,7 +1460,7 @@ public class GeneratedMessageTest extends TestCase { TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build(); TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); assertTrue(message2.hasFooEnum()); - assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.BAR); + assertEquals(TestOneof2.NestedEnum.BAR, message2.getFooEnum()); } // Message @@ -1476,7 +1470,7 @@ public class GeneratedMessageTest extends TestCase { TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).build(); TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build(); assertTrue(message2.hasFooMessage()); - assertEquals(message2.getFooMessage().getQuxInt(), 234); + assertEquals(234, message2.getFooMessage().getQuxInt()); } } @@ -1488,7 +1482,7 @@ public class GeneratedMessageTest extends TestCase { ByteString serialized = message.toByteString(); TestOneof2 message2 = TestOneof2.parseFrom(serialized); assertTrue(message2.hasFooInt()); - assertEquals(message2.getFooInt(), 123); + assertEquals(123, message2.getFooInt()); } // String @@ -1498,7 +1492,7 @@ public class GeneratedMessageTest extends TestCase { ByteString serialized = message.toByteString(); TestOneof2 message2 = TestOneof2.parseFrom(serialized); assertTrue(message2.hasFooString()); - assertEquals(message2.getFooString(), "foo"); + assertEquals("foo", message2.getFooString()); } // Enum @@ -1508,7 +1502,7 @@ public class GeneratedMessageTest extends TestCase { ByteString serialized = message.toByteString(); TestOneof2 message2 = TestOneof2.parseFrom(serialized); assertTrue(message2.hasFooEnum()); - assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.BAR); + assertEquals(TestOneof2.NestedEnum.BAR, message2.getFooEnum()); } // Message @@ -1519,7 +1513,7 @@ public class GeneratedMessageTest extends TestCase { ByteString serialized = message.toByteString(); TestOneof2 message2 = TestOneof2.parseFrom(serialized); assertTrue(message2.hasFooMessage()); - assertEquals(message2.getFooMessage().getQuxInt(), 234); + assertEquals(234, message2.getFooMessage().getQuxInt()); } } 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 98c637a9..ba8bcb1c 100644 --- a/java/core/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/LiteTest.java @@ -33,6 +33,7 @@ package com.google.protobuf; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; +import com.google.protobuf.FieldPresenceTestProto.TestAllTypes; import com.google.protobuf.UnittestImportLite.ImportEnumLite; import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite; import com.google.protobuf.UnittestLite.ForeignEnumLite; @@ -52,7 +53,12 @@ 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.lang.reflect.Field; import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; import junit.framework.TestCase; /** @@ -155,6 +161,31 @@ public class LiteTest extends TestCase { // expected. } } + + public void testMemoization() throws Exception { + TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet(); + + // Test serialized size is memoized + message.memoizedSerializedSize = -1; + int size = message.getSerializedSize(); + assertTrue(size > 0); + assertEquals(size, message.memoizedSerializedSize); + + // Test hashCode is memoized + assertEquals(0, message.memoizedHashCode); + int hashCode = message.hashCode(); + assertTrue(hashCode != 0); + assertEquals(hashCode, message.memoizedHashCode); + + // Test isInitialized is memoized + Field memo = message.getClass().getDeclaredField("memoizedIsInitialized"); + memo.setAccessible(true); + memo.set(message, (byte) -1); + boolean initialized = message.isInitialized(); + assertTrue(initialized); + // We have to cast to Byte first. Casting to byte causes a type error + assertEquals(1, ((Byte) memo.get(message)).intValue()); + } public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { // Since builders are implemented as a thin wrapper around a message @@ -2378,4 +2409,187 @@ public class LiteTest extends TestCase { expected.getUnfinishedMessage()); } } + + // Make sure we haven't screwed up the code generation for packing fields by default. + public void testPackedSerialization() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + builder.addRepeatedInt32(4321); + builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ); + TestAllTypes message = builder.build(); + + CodedInputStream in = CodedInputStream.newInstance(message.toByteArray()); + + while (!in.isAtEnd()) { + int tag = in.readTag(); + assertEquals(WireFormat.WIRETYPE_LENGTH_DELIMITED, WireFormat.getTagWireType(tag)); + in.skipField(tag); + } + } + + public void testAddAllIteratesOnce() { + TestAllTypesLite message = + TestAllTypesLite.newBuilder() + .addAllRepeatedBool(new OneTimeIterableList(false)) + .addAllRepeatedInt32(new OneTimeIterableList(0)) + .addAllRepeatedInt64(new OneTimeIterableList(0L)) + .addAllRepeatedFloat(new OneTimeIterableList(0f)) + .addAllRepeatedDouble(new OneTimeIterableList(0d)) + .addAllRepeatedBytes(new OneTimeIterableList(ByteString.EMPTY)) + .addAllRepeatedString(new OneTimeIterableList("")) + .addAllRepeatedNestedMessage( + new OneTimeIterableList(NestedMessage.getDefaultInstance())) + .addAllRepeatedBool(new OneTimeIterable(false)) + .addAllRepeatedInt32(new OneTimeIterable(0)) + .addAllRepeatedInt64(new OneTimeIterable(0L)) + .addAllRepeatedFloat(new OneTimeIterable(0f)) + .addAllRepeatedDouble(new OneTimeIterable(0d)) + .addAllRepeatedBytes(new OneTimeIterable(ByteString.EMPTY)) + .addAllRepeatedString(new OneTimeIterable("")) + .addAllRepeatedNestedMessage(new OneTimeIterable(NestedMessage.getDefaultInstance())) + .build(); + } + + public void testAddAllIteratesOnce_throwsOnNull() { + TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder(); + try { + builder.addAllRepeatedBool(new OneTimeIterableList(true, false, (Boolean) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 2 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedBoolCount()); + } + + try { + builder.addAllRepeatedBool(new OneTimeIterable(true, false, (Boolean) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 2 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedBoolCount()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedBool(new OneTimeIterableList((Boolean) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 0 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedBoolCount()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedInt32(new OneTimeIterableList((Integer) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 0 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedInt32Count()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedInt64(new OneTimeIterableList((Long) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 0 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedInt64Count()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedFloat(new OneTimeIterableList((Float) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 0 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedFloatCount()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedDouble(new OneTimeIterableList((Double) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 0 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedDoubleCount()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedBytes(new OneTimeIterableList((ByteString) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 0 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedBytesCount()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedString(new OneTimeIterableList("", "", (String) null, "")); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 2 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedStringCount()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedString(new OneTimeIterable("", "", (String) null, "")); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 2 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedStringCount()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedString(new OneTimeIterableList((String) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 0 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedStringCount()); + } + + try { + builder = TestAllTypesLite.newBuilder(); + builder.addAllRepeatedNestedMessage(new OneTimeIterableList((NestedMessage) null)); + fail(); + } catch (NullPointerException expected) { + assertEquals("Element at index 0 is null.", expected.getMessage()); + assertEquals(0, builder.getRepeatedNestedMessageCount()); + } + } + + private static final class OneTimeIterableList<T> extends ArrayList<T> { + private boolean wasIterated = false; + + OneTimeIterableList(T... contents) { + addAll(Arrays.asList(contents)); + } + + @Override + public Iterator<T> iterator() { + if (wasIterated) { + fail(); + } + wasIterated = true; + return super.iterator(); + } + } + + private static final class OneTimeIterable<T> implements Iterable<T> { + private final List<T> list; + private boolean wasIterated = false; + + OneTimeIterable(T... contents) { + list = Arrays.asList(contents); + } + + @Override + public Iterator<T> iterator() { + if (wasIterated) { + fail(); + } + wasIterated = true; + return list.iterator(); + } + } } diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java index 0a14f584..da9195f9 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java @@ -408,12 +408,12 @@ public final class MapForProto2LiteTest extends TestCase { TestMap map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToInt32Field(5, bytes) .build()); - assertEquals(map.getInt32ToInt32FieldOrDefault(5, -1), 0); + assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1)); map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToStringField(stringKey, 5) .build()); - assertEquals(map.getInt32ToStringFieldOrDefault(0, null), ""); + assertEquals("", map.getInt32ToStringFieldOrDefault(0, null)); map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToBytesField(stringKey, 5) @@ -423,7 +423,7 @@ public final class MapForProto2LiteTest extends TestCase { map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToEnumField(stringKey, bytes) .build()); - assertEquals(map.getInt32ToEnumFieldOrDefault(0, null), TestMap.EnumValue.FOO); + assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null)); try { tryParseTestMap(BizarroTestMap.newBuilder() @@ -439,7 +439,7 @@ public final class MapForProto2LiteTest extends TestCase { map = tryParseTestMap(BizarroTestMap.newBuilder() .putStringToInt32Field(stringKey, bytes) .build()); - assertEquals(map.getStringToInt32FieldOrDefault(stringKey, -1), 0); + assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1)); } public void testMergeFrom() throws Exception { 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 453d3928..37827f76 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java @@ -546,12 +546,12 @@ public class MapForProto2Test extends TestCase { TestMap map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToInt32Field(5, bytes) .build()); - assertEquals(map.getInt32ToInt32FieldOrDefault(5, -1), 0); + assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1)); map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToStringField(stringKey, 5) .build()); - assertEquals(map.getInt32ToStringFieldOrDefault(0, null), ""); + assertEquals("", map.getInt32ToStringFieldOrDefault(0, null)); map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToBytesField(stringKey, 5) @@ -561,7 +561,7 @@ public class MapForProto2Test extends TestCase { map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToEnumField(stringKey, bytes) .build()); - assertEquals(map.getInt32ToEnumFieldOrDefault(0, null), TestMap.EnumValue.FOO); + assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null)); try { tryParseTestMap(BizarroTestMap.newBuilder() @@ -577,7 +577,7 @@ public class MapForProto2Test extends TestCase { map = tryParseTestMap(BizarroTestMap.newBuilder() .putStringToInt32Field(stringKey, bytes) .build()); - assertEquals(map.getStringToInt32FieldOrDefault(stringKey, -1), 0); + assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1)); } public void testMergeFrom() throws Exception { 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 45019537..64ae4435 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java @@ -576,12 +576,12 @@ public class MapTest extends TestCase { TestMap map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToInt32Field(5, bytes) .build()); - assertEquals(map.getInt32ToInt32FieldOrDefault(5, -1), 0); + assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1)); map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToStringField(stringKey, 5) .build()); - assertEquals(map.getInt32ToStringFieldOrDefault(0, null), ""); + assertEquals("", map.getInt32ToStringFieldOrDefault(0, null)); map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToBytesField(stringKey, 5) @@ -591,7 +591,7 @@ public class MapTest extends TestCase { map = tryParseTestMap(BizarroTestMap.newBuilder() .putInt32ToEnumField(stringKey, bytes) .build()); - assertEquals(map.getInt32ToEnumFieldOrDefault(0, null), TestMap.EnumValue.FOO); + assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null)); try { tryParseTestMap(BizarroTestMap.newBuilder() @@ -607,7 +607,7 @@ public class MapTest extends TestCase { map = tryParseTestMap(BizarroTestMap.newBuilder() .putStringToInt32Field(stringKey, bytes) .build()); - assertEquals(map.getStringToInt32FieldOrDefault(stringKey, -1), 0); + assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1)); } public void testMergeFrom() throws Exception { diff --git a/java/core/src/test/java/com/google/protobuf/MessageTest.java b/java/core/src/test/java/com/google/protobuf/MessageTest.java index 75b79a34..9d55d0dd 100644 --- a/java/core/src/test/java/com/google/protobuf/MessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/MessageTest.java @@ -321,8 +321,10 @@ public class MessageTest extends TestCase { assertTrue(result.getField(result.getDescriptorForType() .findFieldByName("repeated_foreign_message")) instanceof List<?>); - assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType() - .findFieldByName("repeated_foreign_message")), 0); + assertEquals( + 0, + result.getRepeatedFieldCount( + result.getDescriptorForType().findFieldByName("repeated_foreign_message"))); } /** Test reading repeated message from DynamicMessage. */ @@ -345,7 +347,9 @@ public class MessageTest extends TestCase { assertTrue(result.getField(result.getDescriptorForType() .findFieldByName("repeated_foreign_message")) instanceof List<?>); - assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType() - .findFieldByName("repeated_foreign_message")), 2); + assertEquals( + 2, + result.getRepeatedFieldCount( + result.getDescriptorForType().findFieldByName("repeated_foreign_message"))); } } diff --git a/java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java b/java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java index 2c60fe0e..4af55429 100644 --- a/java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java +++ b/java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java @@ -92,5 +92,31 @@ public class TestBadIdentifiers extends TestCase { assertEquals(0L, message.getExtension( TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldList).longValue()); + assertEquals("", message.getFieldName32()); + assertEquals("", message.getFieldName33()); + assertEquals(0, message.get2Conflict34()); + assertEquals(0, message.get2Conflict35()); + + } + + public void testNumberFields() throws Exception { + TestBadIdentifiersProto.TestLeadingNumberFields message = + TestBadIdentifiersProto.TestLeadingNumberFields.getDefaultInstance(); + // Make sure generated accessors are properly named. + assertFalse(message.has30DayImpressions()); + assertEquals(0, message.get30DayImpressions()); + assertEquals(0, message.get60DayImpressionsCount()); + assertEquals(0, message.get60DayImpressionsList().size()); + + assertFalse(message.has2Underscores()); + assertEquals("", message.get2Underscores()); + assertEquals(0, message.get2RepeatedUnderscoresCount()); + assertEquals(0, message.get2RepeatedUnderscoresList().size()); + + assertFalse(message.has32()); + assertEquals(0, message.get32()); + assertEquals(0, message.get64Count()); + assertEquals(0, message.get64List().size()); + } } diff --git a/java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java b/java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java new file mode 100644 index 00000000..37f94c03 --- /dev/null +++ b/java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java @@ -0,0 +1,83 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.google.protobuf; + +import junit.framework.TestCase; + +/** + * Tests that proto2 api generation doesn't cause compile errors when compiling protocol buffers + * that have names that would otherwise conflict if not fully qualified (like @Deprecated + * and @Override). + * + * <p>Forked from {@link TestBadIdentifiers}. + * + * @author jonp@google.com (Jon Perlow) + */ +public final class TestBadIdentifiersLite extends TestCase { + + public void testCompilation() { + // If this compiles, it means the generation was correct. + TestBadIdentifiersProto.Deprecated.newBuilder(); + TestBadIdentifiersProto.Override.newBuilder(); + } + + public void testConflictingFieldNames() throws Exception { + TestBadIdentifiersProto.TestConflictingFieldNames message = + TestBadIdentifiersProto.TestConflictingFieldNames.getDefaultInstance(); + // Make sure generated accessors are properly named. + assertEquals(0, message.getInt32Field1Count()); + assertEquals(0, message.getEnumField2Count()); + assertEquals(0, message.getStringField3Count()); + assertEquals(0, message.getBytesField4Count()); + assertEquals(0, message.getMessageField5Count()); + + assertEquals(0, message.getInt32FieldCount11()); + assertEquals(0, message.getEnumFieldCount12().getNumber()); + assertEquals("", message.getStringFieldCount13()); + assertEquals(ByteString.EMPTY, message.getBytesFieldCount14()); + assertEquals(0, message.getMessageFieldCount15().getSerializedSize()); + + assertEquals(0, message.getInt32Field21Count()); + assertEquals(0, message.getEnumField22Count()); + assertEquals(0, message.getStringField23Count()); + assertEquals(0, message.getBytesField24Count()); + assertEquals(0, message.getMessageField25Count()); + + assertEquals(0, message.getInt32Field1List().size()); + assertEquals(0, message.getInt32FieldList31()); + + assertEquals(0, message.getInt64FieldCount()); + assertEquals(0L, message.getExtension( + TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldCount).longValue()); + assertEquals(0L, message.getExtension( + TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldList).longValue()); + } +} diff --git a/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java b/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java index 8f45976f..88cbbf86 100644 --- a/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java +++ b/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java @@ -36,7 +36,6 @@ import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.FieldPresenceTestProto.TestAllTypes; import com.google.protobuf.TextFormat.ParseException; - import junit.framework.TestCase; /** @@ -151,18 +150,15 @@ public class UnknownEnumValueTest extends TestCase { assertEquals(4321, unknown4321.getNumber()); assertEquals(5432, unknown5432.getNumber()); assertEquals(6543, unknown6543.getNumber()); - + // Unknown EnumValueDescriptor will map to UNRECOGNIZED. assertEquals( - TestAllTypes.NestedEnum.valueOf(unknown4321), - TestAllTypes.NestedEnum.UNRECOGNIZED); + TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown4321)); assertEquals( - TestAllTypes.NestedEnum.valueOf(unknown5432), - TestAllTypes.NestedEnum.UNRECOGNIZED); + TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown5432)); assertEquals( - TestAllTypes.NestedEnum.valueOf(unknown6543), - TestAllTypes.NestedEnum.UNRECOGNIZED); - + TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown6543)); + // Setters also accept unknown EnumValueDescriptor. builder.setField(optionalNestedEnumField, unknown6543); builder.setRepeatedField(repeatedNestedEnumField, 0, unknown4321); diff --git a/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto b/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto index d2c77936..ff5bf3ae 100644 --- a/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto +++ b/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto @@ -148,6 +148,12 @@ message TestConflictingFieldNames { // the method getInt32FieldList(). required int32 int32_field_list = 31; // NO_PROTO3 + // These field pairs have the same Java converted name + optional string field_name = 32; // NO_PROTO3 + optional string field__name = 33; // NO_PROTO3 + optional int32 _2conflict = 34; // NO_PROTO3 + optional int32 __2conflict = 35; + extensions 1000 to max; // NO_PROTO3 repeated int64 int64_field = 41; @@ -166,3 +172,14 @@ message TestMapField { map<int32, int32> map_field = 1; } + +message TestLeadingNumberFields { + optional int32 _30day_impressions = 1; + repeated string _60day_impressions = 2; + + optional string __2_underscores = 3; + repeated string __2repeated_underscores = 4; + + optional int32 _32 = 32; + repeated int64 _64 = 64; +} diff --git a/java/pom.xml b/java/pom.xml index 39ed31ab..dd3ba3b8 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ <groupId>com.google.protobuf</groupId> <artifactId>protobuf-parent</artifactId> - <version>3.3.2</version> + <version>3.4.0</version> <packaging>pom</packaging> <name>Protocol Buffers [Parent]</name> diff --git a/java/util/pom.xml b/java/util/pom.xml index 62394ed7..61abd146 100644 --- a/java/util/pom.xml +++ b/java/util/pom.xml @@ -6,7 +6,7 @@ <parent> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-parent</artifactId> - <version>3.3.2</version> + <version>3.4.0</version> </parent> <artifactId>protobuf-java-util</artifactId> diff --git a/java/util/src/main/java/com/google/protobuf/util/Durations.java b/java/util/src/main/java/com/google/protobuf/util/Durations.java index 46b21828..fb7f4343 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Durations.java +++ b/java/util/src/main/java/com/google/protobuf/util/Durations.java @@ -30,7 +30,6 @@ package com.google.protobuf.util; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.math.IntMath.checkedAdd; import static com.google.common.math.IntMath.checkedSubtract; import static com.google.common.math.LongMath.checkedAdd; @@ -84,6 +83,17 @@ public final class Durations { } /** + * Compares two durations. The value returned is identical to what would be returned by: + * {@code Durations.comparator().compare(x, y)}. + * + * @return the value {@code 0} if {@code x == y}; a value less than {@code 0} if {@code x < y}; + * and a value greater than {@code 0} if {@code x > y} + */ + public static int compare(Duration x, Duration y) { + return COMPARATOR.compare(x, y); + } + + /** * Returns true if the given {@link Duration} is valid. The {@code seconds} value must be in the * range [-315,576,000,000, +315,576,000,000]. The {@code nanos} value must be in the range * [-999,999,999, +999,999,999]. @@ -124,14 +134,13 @@ public final class Durations { public static Duration checkValid(Duration duration) { long seconds = duration.getSeconds(); int nanos = duration.getNanos(); - checkArgument( - isValid(seconds, nanos), - "Duration is not valid. See proto definition for valid values. " + if (!isValid(seconds, nanos)) { + throw new IllegalArgumentException(String.format( + "Duration is not valid. See proto definition for valid values. " + "Seconds (%s) must be in range [-315,576,000,000, +315,576,000,000]. " + "Nanos (%s) must be in range [-999,999,999, +999,999,999]. " - + "Nanos must have the same sign as seconds", - seconds, - nanos); + + "Nanos must have the same sign as seconds", seconds, nanos)); + } return duration; } diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java index 21d11b2c..b2f849c4 100644 --- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java +++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java @@ -311,16 +311,19 @@ public class FieldMaskUtil { return replacePrimitiveFields; } - public void setReplaceMessageFields(boolean value) { + public MergeOptions setReplaceMessageFields(boolean value) { replaceMessageFields = value; + return this; } - public void setReplaceRepeatedFields(boolean value) { + public MergeOptions setReplaceRepeatedFields(boolean value) { replaceRepeatedFields = value; + return this; } - public void setReplacePrimitiveFields(boolean value) { + public MergeOptions setReplacePrimitiveFields(boolean value) { replacePrimitiveFields = value; + return this; } } 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 e1c2d73d..a603d96a 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 @@ -1686,7 +1686,11 @@ public class JsonFormat { } private ByteString parseBytes(JsonElement json) throws InvalidProtocolBufferException { - return ByteString.copyFrom(BaseEncoding.base64().decode(json.getAsString())); + try { + return ByteString.copyFrom(BaseEncoding.base64().decode(json.getAsString())); + } catch (IllegalArgumentException e) { + return ByteString.copyFrom(BaseEncoding.base64Url().decode(json.getAsString())); + } } private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement json) 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 d0bac417..7a1f2014 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 @@ -30,7 +30,6 @@ package com.google.protobuf.util; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.math.IntMath.checkedAdd; import static com.google.common.math.IntMath.checkedSubtract; import static com.google.common.math.LongMath.checkedAdd; @@ -115,6 +114,17 @@ public final class Timestamps { } /** + * Compares two timestamps. The value returned is identical to what would be returned by: + * {@code Timestamps.comparator().compare(x, y)}. + * + * @return the value {@code 0} if {@code x == y}; a value less than {@code 0} if {@code x < y}; + * and a value greater than {@code 0} if {@code x > y} + */ + public static int compare(Timestamp x, Timestamp y) { + return COMPARATOR.compare(x, y); + } + + /** * Returns true if the given {@link Timestamp} is valid. The {@code seconds} value must be in the * range [-62,135,596,800, +253,402,300,799] (i.e., between 0001-01-01T00:00:00Z and * 9999-12-31T23:59:59Z). The {@code nanos} value must be in the range [0, +999,999,999]. @@ -149,13 +159,12 @@ public final class Timestamps { public static Timestamp checkValid(Timestamp timestamp) { long seconds = timestamp.getSeconds(); int nanos = timestamp.getNanos(); - checkArgument( - isValid(seconds, nanos), - "Timestamp is not valid. See proto definition for valid values. " + if (!isValid(seconds, nanos)) { + throw new IllegalArgumentException(String.format( + "Timestamp is not valid. See proto definition for valid values. " + "Seconds (%s) must be in range [-62,135,596,800, +253,402,300,799]. " - + "Nanos (%s) must be in range [0, +999,999,999].", - seconds, - nanos); + + "Nanos (%s) must be in range [0, +999,999,999].", seconds, nanos)); + } return 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 460b81f6..e4c5387a 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 @@ -73,7 +73,6 @@ 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; @@ -1144,7 +1143,8 @@ public class JsonFormatTest extends TestCase { } public void testParserAcceptBase64Variants() throws Exception { - assertAccepts("optionalBytes", "AQI"); + assertAccepts("optionalBytes", "AQI"); // No padding + assertAccepts("optionalBytes", "-_w"); // base64Url, no padding } public void testParserRejectInvalidEnumValue() throws Exception { diff --git a/js/binary/encoder.js b/js/binary/encoder.js index f25935f1..8e9f5bbc 100644 --- a/js/binary/encoder.js +++ b/js/binary/encoder.js @@ -390,11 +390,13 @@ jspb.BinaryEncoder.prototype.writeDouble = function(value) { /** - * Writes a boolean value to the buffer as a varint. - * @param {boolean} value The value to write. + * Writes a boolean value to the buffer as a varint. We allow numbers as input + * because the JSPB code generator uses 0/1 instead of true/false to save space + * in the string representation of the proto. + * @param {boolean|number} value The value to write. */ jspb.BinaryEncoder.prototype.writeBool = function(value) { - goog.asserts.assert(goog.isBoolean(value)); + goog.asserts.assert(goog.isBoolean(value) || goog.isNumber(value)); this.buffer_.push(value ? 1 : 0); }; diff --git a/js/binary/writer.js b/js/binary/writer.js index 672e94bd..037e92b2 100644 --- a/js/binary/writer.js +++ b/js/binary/writer.js @@ -235,7 +235,7 @@ jspb.BinaryWriter.prototype.getResultBuffer = function() { /** - * Converts the encoded data into a bas64-encoded string. + * Converts the encoded data into a base64-encoded string. * @return {string} */ jspb.BinaryWriter.prototype.getResultBase64String = function() { @@ -716,13 +716,15 @@ jspb.BinaryWriter.prototype.writeDouble = function(field, value) { /** - * Writes a boolean field to the buffer. + * Writes a boolean field to the buffer. We allow numbers as input + * because the JSPB code generator uses 0/1 instead of true/false to save space + * in the string representation of the proto. * @param {number} field The field number. - * @param {boolean?} value The value to write. + * @param {boolean?|number?} value The value to write. */ jspb.BinaryWriter.prototype.writeBool = function(field, value) { if (value == null) return; - goog.asserts.assert(goog.isBoolean(value)); + goog.asserts.assert(goog.isBoolean(value) || goog.isNumber(value)); this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); this.encoder_.writeBool(value); }; diff --git a/js/compatibility_tests/v3.1.0/binary/arith_test.js b/js/compatibility_tests/v3.1.0/binary/arith_test.js new file mode 100644 index 00000000..89796bf7 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/binary/arith_test.js @@ -0,0 +1,355 @@ +// 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. + +/** + * @fileoverview Test cases for Int64-manipulation functions. + * + * Test suite is written using Jasmine -- see http://jasmine.github.io/ + * + * @author cfallin@google.com (Chris Fallin) + */ + +goog.require('goog.testing.asserts'); +goog.require('jspb.arith.Int64'); +goog.require('jspb.arith.UInt64'); + + +describe('binaryArithTest', function() { + /** + * Tests comparison operations. + */ + it('testCompare', function() { + var a = new jspb.arith.UInt64(1234, 5678); + var b = new jspb.arith.UInt64(1234, 5678); + assertEquals(a.cmp(b), 0); + assertEquals(b.cmp(a), 0); + b.lo -= 1; + assertEquals(a.cmp(b), 1); + assertEquals(b.cmp(a), -1); + b.lo += 2; + assertEquals(a.cmp(b), -1); + assertEquals(b.cmp(a), 1); + b.lo = a.lo; + b.hi = a.hi - 1; + assertEquals(a.cmp(b), 1); + assertEquals(b.cmp(a), -1); + + assertEquals(a.zero(), false); + assertEquals(a.msb(), false); + assertEquals(a.lsb(), false); + a.hi = 0; + a.lo = 0; + assertEquals(a.zero(), true); + a.hi = 0x80000000; + assertEquals(a.zero(), false); + assertEquals(a.msb(), true); + a.lo = 0x00000001; + assertEquals(a.lsb(), true); + }); + + + /** + * Tests shifts. + */ + it('testShifts', function() { + var a = new jspb.arith.UInt64(1, 0); + assertEquals(a.lo, 1); + assertEquals(a.hi, 0); + var orig = a; + a = a.leftShift(); + assertEquals(orig.lo, 1); // original unmodified. + assertEquals(orig.hi, 0); + assertEquals(a.lo, 2); + assertEquals(a.hi, 0); + a = a.leftShift(); + assertEquals(a.lo, 4); + assertEquals(a.hi, 0); + for (var i = 0; i < 29; i++) { + a = a.leftShift(); + } + assertEquals(a.lo, 0x80000000); + assertEquals(a.hi, 0); + a = a.leftShift(); + assertEquals(a.lo, 0); + assertEquals(a.hi, 1); + a = a.leftShift(); + assertEquals(a.lo, 0); + assertEquals(a.hi, 2); + a = a.rightShift(); + a = a.rightShift(); + assertEquals(a.lo, 0x80000000); + assertEquals(a.hi, 0); + a = a.rightShift(); + assertEquals(a.lo, 0x40000000); + assertEquals(a.hi, 0); + }); + + + /** + * Tests additions. + */ + it('testAdd', function() { + var a = new jspb.arith.UInt64(/* lo = */ 0x89abcdef, + /* hi = */ 0x01234567); + var b = new jspb.arith.UInt64(/* lo = */ 0xff52ab91, + /* hi = */ 0x92fa2123); + // Addition with carry. + var c = a.add(b); + assertEquals(a.lo, 0x89abcdef); // originals unmodified. + assertEquals(a.hi, 0x01234567); + assertEquals(b.lo, 0xff52ab91); + assertEquals(b.hi, 0x92fa2123); + assertEquals(c.lo, 0x88fe7980); + assertEquals(c.hi, 0x941d668b); + + // Simple addition without carry. + a.lo = 2; + a.hi = 0; + b.lo = 3; + b.hi = 0; + c = a.add(b); + assertEquals(c.lo, 5); + assertEquals(c.hi, 0); + }); + + + /** + * Test subtractions. + */ + it('testSub', function() { + var kLength = 10; + var hiValues = [0x1682ef32, + 0x583902f7, + 0xb62f5955, + 0x6ea99bbf, + 0x25a39c20, + 0x0700a08b, + 0x00f7304d, + 0x91a5b5af, + 0x89077fd2, + 0xe09e347c]; + var loValues = [0xe1538b18, + 0xbeacd556, + 0x74100758, + 0x96e3cb26, + 0x56c37c3f, + 0xe00b3f7d, + 0x859f25d7, + 0xc2ee614a, + 0xe1d21cd7, + 0x30aae6a4]; + for (var i = 0; i < kLength; i++) { + for (var j = 0; j < kLength; j++) { + var a = new jspb.arith.UInt64(loValues[i], hiValues[j]); + var b = new jspb.arith.UInt64(loValues[j], hiValues[i]); + var c = a.add(b).sub(b); + assertEquals(c.hi, a.hi); + assertEquals(c.lo, a.lo); + } + } + }); + + + /** + * Tests 32-by-32 multiplication. + */ + it('testMul32x32', function() { + var testData = [ + // a b low(a*b) high(a*b) + [0xc0abe2f8, 0x1607898a, 0x5de711b0, 0x109471b8], + [0x915eb3cb, 0x4fb66d0e, 0xbd0d441a, 0x2d43d0bc], + [0xfe4efe70, 0x80b48c37, 0xbcddea10, 0x7fdada0c], + [0xe222fd4a, 0xe43d524a, 0xd5e0eb64, 0xc99d549c], + [0xd171f469, 0xb94ebd01, 0x4be17969, 0x979bc4fa], + [0x829cc1df, 0xe2598b38, 0xf4157dc8, 0x737c12ad], + [0xf10c3767, 0x8382881e, 0x942b3612, 0x7bd428b8], + [0xb0f6dd24, 0x232597e1, 0x079c98a4, 0x184bbce7], + [0xfcdb05a7, 0x902f55bc, 0x636199a4, 0x8e69f412], + [0x0dd0bfa9, 0x916e27b1, 0x6e2542d9, 0x07d92e65] + ]; + + for (var i = 0; i < testData.length; i++) { + var a = testData[i][0] >>> 0; + var b = testData[i][1] >>> 0; + var cLow = testData[i][2] >>> 0; + var cHigh = testData[i][3] >>> 0; + var c = jspb.arith.UInt64.mul32x32(a, b); + assertEquals(c.lo, cLow); + assertEquals(c.hi, cHigh); + } + }); + + + /** + * Tests 64-by-32 multiplication. + */ + it('testMul', function() { + // 64x32 bits produces 96 bits of product. The multiplication function under + // test truncates the top 32 bits, so we compare against a 64-bit expected + // product. + var testData = [ + // low(a) high(a) low(a*b) high(a*b) + [0xec10955b, 0x360eb168, 0x4b7f3f5b, 0xbfcb7c59, 0x9517da5f], + [0x42b000fc, 0x9d101642, 0x6fa1ab72, 0x2584c438, 0x6a9e6d2b], + [0xf42d4fb4, 0xae366403, 0xa65a1000, 0x92434000, 0x1ff978df], + [0x17e2f56b, 0x25487693, 0xf13f98c7, 0x73794e2d, 0xa96b0c6a], + [0x492f241f, 0x76c0eb67, 0x7377ac44, 0xd4336c3c, 0xfc4b1ebe], + [0xd6b92321, 0xe184fa48, 0xd6e76904, 0x93141584, 0xcbf44da1], + [0x4bf007ea, 0x968c0a9e, 0xf5e4026a, 0x4fdb1ae4, 0x61b9fb7d], + [0x10a83be7, 0x2d685ba6, 0xc9e5fb7f, 0x2ad43499, 0x3742473d], + [0x2f261829, 0x1aca681a, 0x3d3494e3, 0x8213205b, 0x283719f8], + [0xe4f2ce21, 0x2e74b7bd, 0xd801b38b, 0xbc17feeb, 0xc6c44e0f] + ]; + + for (var i = 0; i < testData.length; i++) { + var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); + var prod = a.mul(testData[i][2]); + assertEquals(prod.lo, testData[i][3]); + assertEquals(prod.hi, testData[i][4]); + } + }); + + + /** + * Tests 64-div-by-32 division. + */ + it('testDiv', function() { + // Compute a/b, yielding quot = a/b and rem = a%b. + var testData = [ + // --- divisors in (0, 2^32-1) to test full divisor range + // low(a) high(a) b low(quot) high(quot) rem + [0x712443f1, 0xe85cefcc, 0xc1a7050b, 0x332c79ad, 0x00000001, 0x92ffa882], + [0x11912915, 0xb2699eb5, 0x30467cbe, 0xb21b4be4, 0x00000003, 0x283465dd], + [0x0d917982, 0x201f2a6e, 0x3f35bf03, 0x8217c8e4, 0x00000000, 0x153402d6], + [0xa072c108, 0x74020c96, 0xc60568fd, 0x95f9613e, 0x00000000, 0x3f4676c2], + [0xd845d5d8, 0xcdd235c4, 0x20426475, 0x6154e78b, 0x00000006, 0x202fb751], + [0xa4dbf71f, 0x9e90465e, 0xf08e022f, 0xa8be947f, 0x00000000, 0xbe43b5ce], + [0x3dbe627f, 0xa791f4b9, 0x28a5bd89, 0x1f5dfe93, 0x00000004, 0x02bf9ed4], + [0x5c1c53ee, 0xccf5102e, 0x198576e7, 0x07e3ae31, 0x00000008, 0x02ea8fb7], + [0xfef1e581, 0x04714067, 0xca6540c1, 0x059e73ec, 0x00000000, 0x31658095], + [0x1e2dd90c, 0x13dd6667, 0x8b2184c3, 0x248d1a42, 0x00000000, 0x4ca6d0c6], + // --- divisors in (0, 2^16-1) to test larger quotient high-words + // low(a) high(a) b low(quot) high(quot) rem + [0x86722b47, 0x2cd57c9a, 0x00003123, 0x2ae41b7a, 0x0000e995, 0x00000f99], + [0x1dd7884c, 0xf5e839bc, 0x00009eeb, 0x5c886242, 0x00018c21, 0x000099b6], + [0x5c53d625, 0x899fc7e5, 0x000087d7, 0xd625007a, 0x0001035c, 0x000019af], + [0x6932d932, 0x9d0a5488, 0x000051fb, 0x9d976143, 0x0001ea63, 0x00004981], + [0x4d18bb85, 0x0c92fb31, 0x00001d9f, 0x03265ab4, 0x00006cac, 0x000001b9], + [0xbe756768, 0xdea67ccb, 0x00008a03, 0x58add442, 0x00019cff, 0x000056a2], + [0xe2466f9a, 0x2521f114, 0x0000c350, 0xa0c0860d, 0x000030ab, 0x0000a48a], + [0xf00ddad1, 0xe2f5446a, 0x00002cfc, 0x762697a6, 0x00050b96, 0x00000b69], + [0xa879152a, 0x0a70e0a5, 0x00007cdf, 0xb44151b3, 0x00001567, 0x0000363d], + [0x7179a74c, 0x46083fff, 0x0000253c, 0x4d39ba6e, 0x0001e17f, 0x00000f84] + ]; + + for (var i = 0; i < testData.length; i++) { + var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); + var result = a.div(testData[i][2]); + var quotient = result[0]; + var remainder = result[1]; + assertEquals(quotient.lo, testData[i][3]); + assertEquals(quotient.hi, testData[i][4]); + assertEquals(remainder.lo, testData[i][5]); + } + }); + + + /** + * Tests .toString() and .fromString(). + */ + it('testStrings', function() { + var testData = [ + [0x5e84c935, 0xcae33d0e, '14619595947299359029'], + [0x62b3b8b8, 0x93480544, '10612738313170434232'], + [0x319bfb13, 0xc01c4172, '13843011313344445203'], + [0x5b8a65fb, 0xa5885b31, '11927883880638080507'], + [0x6bdb80f1, 0xb0d1b16b, '12741159895737008369'], + [0x4b82b442, 0x2e0d8c97, '3318463081876730946'], + [0x780d5208, 0x7d76752c, '9040542135845999112'], + [0x2e46800f, 0x0993778d, '690026616168284175'], + [0xf00a7e32, 0xcd8e3931, '14811839111111540274'], + [0x1baeccd6, 0x923048c4, '10533999535534820566'], + [0x03669d29, 0xbff3ab72, '13831587386756603177'], + [0x2526073e, 0x01affc81, '121593346566522686'], + [0xc24244e0, 0xd7f40d0e, '15561076969511732448'], + [0xc56a341e, 0xa68b66a7, '12000798502816461854'], + [0x8738d64d, 0xbfe78604, '13828168534871037517'], + [0x5baff03b, 0xd7572aea, '15516918227177304123'], + [0x4a843d8a, 0x864e132b, '9677693725920476554'], + [0x25b4e94d, 0x22b54dc6, '2500990681505655117'], + [0x6bbe664b, 0x55a5cc0e, '6171563226690381387'], + [0xee916c81, 0xb00aabb3, '12685140089732426881'] + ]; + + for (var i = 0; i < testData.length; i++) { + var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); + var roundtrip = jspb.arith.UInt64.fromString(a.toString()); + assertEquals(roundtrip.lo, a.lo); + assertEquals(roundtrip.hi, a.hi); + assertEquals(a.toString(), testData[i][2]); + } + }); + + + /** + * Tests signed Int64s. These are built on UInt64s, so we only need to test + * the explicit overrides: .toString() and .fromString(). + */ + it('testSignedInt64', function() { + var testStrings = [ + '-7847499644178593666', + '3771946501229139523', + '2872856549054995060', + '-5780049594274350904', + '3383785956695105201', + '2973055184857072610', + '-3879428459215627206', + '4589812431064156631', + '8484075557333689940', + '1075325817098092407', + '-4346697501012292314', + '2488620459718316637', + '6112655187423520672', + '-3655278273928612104', + '3439154019435803196', + '1004112478843763757', + '-6587790776614368413', + '664320065099714586', + '4760412909973292912', + '-7911903989602274672' + ]; + + for (var i = 0; i < testStrings.length; i++) { + var roundtrip = + jspb.arith.Int64.fromString(testStrings[i]).toString(); + assertEquals(roundtrip, testStrings[i]); + } + }); +}); diff --git a/js/compatibility_tests/v3.1.0/binary/decoder_test.js b/js/compatibility_tests/v3.1.0/binary/decoder_test.js new file mode 100644 index 00000000..ac312648 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/binary/decoder_test.js @@ -0,0 +1,334 @@ +// 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. + +/** + * @fileoverview Test cases for jspb's binary protocol buffer decoder. + * + * There are two particular magic numbers that need to be pointed out - + * 2^64-1025 is the largest number representable as both a double and an + * unsigned 64-bit integer, and 2^63-513 is the largest number representable as + * both a double and a signed 64-bit integer. + * + * Test suite is written using Jasmine -- see http://jasmine.github.io/ + * + * @author aappleby@google.com (Austin Appleby) + */ + +goog.require('goog.testing.asserts'); +goog.require('jspb.BinaryConstants'); +goog.require('jspb.BinaryDecoder'); +goog.require('jspb.BinaryEncoder'); + + +/** + * Tests encoding and decoding of unsigned types. + * @param {Function} readValue + * @param {Function} writeValue + * @param {number} epsilon + * @param {number} upperLimit + * @param {Function} filter + * @suppress {missingProperties|visibility} + */ +function doTestUnsignedValue(readValue, + writeValue, epsilon, upperLimit, filter) { + var encoder = new jspb.BinaryEncoder(); + + // Encode zero and limits. + writeValue.call(encoder, filter(0)); + writeValue.call(encoder, filter(epsilon)); + writeValue.call(encoder, filter(upperLimit)); + + // Encode positive values. + for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { + writeValue.call(encoder, filter(cursor)); + } + + var decoder = jspb.BinaryDecoder.alloc(encoder.end()); + + // Check zero and limits. + assertEquals(filter(0), readValue.call(decoder)); + assertEquals(filter(epsilon), readValue.call(decoder)); + assertEquals(filter(upperLimit), readValue.call(decoder)); + + // Check positive values. + for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { + if (filter(cursor) != readValue.call(decoder)) throw 'fail!'; + } + + // Encoding values outside the valid range should assert. + assertThrows(function() {writeValue.call(encoder, -1);}); + assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);}); +} + + +/** + * Tests encoding and decoding of signed types. + * @param {Function} readValue + * @param {Function} writeValue + * @param {number} epsilon + * @param {number} lowerLimit + * @param {number} upperLimit + * @param {Function} filter + * @suppress {missingProperties} + */ +function doTestSignedValue(readValue, + writeValue, epsilon, lowerLimit, upperLimit, filter) { + var encoder = new jspb.BinaryEncoder(); + + // Encode zero and limits. + writeValue.call(encoder, filter(lowerLimit)); + writeValue.call(encoder, filter(-epsilon)); + writeValue.call(encoder, filter(0)); + writeValue.call(encoder, filter(epsilon)); + writeValue.call(encoder, filter(upperLimit)); + + var inputValues = []; + + // Encode negative values. + for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) { + var val = filter(cursor); + writeValue.call(encoder, val); + inputValues.push(val); + } + + // Encode positive values. + for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { + var val = filter(cursor); + writeValue.call(encoder, val); + inputValues.push(val); + } + + var decoder = jspb.BinaryDecoder.alloc(encoder.end()); + + // Check zero and limits. + assertEquals(filter(lowerLimit), readValue.call(decoder)); + assertEquals(filter(-epsilon), readValue.call(decoder)); + assertEquals(filter(0), readValue.call(decoder)); + assertEquals(filter(epsilon), readValue.call(decoder)); + assertEquals(filter(upperLimit), readValue.call(decoder)); + + // Verify decoded values. + for (var i = 0; i < inputValues.length; i++) { + assertEquals(inputValues[i], readValue.call(decoder)); + } + + // Encoding values outside the valid range should assert. + assertThrows(function() {writeValue.call(encoder, lowerLimit * 1.1);}); + assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);}); +} + +describe('binaryDecoderTest', function() { + /** + * Tests the decoder instance cache. + */ + it('testInstanceCache', /** @suppress {visibility} */ function() { + // Empty the instance caches. + jspb.BinaryDecoder.instanceCache_ = []; + + // Allocating and then freeing a decoder should put it in the instance + // cache. + jspb.BinaryDecoder.alloc().free(); + + assertEquals(1, jspb.BinaryDecoder.instanceCache_.length); + + // Allocating and then freeing three decoders should leave us with three in + // the cache. + + var decoder1 = jspb.BinaryDecoder.alloc(); + var decoder2 = jspb.BinaryDecoder.alloc(); + var decoder3 = jspb.BinaryDecoder.alloc(); + decoder1.free(); + decoder2.free(); + decoder3.free(); + + assertEquals(3, jspb.BinaryDecoder.instanceCache_.length); + }); + + + /** + * Tests reading 64-bit integers as hash strings. + */ + it('testHashStrings', function() { + var encoder = new jspb.BinaryEncoder(); + + var hashA = String.fromCharCode(0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00); + var hashB = String.fromCharCode(0x12, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00); + var hashC = String.fromCharCode(0x12, 0x34, 0x56, 0x78, + 0x87, 0x65, 0x43, 0x21); + var hashD = String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF); + + encoder.writeVarintHash64(hashA); + encoder.writeVarintHash64(hashB); + encoder.writeVarintHash64(hashC); + encoder.writeVarintHash64(hashD); + + encoder.writeFixedHash64(hashA); + encoder.writeFixedHash64(hashB); + encoder.writeFixedHash64(hashC); + encoder.writeFixedHash64(hashD); + + var decoder = jspb.BinaryDecoder.alloc(encoder.end()); + + assertEquals(hashA, decoder.readVarintHash64()); + assertEquals(hashB, decoder.readVarintHash64()); + assertEquals(hashC, decoder.readVarintHash64()); + assertEquals(hashD, decoder.readVarintHash64()); + + assertEquals(hashA, decoder.readFixedHash64()); + assertEquals(hashB, decoder.readFixedHash64()); + assertEquals(hashC, decoder.readFixedHash64()); + assertEquals(hashD, decoder.readFixedHash64()); + }); + + + /** + * Verifies that misuse of the decoder class triggers assertions. + * @suppress {checkTypes|visibility} + */ + it('testDecodeErrors', function() { + // Reading a value past the end of the stream should trigger an assertion. + var decoder = jspb.BinaryDecoder.alloc([0, 1, 2]); + assertThrows(function() {decoder.readUint64()}); + + // Overlong varints should trigger assertions. + decoder.setBlock([255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 0]); + assertThrows(function() {decoder.readUnsignedVarint64()}); + decoder.reset(); + assertThrows(function() {decoder.readSignedVarint64()}); + decoder.reset(); + assertThrows(function() {decoder.readZigzagVarint64()}); + + // Positive 32-bit varints encoded with 1 bits in positions 33 through 35 + // should trigger assertions. + decoder.setBlock([255, 255, 255, 255, 0x1F]); + assertThrows(function() {decoder.readUnsignedVarint32()}); + + decoder.setBlock([255, 255, 255, 255, 0x2F]); + assertThrows(function() {decoder.readUnsignedVarint32()}); + + decoder.setBlock([255, 255, 255, 255, 0x4F]); + assertThrows(function() {decoder.readUnsignedVarint32()}); + + // Negative 32-bit varints encoded with non-1 bits in the high dword should + // trigger assertions. + decoder.setBlock([255, 255, 255, 255, 255, 255, 0, 255, 255, 1]); + assertThrows(function() {decoder.readUnsignedVarint32()}); + + decoder.setBlock([255, 255, 255, 255, 255, 255, 255, 255, 255, 0]); + assertThrows(function() {decoder.readUnsignedVarint32()}); + }); + + + /** + * Tests encoding and decoding of unsigned integers. + */ + it('testUnsignedIntegers', function() { + doTestUnsignedValue( + jspb.BinaryDecoder.prototype.readUint8, + jspb.BinaryEncoder.prototype.writeUint8, + 1, 0xFF, Math.round); + + doTestUnsignedValue( + jspb.BinaryDecoder.prototype.readUint16, + jspb.BinaryEncoder.prototype.writeUint16, + 1, 0xFFFF, Math.round); + + doTestUnsignedValue( + jspb.BinaryDecoder.prototype.readUint32, + jspb.BinaryEncoder.prototype.writeUint32, + 1, 0xFFFFFFFF, Math.round); + + doTestUnsignedValue( + jspb.BinaryDecoder.prototype.readUint64, + jspb.BinaryEncoder.prototype.writeUint64, + 1, Math.pow(2, 64) - 1025, Math.round); + }); + + + /** + * Tests encoding and decoding of signed integers. + */ + it('testSignedIntegers', function() { + doTestSignedValue( + jspb.BinaryDecoder.prototype.readInt8, + jspb.BinaryEncoder.prototype.writeInt8, + 1, -0x80, 0x7F, Math.round); + + doTestSignedValue( + jspb.BinaryDecoder.prototype.readInt16, + jspb.BinaryEncoder.prototype.writeInt16, + 1, -0x8000, 0x7FFF, Math.round); + + doTestSignedValue( + jspb.BinaryDecoder.prototype.readInt32, + jspb.BinaryEncoder.prototype.writeInt32, + 1, -0x80000000, 0x7FFFFFFF, Math.round); + + doTestSignedValue( + jspb.BinaryDecoder.prototype.readInt64, + jspb.BinaryEncoder.prototype.writeInt64, + 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); + }); + + + /** + * Tests encoding and decoding of floats. + */ + it('testFloats', function() { + /** + * @param {number} x + * @return {number} + */ + function truncate(x) { + var temp = new Float32Array(1); + temp[0] = x; + return temp[0]; + } + doTestSignedValue( + jspb.BinaryDecoder.prototype.readFloat, + jspb.BinaryEncoder.prototype.writeFloat, + jspb.BinaryConstants.FLOAT32_EPS, + -jspb.BinaryConstants.FLOAT32_MAX, + jspb.BinaryConstants.FLOAT32_MAX, + truncate); + + doTestSignedValue( + jspb.BinaryDecoder.prototype.readDouble, + jspb.BinaryEncoder.prototype.writeDouble, + jspb.BinaryConstants.FLOAT64_EPS * 10, + -jspb.BinaryConstants.FLOAT64_MAX, + jspb.BinaryConstants.FLOAT64_MAX, + function(x) { return x; }); + }); +}); diff --git a/js/compatibility_tests/v3.1.0/binary/proto_test.js b/js/compatibility_tests/v3.1.0/binary/proto_test.js new file mode 100644 index 00000000..26e1d30f --- /dev/null +++ b/js/compatibility_tests/v3.1.0/binary/proto_test.js @@ -0,0 +1,628 @@ +// 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. + +// Test suite is written using Jasmine -- see http://jasmine.github.io/ + +goog.require('goog.crypt.base64'); +goog.require('goog.testing.asserts'); +goog.require('jspb.Message'); + +// CommonJS-LoadFromFile: ../testbinary_pb proto.jspb.test +goog.require('proto.jspb.test.ExtendsWithMessage'); +goog.require('proto.jspb.test.ForeignEnum'); +goog.require('proto.jspb.test.ForeignMessage'); +goog.require('proto.jspb.test.TestAllTypes'); +goog.require('proto.jspb.test.TestExtendable'); +goog.require('proto.jspb.test.extendOptionalBool'); +goog.require('proto.jspb.test.extendOptionalBytes'); +goog.require('proto.jspb.test.extendOptionalDouble'); +goog.require('proto.jspb.test.extendOptionalFixed32'); +goog.require('proto.jspb.test.extendOptionalFixed64'); +goog.require('proto.jspb.test.extendOptionalFloat'); +goog.require('proto.jspb.test.extendOptionalForeignEnum'); +goog.require('proto.jspb.test.extendOptionalInt32'); +goog.require('proto.jspb.test.extendOptionalInt64'); +goog.require('proto.jspb.test.extendOptionalSfixed32'); +goog.require('proto.jspb.test.extendOptionalSfixed64'); +goog.require('proto.jspb.test.extendOptionalSint32'); +goog.require('proto.jspb.test.extendOptionalSint64'); +goog.require('proto.jspb.test.extendOptionalString'); +goog.require('proto.jspb.test.extendOptionalUint32'); +goog.require('proto.jspb.test.extendOptionalUint64'); +goog.require('proto.jspb.test.extendPackedRepeatedBoolList'); +goog.require('proto.jspb.test.extendPackedRepeatedDoubleList'); +goog.require('proto.jspb.test.extendPackedRepeatedFixed32List'); +goog.require('proto.jspb.test.extendPackedRepeatedFixed64List'); +goog.require('proto.jspb.test.extendPackedRepeatedFloatList'); +goog.require('proto.jspb.test.extendPackedRepeatedForeignEnumList'); +goog.require('proto.jspb.test.extendPackedRepeatedInt32List'); +goog.require('proto.jspb.test.extendPackedRepeatedInt64List'); +goog.require('proto.jspb.test.extendPackedRepeatedSfixed32List'); +goog.require('proto.jspb.test.extendPackedRepeatedSfixed64List'); +goog.require('proto.jspb.test.extendPackedRepeatedSint32List'); +goog.require('proto.jspb.test.extendPackedRepeatedSint64List'); +goog.require('proto.jspb.test.extendPackedRepeatedUint32List'); +goog.require('proto.jspb.test.extendPackedRepeatedUint64List'); +goog.require('proto.jspb.test.extendRepeatedBoolList'); +goog.require('proto.jspb.test.extendRepeatedBytesList'); +goog.require('proto.jspb.test.extendRepeatedDoubleList'); +goog.require('proto.jspb.test.extendRepeatedFixed32List'); +goog.require('proto.jspb.test.extendRepeatedFixed64List'); +goog.require('proto.jspb.test.extendRepeatedFloatList'); +goog.require('proto.jspb.test.extendRepeatedForeignEnumList'); +goog.require('proto.jspb.test.extendRepeatedInt32List'); +goog.require('proto.jspb.test.extendRepeatedInt64List'); +goog.require('proto.jspb.test.extendRepeatedSfixed32List'); +goog.require('proto.jspb.test.extendRepeatedSfixed64List'); +goog.require('proto.jspb.test.extendRepeatedSint32List'); +goog.require('proto.jspb.test.extendRepeatedSint64List'); +goog.require('proto.jspb.test.extendRepeatedStringList'); +goog.require('proto.jspb.test.extendRepeatedUint32List'); +goog.require('proto.jspb.test.extendRepeatedUint64List'); + + +var suite = {}; + +var BYTES = new Uint8Array([1, 2, 8, 9]); + +var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES); + + +/** + * Helper: fill all fields on a TestAllTypes message. + * @param {proto.jspb.test.TestAllTypes} msg + */ +function fillAllFields(msg) { + msg.setOptionalInt32(-42); + // can be exactly represented by JS number (64-bit double, i.e., 52-bit + // mantissa). + msg.setOptionalInt64(-0x7fffffff00000000); + msg.setOptionalUint32(0x80000000); + msg.setOptionalUint64(0xf000000000000000); + msg.setOptionalSint32(-100); + msg.setOptionalSint64(-0x8000000000000000); + msg.setOptionalFixed32(1234); + msg.setOptionalFixed64(0x1234567800000000); + msg.setOptionalSfixed32(-1234); + msg.setOptionalSfixed64(-0x1234567800000000); + msg.setOptionalFloat(1.5); + msg.setOptionalDouble(-1.5); + msg.setOptionalBool(true); + msg.setOptionalString('hello world'); + msg.setOptionalBytes(BYTES); + msg.setOptionalGroup(new proto.jspb.test.TestAllTypes.OptionalGroup()); + msg.getOptionalGroup().setA(100); + var submsg = new proto.jspb.test.ForeignMessage(); + submsg.setC(16); + msg.setOptionalForeignMessage(submsg); + msg.setOptionalForeignEnum(proto.jspb.test.ForeignEnum.FOREIGN_FOO); + msg.setOneofString('oneof'); + + + msg.setRepeatedInt32List([-42]); + msg.setRepeatedInt64List([-0x7fffffff00000000]); + msg.setRepeatedUint32List([0x80000000]); + msg.setRepeatedUint64List([0xf000000000000000]); + msg.setRepeatedSint32List([-100]); + msg.setRepeatedSint64List([-0x8000000000000000]); + msg.setRepeatedFixed32List([1234]); + msg.setRepeatedFixed64List([0x1234567800000000]); + msg.setRepeatedSfixed32List([-1234]); + msg.setRepeatedSfixed64List([-0x1234567800000000]); + msg.setRepeatedFloatList([1.5]); + msg.setRepeatedDoubleList([-1.5]); + msg.setRepeatedBoolList([true]); + msg.setRepeatedStringList(['hello world']); + msg.setRepeatedBytesList([BYTES, BYTES]); + msg.setRepeatedGroupList([new proto.jspb.test.TestAllTypes.RepeatedGroup()]); + msg.getRepeatedGroupList()[0].setA(100); + submsg = new proto.jspb.test.ForeignMessage(); + submsg.setC(1000); + msg.setRepeatedForeignMessageList([submsg]); + msg.setRepeatedForeignEnumList([proto.jspb.test.ForeignEnum.FOREIGN_FOO]); + + msg.setPackedRepeatedInt32List([-42]); + msg.setPackedRepeatedInt64List([-0x7fffffff00000000]); + msg.setPackedRepeatedUint32List([0x80000000]); + msg.setPackedRepeatedUint64List([0xf000000000000000]); + msg.setPackedRepeatedSint32List([-100]); + msg.setPackedRepeatedSint64List([-0x8000000000000000]); + msg.setPackedRepeatedFixed32List([1234]); + msg.setPackedRepeatedFixed64List([0x1234567800000000]); + msg.setPackedRepeatedSfixed32List([-1234]); + msg.setPackedRepeatedSfixed64List([-0x1234567800000000]); + msg.setPackedRepeatedFloatList([1.5]); + msg.setPackedRepeatedDoubleList([-1.5]); + msg.setPackedRepeatedBoolList([true]); + +} + + +/** + * Helper: compare a bytes field to an expected value + * @param {Uint8Array|string} arr + * @param {Uint8Array} expected + * @return {boolean} + */ +function bytesCompare(arr, expected) { + if (goog.isString(arr)) { + arr = goog.crypt.base64.decodeStringToUint8Array(arr); + } + if (arr.length != expected.length) { + return false; + } + for (var i = 0; i < arr.length; i++) { + if (arr[i] != expected[i]) { + return false; + } + } + return true; +} + + +/** + * Helper: verify contents of given TestAllTypes message as set by + * fillAllFields(). + * @param {proto.jspb.test.TestAllTypes} original + * @param {proto.jspb.test.TestAllTypes} copy + */ +function checkAllFields(original, copy) { + assertTrue(jspb.Message.equals(original, copy)); + + assertEquals(copy.getOptionalInt32(), -42); + assertEquals(copy.getOptionalInt64(), -0x7fffffff00000000); + assertEquals(copy.getOptionalUint32(), 0x80000000); + assertEquals(copy.getOptionalUint64(), 0xf000000000000000); + assertEquals(copy.getOptionalSint32(), -100); + assertEquals(copy.getOptionalSint64(), -0x8000000000000000); + assertEquals(copy.getOptionalFixed32(), 1234); + assertEquals(copy.getOptionalFixed64(), 0x1234567800000000); + assertEquals(copy.getOptionalSfixed32(), -1234); + assertEquals(copy.getOptionalSfixed64(), -0x1234567800000000); + assertEquals(copy.getOptionalFloat(), 1.5); + assertEquals(copy.getOptionalDouble(), -1.5); + assertEquals(copy.getOptionalBool(), true); + assertEquals(copy.getOptionalString(), 'hello world'); + assertEquals(true, bytesCompare(copy.getOptionalBytes(), BYTES)); + assertEquals(true, bytesCompare(copy.getOptionalBytes_asU8(), BYTES)); + assertEquals( + copy.getOptionalBytes_asB64(), goog.crypt.base64.encodeByteArray(BYTES)); + + assertEquals(copy.getOptionalGroup().getA(), 100); + assertEquals(copy.getOptionalForeignMessage().getC(), 16); + assertEquals(copy.getOptionalForeignEnum(), + proto.jspb.test.ForeignEnum.FOREIGN_FOO); + + + assertEquals(copy.getOneofString(), 'oneof'); + assertEquals(copy.getOneofFieldCase(), + proto.jspb.test.TestAllTypes.OneofFieldCase.ONEOF_STRING); + + assertElementsEquals(copy.getRepeatedInt32List(), [-42]); + assertElementsEquals(copy.getRepeatedInt64List(), [-0x7fffffff00000000]); + assertElementsEquals(copy.getRepeatedUint32List(), [0x80000000]); + assertElementsEquals(copy.getRepeatedUint64List(), [0xf000000000000000]); + assertElementsEquals(copy.getRepeatedSint32List(), [-100]); + assertElementsEquals(copy.getRepeatedSint64List(), [-0x8000000000000000]); + assertElementsEquals(copy.getRepeatedFixed32List(), [1234]); + assertElementsEquals(copy.getRepeatedFixed64List(), [0x1234567800000000]); + assertElementsEquals(copy.getRepeatedSfixed32List(), [-1234]); + assertElementsEquals(copy.getRepeatedSfixed64List(), [-0x1234567800000000]); + assertElementsEquals(copy.getRepeatedFloatList(), [1.5]); + assertElementsEquals(copy.getRepeatedDoubleList(), [-1.5]); + assertElementsEquals(copy.getRepeatedBoolList(), [true]); + assertElementsEquals(copy.getRepeatedStringList(), ['hello world']); + assertEquals(copy.getRepeatedBytesList().length, 2); + assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[0], BYTES)); + assertEquals(true, bytesCompare(copy.getRepeatedBytesList()[0], BYTES)); + assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[1], BYTES)); + assertEquals(copy.getRepeatedBytesList_asB64()[0], BYTES_B64); + assertEquals(copy.getRepeatedBytesList_asB64()[1], BYTES_B64); + assertEquals(copy.getRepeatedGroupList().length, 1); + assertEquals(copy.getRepeatedGroupList()[0].getA(), 100); + assertEquals(copy.getRepeatedForeignMessageList().length, 1); + assertEquals(copy.getRepeatedForeignMessageList()[0].getC(), 1000); + assertElementsEquals(copy.getRepeatedForeignEnumList(), + [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); + + assertElementsEquals(copy.getPackedRepeatedInt32List(), [-42]); + assertElementsEquals(copy.getPackedRepeatedInt64List(), + [-0x7fffffff00000000]); + assertElementsEquals(copy.getPackedRepeatedUint32List(), [0x80000000]); + assertElementsEquals(copy.getPackedRepeatedUint64List(), + [0xf000000000000000]); + assertElementsEquals(copy.getPackedRepeatedSint32List(), [-100]); + assertElementsEquals(copy.getPackedRepeatedSint64List(), + [-0x8000000000000000]); + assertElementsEquals(copy.getPackedRepeatedFixed32List(), [1234]); + assertElementsEquals(copy.getPackedRepeatedFixed64List(), + [0x1234567800000000]); + assertElementsEquals(copy.getPackedRepeatedSfixed32List(), [-1234]); + assertElementsEquals(copy.getPackedRepeatedSfixed64List(), + [-0x1234567800000000]); + assertElementsEquals(copy.getPackedRepeatedFloatList(), [1.5]); + assertElementsEquals(copy.getPackedRepeatedDoubleList(), [-1.5]); + +} + + +/** + * Helper: verify that all expected extensions are present. + * @param {!proto.jspb.test.TestExtendable} msg + */ +function checkExtensions(msg) { + assertEquals(-42, + msg.getExtension(proto.jspb.test.extendOptionalInt32)); + assertEquals(-0x7fffffff00000000, + msg.getExtension(proto.jspb.test.extendOptionalInt64)); + assertEquals(0x80000000, + msg.getExtension(proto.jspb.test.extendOptionalUint32)); + assertEquals(0xf000000000000000, + msg.getExtension(proto.jspb.test.extendOptionalUint64)); + assertEquals(-100, + msg.getExtension(proto.jspb.test.extendOptionalSint32)); + assertEquals(-0x8000000000000000, + msg.getExtension(proto.jspb.test.extendOptionalSint64)); + assertEquals(1234, + msg.getExtension(proto.jspb.test.extendOptionalFixed32)); + assertEquals(0x1234567800000000, + msg.getExtension(proto.jspb.test.extendOptionalFixed64)); + assertEquals(-1234, + msg.getExtension(proto.jspb.test.extendOptionalSfixed32)); + assertEquals(-0x1234567800000000, + msg.getExtension(proto.jspb.test.extendOptionalSfixed64)); + assertEquals(1.5, + msg.getExtension(proto.jspb.test.extendOptionalFloat)); + assertEquals(-1.5, + msg.getExtension(proto.jspb.test.extendOptionalDouble)); + assertEquals(true, + msg.getExtension(proto.jspb.test.extendOptionalBool)); + assertEquals('hello world', + msg.getExtension(proto.jspb.test.extendOptionalString)); + assertEquals( + true, bytesCompare( + msg.getExtension(proto.jspb.test.extendOptionalBytes), BYTES)); + assertEquals(16, + msg.getExtension( + proto.jspb.test.ExtendsWithMessage.optionalExtension).getFoo()); + + + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedInt32List), + [-42]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedInt64List), + [-0x7fffffff00000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedUint32List), + [0x80000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedUint64List), + [0xf000000000000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedSint32List), + [-100]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedSint64List), + [-0x8000000000000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedFixed32List), + [1234]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedFixed64List), + [0x1234567800000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedSfixed32List), + [-1234]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedSfixed64List), + [-0x1234567800000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedFloatList), + [1.5]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedDoubleList), + [-1.5]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedBoolList), + [true]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedStringList), + ['hello world']); + assertEquals( + true, + bytesCompare( + msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0], BYTES)); + assertEquals(1000, + msg.getExtension( + proto.jspb.test.ExtendsWithMessage.repeatedExtensionList)[0] + .getFoo()); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendRepeatedForeignEnumList), + [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); + + + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedInt32List), + [-42]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedInt64List), + [-0x7fffffff00000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedUint32List), + [0x80000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedUint64List), + [0xf000000000000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedSint32List), + [-100]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedSint64List), + [-0x8000000000000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed32List), + [1234]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed64List), + [0x1234567800000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed32List), + [-1234]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed64List), + [-0x1234567800000000]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedFloatList), + [1.5]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedDoubleList), + [-1.5]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedBoolList), + [true]); + assertElementsEquals( + msg.getExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList), + [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); + +} + + +describe('protoBinaryTest', function() { + /** + * Tests a basic serialization-deserializaton round-trip with all supported + * field types (on the TestAllTypes message type). + */ + it('testRoundTrip', function() { + var msg = new proto.jspb.test.TestAllTypes(); + fillAllFields(msg); + var encoded = msg.serializeBinary(); + var decoded = proto.jspb.test.TestAllTypes.deserializeBinary(encoded); + checkAllFields(msg, decoded); + }); + + /** + * Test that base64 string and Uint8Array are interchangeable in bytes fields. + */ + it('testBytesFieldsGettersInterop', function() { + var msg = new proto.jspb.test.TestAllTypes(); + // Set from a base64 string and check all the getters work. + msg.setOptionalBytes(BYTES_B64); + assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + + // Test binary serialize round trip doesn't break it. + msg = proto.jspb.test.TestAllTypes.deserializeBinary(msg.serializeBinary()); + assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + + msg = new proto.jspb.test.TestAllTypes(); + // Set from a Uint8Array and check all the getters work. + msg.setOptionalBytes(BYTES); + assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + + }); + + /** + * Test that bytes setters will receive result of any of the getters. + */ + it('testBytesFieldsSettersInterop', function() { + var msg = new proto.jspb.test.TestAllTypes(); + msg.setOptionalBytes(BYTES); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + + msg.setOptionalBytes(msg.getOptionalBytes()); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + msg.setOptionalBytes(msg.getOptionalBytes_asB64()); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + msg.setOptionalBytes(msg.getOptionalBytes_asU8()); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + }); + + /** + * Test that bytes setters will receive result of any of the getters. + */ + it('testRepeatedBytesGetters', function() { + var msg = new proto.jspb.test.TestAllTypes(); + + function assertGetters() { + assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[0])); + assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[1])); + assertTrue(msg.getRepeatedBytesList_asU8()[0] instanceof Uint8Array); + assertTrue(msg.getRepeatedBytesList_asU8()[1] instanceof Uint8Array); + + assertTrue(bytesCompare(msg.getRepeatedBytesList()[0], BYTES)); + assertTrue(bytesCompare(msg.getRepeatedBytesList()[1], BYTES)); + assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[0], BYTES)); + assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[1], BYTES)); + assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[0], BYTES)); + assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[1], BYTES)); + } + + msg.setRepeatedBytesList([BYTES, BYTES]); + assertGetters(); + + msg.setRepeatedBytesList([BYTES_B64, BYTES_B64]); + assertGetters(); + + msg.setRepeatedBytesList([]); + assertEquals(0, msg.getRepeatedBytesList().length); + assertEquals(0, msg.getRepeatedBytesList_asB64().length); + assertEquals(0, msg.getRepeatedBytesList_asU8().length); + }); + + /** + * Helper: fill all extension values. + * @param {proto.jspb.test.TestExtendable} msg + */ + function fillExtensions(msg) { + msg.setExtension( + proto.jspb.test.extendOptionalInt32, -42); + msg.setExtension( + proto.jspb.test.extendOptionalInt64, -0x7fffffff00000000); + msg.setExtension( + proto.jspb.test.extendOptionalUint32, 0x80000000); + msg.setExtension( + proto.jspb.test.extendOptionalUint64, 0xf000000000000000); + msg.setExtension( + proto.jspb.test.extendOptionalSint32, -100); + msg.setExtension( + proto.jspb.test.extendOptionalSint64, -0x8000000000000000); + msg.setExtension( + proto.jspb.test.extendOptionalFixed32, 1234); + msg.setExtension( + proto.jspb.test.extendOptionalFixed64, 0x1234567800000000); + msg.setExtension( + proto.jspb.test.extendOptionalSfixed32, -1234); + msg.setExtension( + proto.jspb.test.extendOptionalSfixed64, -0x1234567800000000); + msg.setExtension( + proto.jspb.test.extendOptionalFloat, 1.5); + msg.setExtension( + proto.jspb.test.extendOptionalDouble, -1.5); + msg.setExtension( + proto.jspb.test.extendOptionalBool, true); + msg.setExtension( + proto.jspb.test.extendOptionalString, 'hello world'); + msg.setExtension(proto.jspb.test.extendOptionalBytes, BYTES); + var submsg = new proto.jspb.test.ExtendsWithMessage(); + submsg.setFoo(16); + msg.setExtension( + proto.jspb.test.ExtendsWithMessage.optionalExtension, submsg); + msg.setExtension( + proto.jspb.test.extendOptionalForeignEnum, + proto.jspb.test.ForeignEnum.FOREIGN_FOO); + + + msg.setExtension( + proto.jspb.test.extendRepeatedInt32List, [-42]); + msg.setExtension( + proto.jspb.test.extendRepeatedInt64List, [-0x7fffffff00000000]); + msg.setExtension( + proto.jspb.test.extendRepeatedUint32List, [0x80000000]); + msg.setExtension( + proto.jspb.test.extendRepeatedUint64List, [0xf000000000000000]); + msg.setExtension( + proto.jspb.test.extendRepeatedSint32List, [-100]); + msg.setExtension( + proto.jspb.test.extendRepeatedSint64List, [-0x8000000000000000]); + msg.setExtension( + proto.jspb.test.extendRepeatedFixed32List, [1234]); + msg.setExtension( + proto.jspb.test.extendRepeatedFixed64List, [0x1234567800000000]); + msg.setExtension( + proto.jspb.test.extendRepeatedSfixed32List, [-1234]); + msg.setExtension( + proto.jspb.test.extendRepeatedSfixed64List, [-0x1234567800000000]); + msg.setExtension( + proto.jspb.test.extendRepeatedFloatList, [1.5]); + msg.setExtension( + proto.jspb.test.extendRepeatedDoubleList, [-1.5]); + msg.setExtension( + proto.jspb.test.extendRepeatedBoolList, [true]); + msg.setExtension( + proto.jspb.test.extendRepeatedStringList, ['hello world']); + msg.setExtension(proto.jspb.test.extendRepeatedBytesList, [BYTES]); + submsg = new proto.jspb.test.ExtendsWithMessage(); + submsg.setFoo(1000); + msg.setExtension( + proto.jspb.test.ExtendsWithMessage.repeatedExtensionList, [submsg]); + msg.setExtension(proto.jspb.test.extendRepeatedForeignEnumList, + [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); + + + msg.setExtension( + proto.jspb.test.extendPackedRepeatedInt32List, [-42]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedInt64List, [-0x7fffffff00000000]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedUint32List, [0x80000000]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedUint64List, [0xf000000000000000]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedSint32List, [-100]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedSint64List, [-0x8000000000000000]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedFixed32List, [1234]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedFixed64List, [0x1234567800000000]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedSfixed32List, [-1234]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedSfixed64List, + [-0x1234567800000000]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedFloatList, [1.5]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedDoubleList, [-1.5]); + msg.setExtension( + proto.jspb.test.extendPackedRepeatedBoolList, [true]); + msg.setExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList, + [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); + + } + + + /** + * Tests extension serialization and deserialization. + */ + it('testExtensions', function() { + var msg = new proto.jspb.test.TestExtendable(); + fillExtensions(msg); + var encoded = msg.serializeBinary(); + var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded); + checkExtensions(decoded); + }); +}); diff --git a/js/compatibility_tests/v3.1.0/binary/reader_test.js b/js/compatibility_tests/v3.1.0/binary/reader_test.js new file mode 100644 index 00000000..95711385 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/binary/reader_test.js @@ -0,0 +1,922 @@ +// 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. + +/** + * @fileoverview Test cases for jspb's binary protocol buffer reader. + * + * There are two particular magic numbers that need to be pointed out - + * 2^64-1025 is the largest number representable as both a double and an + * unsigned 64-bit integer, and 2^63-513 is the largest number representable as + * both a double and a signed 64-bit integer. + * + * Test suite is written using Jasmine -- see http://jasmine.github.io/ + * + * @author aappleby@google.com (Austin Appleby) + */ + +goog.require('goog.testing.asserts'); +goog.require('jspb.BinaryConstants'); +goog.require('jspb.BinaryDecoder'); +goog.require('jspb.BinaryReader'); +goog.require('jspb.BinaryWriter'); + + + +describe('binaryReaderTest', function() { + /** + * Tests the reader instance cache. + */ + it('testInstanceCaches', /** @suppress {visibility} */ function() { + var writer = new jspb.BinaryWriter(); + var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); + writer.writeMessage(1, dummyMessage, goog.nullFunction); + writer.writeMessage(2, dummyMessage, goog.nullFunction); + + var buffer = writer.getResultBuffer(); + + // Empty the instance caches. + jspb.BinaryReader.instanceCache_ = []; + + // Allocating and then freeing three decoders should leave us with three in + // the cache. + + var decoder1 = jspb.BinaryDecoder.alloc(); + var decoder2 = jspb.BinaryDecoder.alloc(); + var decoder3 = jspb.BinaryDecoder.alloc(); + decoder1.free(); + decoder2.free(); + decoder3.free(); + + assertEquals(3, jspb.BinaryDecoder.instanceCache_.length); + assertEquals(0, jspb.BinaryReader.instanceCache_.length); + + // Allocating and then freeing a reader should remove one decoder from its + // cache, but it should stay stuck to the reader afterwards since we can't + // have a reader without a decoder. + jspb.BinaryReader.alloc().free(); + + assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); + assertEquals(1, jspb.BinaryReader.instanceCache_.length); + + // Allocating a reader should remove a reader from the cache. + var reader = jspb.BinaryReader.alloc(buffer); + + assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); + assertEquals(0, jspb.BinaryReader.instanceCache_.length); + + // Processing the message reuses the current reader. + reader.nextField(); + assertEquals(1, reader.getFieldNumber()); + reader.readMessage(dummyMessage, function() { + assertEquals(0, jspb.BinaryReader.instanceCache_.length); + }); + + reader.nextField(); + assertEquals(2, reader.getFieldNumber()); + reader.readMessage(dummyMessage, function() { + assertEquals(0, jspb.BinaryReader.instanceCache_.length); + }); + + assertEquals(false, reader.nextField()); + + assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); + assertEquals(0, jspb.BinaryReader.instanceCache_.length); + + // Freeing the reader should put it back into the cache. + reader.free(); + + assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); + assertEquals(1, jspb.BinaryReader.instanceCache_.length); + }); + + + /** + * @param {number} x + * @return {number} + */ + function truncate(x) { + var temp = new Float32Array(1); + temp[0] = x; + return temp[0]; + } + + + /** + * Verifies that misuse of the reader class triggers assertions. + */ + it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() { + // Calling readMessage on a non-delimited field should trigger an + // assertion. + var reader = jspb.BinaryReader.alloc([8, 1]); + var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); + reader.nextField(); + assertThrows(function() { + reader.readMessage(dummyMessage, goog.nullFunction); + }); + + // Reading past the end of the stream should trigger an assertion. + reader = jspb.BinaryReader.alloc([9, 1]); + reader.nextField(); + assertThrows(function() {reader.readFixed64()}); + + // Reading past the end of a submessage should trigger an assertion. + reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]); + reader.nextField(); + reader.readMessage(dummyMessage, function() { + reader.nextField(); + assertThrows(function() {reader.readFixed32()}); + }); + + // Skipping an invalid field should trigger an assertion. + reader = jspb.BinaryReader.alloc([12, 1]); + reader.nextWireType_ = 1000; + assertThrows(function() {reader.skipField()}); + + // Reading fields with the wrong wire type should assert. + reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]); + reader.nextField(); + assertThrows(function() {reader.readInt32()}); + assertThrows(function() {reader.readInt32String()}); + assertThrows(function() {reader.readInt64()}); + assertThrows(function() {reader.readInt64String()}); + assertThrows(function() {reader.readUint32()}); + assertThrows(function() {reader.readUint32String()}); + assertThrows(function() {reader.readUint64()}); + assertThrows(function() {reader.readUint64String()}); + assertThrows(function() {reader.readSint32()}); + assertThrows(function() {reader.readBool()}); + assertThrows(function() {reader.readEnum()}); + + reader = jspb.BinaryReader.alloc([8, 1]); + reader.nextField(); + assertThrows(function() {reader.readFixed32()}); + assertThrows(function() {reader.readFixed64()}); + assertThrows(function() {reader.readSfixed32()}); + assertThrows(function() {reader.readSfixed64()}); + assertThrows(function() {reader.readFloat()}); + assertThrows(function() {reader.readDouble()}); + + assertThrows(function() {reader.readString()}); + assertThrows(function() {reader.readBytes()}); + }); + + + /** + * Tests encoding and decoding of unsigned field types. + * @param {Function} readField + * @param {Function} writeField + * @param {number} epsilon + * @param {number} upperLimit + * @param {Function} filter + * @private + * @suppress {missingProperties} + */ + var doTestUnsignedField_ = function(readField, + writeField, epsilon, upperLimit, filter) { + assertNotNull(readField); + assertNotNull(writeField); + + var writer = new jspb.BinaryWriter(); + + // Encode zero and limits. + writeField.call(writer, 1, filter(0)); + writeField.call(writer, 2, filter(epsilon)); + writeField.call(writer, 3, filter(upperLimit)); + + // Encode positive values. + for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { + writeField.call(writer, 4, filter(cursor)); + } + + var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); + + // Check zero and limits. + reader.nextField(); + assertEquals(1, reader.getFieldNumber()); + assertEquals(filter(0), readField.call(reader)); + + reader.nextField(); + assertEquals(2, reader.getFieldNumber()); + assertEquals(filter(epsilon), readField.call(reader)); + + reader.nextField(); + assertEquals(3, reader.getFieldNumber()); + assertEquals(filter(upperLimit), readField.call(reader)); + + // Check positive values. + for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { + reader.nextField(); + if (4 != reader.getFieldNumber()) throw 'fail!'; + if (filter(cursor) != readField.call(reader)) throw 'fail!'; + } + }; + + + /** + * Tests encoding and decoding of signed field types. + * @param {Function} readField + * @param {Function} writeField + * @param {number} epsilon + * @param {number} lowerLimit + * @param {number} upperLimit + * @param {Function} filter + * @private + * @suppress {missingProperties} + */ + var doTestSignedField_ = function(readField, + writeField, epsilon, lowerLimit, upperLimit, filter) { + var writer = new jspb.BinaryWriter(); + + // Encode zero and limits. + writeField.call(writer, 1, filter(lowerLimit)); + writeField.call(writer, 2, filter(-epsilon)); + writeField.call(writer, 3, filter(0)); + writeField.call(writer, 4, filter(epsilon)); + writeField.call(writer, 5, filter(upperLimit)); + + var inputValues = []; + + // Encode negative values. + for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) { + var val = filter(cursor); + writeField.call(writer, 6, val); + inputValues.push({ + fieldNumber: 6, + value: val + }); + } + + // Encode positive values. + for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { + var val = filter(cursor); + writeField.call(writer, 7, val); + inputValues.push({ + fieldNumber: 7, + value: val + }); + } + + var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); + + // Check zero and limits. + reader.nextField(); + assertEquals(1, reader.getFieldNumber()); + assertEquals(filter(lowerLimit), readField.call(reader)); + + reader.nextField(); + assertEquals(2, reader.getFieldNumber()); + assertEquals(filter(-epsilon), readField.call(reader)); + + reader.nextField(); + assertEquals(3, reader.getFieldNumber()); + assertEquals(filter(0), readField.call(reader)); + + reader.nextField(); + assertEquals(4, reader.getFieldNumber()); + assertEquals(filter(epsilon), readField.call(reader)); + + reader.nextField(); + assertEquals(5, reader.getFieldNumber()); + assertEquals(filter(upperLimit), readField.call(reader)); + + for (var i = 0; i < inputValues.length; i++) { + var expected = inputValues[i]; + reader.nextField(); + assertEquals(expected.fieldNumber, reader.getFieldNumber()); + assertEquals(expected.value, readField.call(reader)); + } + }; + + + /** + * Tests fields that use varint encoding. + */ + it('testVarintFields', function() { + assertNotUndefined(jspb.BinaryReader.prototype.readUint32); + assertNotUndefined(jspb.BinaryWriter.prototype.writeUint32); + assertNotUndefined(jspb.BinaryReader.prototype.readUint64); + assertNotUndefined(jspb.BinaryWriter.prototype.writeUint64); + assertNotUndefined(jspb.BinaryReader.prototype.readBool); + assertNotUndefined(jspb.BinaryWriter.prototype.writeBool); + doTestUnsignedField_( + jspb.BinaryReader.prototype.readUint32, + jspb.BinaryWriter.prototype.writeUint32, + 1, Math.pow(2, 32) - 1, Math.round); + + doTestUnsignedField_( + jspb.BinaryReader.prototype.readUint64, + jspb.BinaryWriter.prototype.writeUint64, + 1, Math.pow(2, 64) - 1025, Math.round); + + doTestSignedField_( + jspb.BinaryReader.prototype.readInt32, + jspb.BinaryWriter.prototype.writeInt32, + 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); + + doTestSignedField_( + jspb.BinaryReader.prototype.readInt64, + jspb.BinaryWriter.prototype.writeInt64, + 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); + + doTestSignedField_( + jspb.BinaryReader.prototype.readEnum, + jspb.BinaryWriter.prototype.writeEnum, + 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); + + doTestUnsignedField_( + jspb.BinaryReader.prototype.readBool, + jspb.BinaryWriter.prototype.writeBool, + 1, 1, function(x) { return !!x; }); + }); + + + /** + * Tests reading a field from hexadecimal string (format: '08 BE EF'). + * @param {Function} readField + * @param {number} expected + * @param {string} hexString + */ + function doTestHexStringVarint_(readField, expected, hexString) { + var bytesCount = (hexString.length + 1) / 3; + var bytes = new Uint8Array(bytesCount); + for (var i = 0; i < bytesCount; i++) { + bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16); + } + var reader = jspb.BinaryReader.alloc(bytes); + reader.nextField(); + assertEquals(expected, readField.call(reader)); + } + + + /** + * Tests non-canonical redundant varint decoding. + */ + it('testRedundantVarintFields', function() { + assertNotNull(jspb.BinaryReader.prototype.readUint32); + assertNotNull(jspb.BinaryReader.prototype.readUint64); + assertNotNull(jspb.BinaryReader.prototype.readSint32); + assertNotNull(jspb.BinaryReader.prototype.readSint64); + + // uint32 and sint32 take no more than 5 bytes + // 08 - field prefix (type = 0 means varint) + doTestHexStringVarint_( + jspb.BinaryReader.prototype.readUint32, + 12, '08 8C 80 80 80 00'); + + // 11 stands for -6 in zigzag encoding + doTestHexStringVarint_( + jspb.BinaryReader.prototype.readSint32, + -6, '08 8B 80 80 80 00'); + + // uint64 and sint64 take no more than 10 bytes + // 08 - field prefix (type = 0 means varint) + doTestHexStringVarint_( + jspb.BinaryReader.prototype.readUint64, + 12, '08 8C 80 80 80 80 80 80 80 80 00'); + + // 11 stands for -6 in zigzag encoding + doTestHexStringVarint_( + jspb.BinaryReader.prototype.readSint64, + -6, '08 8B 80 80 80 80 80 80 80 80 00'); + }); + + + /** + * Tests 64-bit fields that are handled as strings. + */ + it('testStringInt64Fields', function() { + var writer = new jspb.BinaryWriter(); + + var testSignedData = [ + '2730538252207801776', + '-2688470994844604560', + '3398529779486536359', + '3568577411627971000', + '272477188847484900', + '-6649058714086158188', + '-7695254765712060806', + '-4525541438037104029', + '-4993706538836508568', + '4990160321893729138' + ]; + var testUnsignedData = [ + '7822732630241694882', + '6753602971916687352', + '2399935075244442116', + '8724292567325338867', + '16948784802625696584', + '4136275908516066934', + '3575388346793700364', + '5167142028379259461', + '1557573948689737699', + '17100725280812548567' + ]; + + for (var i = 0; i < testSignedData.length; i++) { + writer.writeInt64String(2 * i + 1, testSignedData[i]); + writer.writeUint64String(2 * i + 2, testUnsignedData[i]); + } + + var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); + + for (var i = 0; i < testSignedData.length; i++) { + reader.nextField(); + assertEquals(2 * i + 1, reader.getFieldNumber()); + assertEquals(testSignedData[i], reader.readInt64String()); + reader.nextField(); + assertEquals(2 * i + 2, reader.getFieldNumber()); + assertEquals(testUnsignedData[i], reader.readUint64String()); + } + }); + + + /** + * Tests fields that use zigzag encoding. + */ + it('testZigzagFields', function() { + doTestSignedField_( + jspb.BinaryReader.prototype.readSint32, + jspb.BinaryWriter.prototype.writeSint32, + 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); + + doTestSignedField_( + jspb.BinaryReader.prototype.readSint64, + jspb.BinaryWriter.prototype.writeSint64, + 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); + }); + + + /** + * Tests fields that use fixed-length encoding. + */ + it('testFixedFields', function() { + doTestUnsignedField_( + jspb.BinaryReader.prototype.readFixed32, + jspb.BinaryWriter.prototype.writeFixed32, + 1, Math.pow(2, 32) - 1, Math.round); + + doTestUnsignedField_( + jspb.BinaryReader.prototype.readFixed64, + jspb.BinaryWriter.prototype.writeFixed64, + 1, Math.pow(2, 64) - 1025, Math.round); + + doTestSignedField_( + jspb.BinaryReader.prototype.readSfixed32, + jspb.BinaryWriter.prototype.writeSfixed32, + 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); + + doTestSignedField_( + jspb.BinaryReader.prototype.readSfixed64, + jspb.BinaryWriter.prototype.writeSfixed64, + 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); + }); + + + /** + * Tests floating point fields. + */ + it('testFloatFields', function() { + doTestSignedField_( + jspb.BinaryReader.prototype.readFloat, + jspb.BinaryWriter.prototype.writeFloat, + jspb.BinaryConstants.FLOAT32_MIN, + -jspb.BinaryConstants.FLOAT32_MAX, + jspb.BinaryConstants.FLOAT32_MAX, + truncate); + + doTestSignedField_( + jspb.BinaryReader.prototype.readDouble, + jspb.BinaryWriter.prototype.writeDouble, + jspb.BinaryConstants.FLOAT64_EPS * 10, + -jspb.BinaryConstants.FLOAT64_MIN, + jspb.BinaryConstants.FLOAT64_MIN, + function(x) { return x; }); + }); + + + /** + * Tests length-delimited string fields. + */ + it('testStringFields', function() { + var s1 = 'The quick brown fox jumps over the lazy dog.'; + var s2 = '人人生而自由,在尊嚴和權利上一律平等。'; + + var writer = new jspb.BinaryWriter(); + + writer.writeString(1, s1); + writer.writeString(2, s2); + + var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); + + reader.nextField(); + assertEquals(1, reader.getFieldNumber()); + assertEquals(s1, reader.readString()); + + reader.nextField(); + assertEquals(2, reader.getFieldNumber()); + assertEquals(s2, reader.readString()); + }); + + + /** + * Tests length-delimited byte fields. + */ + it('testByteFields', function() { + var message = []; + var lowerLimit = 1; + var upperLimit = 256; + var scale = 1.1; + + var writer = new jspb.BinaryWriter(); + + for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) { + var len = Math.round(cursor); + var bytes = []; + for (var i = 0; i < len; i++) bytes.push(i % 256); + + writer.writeBytes(len, bytes); + } + + var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); + + for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) { + var len = Math.round(cursor); + if (len != reader.getFieldNumber()) throw 'fail!'; + + var bytes = reader.readBytes(); + if (len != bytes.length) throw 'fail!'; + for (var i = 0; i < bytes.length; i++) { + if (i % 256 != bytes[i]) throw 'fail!'; + } + } + }); + + + /** + * Tests nested messages. + */ + it('testNesting', function() { + var writer = new jspb.BinaryWriter(); + var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); + + writer.writeInt32(1, 100); + + // Add one message with 3 int fields. + writer.writeMessage(2, dummyMessage, function() { + writer.writeInt32(3, 300); + writer.writeInt32(4, 400); + writer.writeInt32(5, 500); + }); + + // Add one empty message. + writer.writeMessage(6, dummyMessage, goog.nullFunction); + + writer.writeInt32(7, 700); + + var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); + + // Validate outermost message. + + reader.nextField(); + assertEquals(1, reader.getFieldNumber()); + assertEquals(100, reader.readInt32()); + + reader.nextField(); + assertEquals(2, reader.getFieldNumber()); + reader.readMessage(dummyMessage, function() { + // Validate embedded message 1. + reader.nextField(); + assertEquals(3, reader.getFieldNumber()); + assertEquals(300, reader.readInt32()); + + reader.nextField(); + assertEquals(4, reader.getFieldNumber()); + assertEquals(400, reader.readInt32()); + + reader.nextField(); + assertEquals(5, reader.getFieldNumber()); + assertEquals(500, reader.readInt32()); + + assertEquals(false, reader.nextField()); + }); + + reader.nextField(); + assertEquals(6, reader.getFieldNumber()); + reader.readMessage(dummyMessage, function() { + // Validate embedded message 2. + + assertEquals(false, reader.nextField()); + }); + + reader.nextField(); + assertEquals(7, reader.getFieldNumber()); + assertEquals(700, reader.readInt32()); + + assertEquals(false, reader.nextField()); + }); + + /** + * Tests skipping fields of each type by interleaving them with sentinel + * values and skipping everything that's not a sentinel. + */ + it('testSkipField', function() { + var writer = new jspb.BinaryWriter(); + + var sentinel = 123456789; + + // Write varint fields of different sizes. + writer.writeInt32(1, sentinel); + writer.writeInt32(1, 1); + writer.writeInt32(1, 1000); + writer.writeInt32(1, 1000000); + writer.writeInt32(1, 1000000000); + + // Write fixed 64-bit encoded fields. + writer.writeInt32(2, sentinel); + writer.writeDouble(2, 1); + writer.writeFixed64(2, 1); + writer.writeSfixed64(2, 1); + + // Write fixed 32-bit encoded fields. + writer.writeInt32(3, sentinel); + writer.writeFloat(3, 1); + writer.writeFixed32(3, 1); + writer.writeSfixed32(3, 1); + + // Write delimited fields. + writer.writeInt32(4, sentinel); + writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + writer.writeString(4, 'The quick brown fox jumps over the lazy dog'); + + // Write a group with a nested group inside. + writer.writeInt32(5, sentinel); + var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); + writer.writeGroup(5, dummyMessage, function() { + writer.writeInt64(42, 42); + writer.writeGroup(6, dummyMessage, function() { + writer.writeInt64(84, 42); + }); + }); + + // Write final sentinel. + writer.writeInt32(6, sentinel); + + var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); + + function skip(field, count) { + for (var i = 0; i < count; i++) { + reader.nextField(); + if (field != reader.getFieldNumber()) throw 'fail!'; + reader.skipField(); + } + } + + reader.nextField(); + assertEquals(1, reader.getFieldNumber()); + assertEquals(sentinel, reader.readInt32()); + skip(1, 4); + + reader.nextField(); + assertEquals(2, reader.getFieldNumber()); + assertEquals(sentinel, reader.readInt32()); + skip(2, 3); + + reader.nextField(); + assertEquals(3, reader.getFieldNumber()); + assertEquals(sentinel, reader.readInt32()); + skip(3, 3); + + reader.nextField(); + assertEquals(4, reader.getFieldNumber()); + assertEquals(sentinel, reader.readInt32()); + skip(4, 2); + + reader.nextField(); + assertEquals(5, reader.getFieldNumber()); + assertEquals(sentinel, reader.readInt32()); + skip(5, 1); + + reader.nextField(); + assertEquals(6, reader.getFieldNumber()); + assertEquals(sentinel, reader.readInt32()); + }); + + + /** + * Tests packed fields. + */ + it('testPackedFields', function() { + var writer = new jspb.BinaryWriter(); + + var sentinel = 123456789; + + var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]; + var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; + var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; + var boolData = [true, false, true, true, false, false, true, false]; + + for (var i = 0; i < floatData.length; i++) { + floatData[i] = truncate(floatData[i]); + } + + writer.writeInt32(1, sentinel); + + writer.writePackedInt32(2, signedData); + writer.writePackedInt64(2, signedData); + writer.writePackedUint32(2, unsignedData); + writer.writePackedUint64(2, unsignedData); + writer.writePackedSint32(2, signedData); + writer.writePackedSint64(2, signedData); + writer.writePackedFixed32(2, unsignedData); + writer.writePackedFixed64(2, unsignedData); + writer.writePackedSfixed32(2, signedData); + writer.writePackedSfixed64(2, signedData); + writer.writePackedFloat(2, floatData); + writer.writePackedDouble(2, doubleData); + writer.writePackedBool(2, boolData); + writer.writePackedEnum(2, unsignedData); + + writer.writeInt32(3, sentinel); + + var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); + + reader.nextField(); + assertEquals(sentinel, reader.readInt32()); + + reader.nextField(); + assertElementsEquals(reader.readPackedInt32(), signedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedInt64(), signedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedUint32(), unsignedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedUint64(), unsignedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedSint32(), signedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedSint64(), signedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedFixed32(), unsignedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedFixed64(), unsignedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedSfixed32(), signedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedSfixed64(), signedData); + + reader.nextField(); + assertElementsEquals(reader.readPackedFloat(), floatData); + + reader.nextField(); + assertElementsEquals(reader.readPackedDouble(), doubleData); + + reader.nextField(); + assertElementsEquals(reader.readPackedBool(), boolData); + + reader.nextField(); + assertElementsEquals(reader.readPackedEnum(), unsignedData); + + reader.nextField(); + assertEquals(sentinel, reader.readInt32()); + }); + + + /** + * Byte blobs inside nested messages should always have their byte offset set + * relative to the start of the outermost blob, not the start of their parent + * blob. + */ + it('testNestedBlobs', function() { + // Create a proto consisting of two nested messages, with the inner one + // containing a blob of bytes. + + var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED; + var blob = [1, 2, 3, 4, 5]; + var writer = new jspb.BinaryWriter(); + var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); + + writer.writeMessage(1, dummyMessage, function() { + writer.writeMessage(1, dummyMessage, function() { + writer.writeBytes(1, blob); + }); + }); + + // Peel off the outer two message layers. Each layer should have two bytes + // of overhead, one for the field tag and one for the length of the inner + // blob. + + var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer()); + assertEquals(fieldTag, decoder1.readUnsignedVarint32()); + assertEquals(blob.length + 4, decoder1.readUnsignedVarint32()); + + var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4)); + assertEquals(fieldTag, decoder2.readUnsignedVarint32()); + assertEquals(blob.length + 2, decoder2.readUnsignedVarint32()); + + assertEquals(fieldTag, decoder2.readUnsignedVarint32()); + assertEquals(blob.length, decoder2.readUnsignedVarint32()); + var bytes = decoder2.readBytes(blob.length); + + assertElementsEquals(bytes, blob); + }); + + + /** + * Tests read callbacks. + */ + it('testReadCallbacks', function() { + var writer = new jspb.BinaryWriter(); + var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); + + // Add an int, a submessage, and another int. + writer.writeInt32(1, 100); + + writer.writeMessage(2, dummyMessage, function() { + writer.writeInt32(3, 300); + writer.writeInt32(4, 400); + writer.writeInt32(5, 500); + }); + + writer.writeInt32(7, 700); + + // Create the reader and register a custom read callback. + var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); + + /** + * @param {!jspb.BinaryReader} reader + * @return {*} + */ + function readCallback(reader) { + reader.nextField(); + assertEquals(3, reader.getFieldNumber()); + assertEquals(300, reader.readInt32()); + + reader.nextField(); + assertEquals(4, reader.getFieldNumber()); + assertEquals(400, reader.readInt32()); + + reader.nextField(); + assertEquals(5, reader.getFieldNumber()); + assertEquals(500, reader.readInt32()); + + assertEquals(false, reader.nextField()); + }; + + reader.registerReadCallback('readCallback', readCallback); + + // Read the container message. + reader.nextField(); + assertEquals(1, reader.getFieldNumber()); + assertEquals(100, reader.readInt32()); + + reader.nextField(); + assertEquals(2, reader.getFieldNumber()); + reader.readMessage(dummyMessage, function() { + // Decode the embedded message using the registered callback. + reader.runReadCallback('readCallback'); + }); + + reader.nextField(); + assertEquals(7, reader.getFieldNumber()); + assertEquals(700, reader.readInt32()); + + assertEquals(false, reader.nextField()); + }); +}); diff --git a/js/compatibility_tests/v3.1.0/binary/utils_test.js b/js/compatibility_tests/v3.1.0/binary/utils_test.js new file mode 100644 index 00000000..d27e5ea2 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/binary/utils_test.js @@ -0,0 +1,668 @@ +// 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. + +/** + * @fileoverview Test cases for jspb's helper functions. + * + * Test suite is written using Jasmine -- see http://jasmine.github.io/ + * + * @author aappleby@google.com (Austin Appleby) + */ + +goog.require('goog.crypt.base64'); +goog.require('goog.testing.asserts'); +goog.require('jspb.BinaryConstants'); +goog.require('jspb.BinaryWriter'); +goog.require('jspb.utils'); + + +/** + * @param {number} x + * @return {number} + */ +function truncate(x) { + var temp = new Float32Array(1); + temp[0] = x; + return temp[0]; +} + + +/** + * Converts an 64-bit integer in split representation to a 64-bit hash string + * (8 bits encoded per character). + * @param {number} bitsLow The low 32 bits of the split 64-bit integer. + * @param {number} bitsHigh The high 32 bits of the split 64-bit integer. + * @return {string} The encoded hash string, 8 bits per character. + */ +function toHashString(bitsLow, bitsHigh) { + return String.fromCharCode((bitsLow >>> 0) & 0xFF, + (bitsLow >>> 8) & 0xFF, + (bitsLow >>> 16) & 0xFF, + (bitsLow >>> 24) & 0xFF, + (bitsHigh >>> 0) & 0xFF, + (bitsHigh >>> 8) & 0xFF, + (bitsHigh >>> 16) & 0xFF, + (bitsHigh >>> 24) & 0xFF); +} + + +describe('binaryUtilsTest', function() { + /** + * Tests lossless binary-to-decimal conversion. + */ + it('testDecimalConversion', function() { + // Check some magic numbers. + var result = + jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304); + assertEquals('10000000000000000001', result); + + result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b); + assertEquals('123456789123456789', result); + + result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c); + assertEquals('12345678901234567890', result); + + result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8); + assertEquals('9876543210987654321', result); + + // Check limits. + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000); + assertEquals('0', result); + + result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF); + assertEquals('18446744073709551615', result); + + // Check each bit of the low dword. + for (var i = 0; i < 32; i++) { + var low = (1 << i) >>> 0; + result = jspb.utils.joinUnsignedDecimalString(low, 0); + assertEquals('' + Math.pow(2, i), result); + } + + // Check the first 20 bits of the high dword. + for (var i = 0; i < 20; i++) { + var high = (1 << i) >>> 0; + result = jspb.utils.joinUnsignedDecimalString(0, high); + assertEquals('' + Math.pow(2, 32 + i), result); + } + + // V8's internal double-to-string conversion is inaccurate for values above + // 2^52, even if they're representable integers - check the rest of the bits + // manually against the correct string representations of 2^N. + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000); + assertEquals('4503599627370496', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000); + assertEquals('9007199254740992', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000); + assertEquals('18014398509481984', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000); + assertEquals('36028797018963968', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000); + assertEquals('72057594037927936', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000); + assertEquals('144115188075855872', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000); + assertEquals('288230376151711744', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000); + assertEquals('576460752303423488', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000); + assertEquals('1152921504606846976', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000); + assertEquals('2305843009213693952', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000); + assertEquals('4611686018427387904', result); + + result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000); + assertEquals('9223372036854775808', result); + }); + + + /** + * Going from hash strings to decimal strings should also be lossless. + */ + it('testHashToDecimalConversion', function() { + var result; + var convert = jspb.utils.hash64ToDecimalString; + + result = convert(toHashString(0x00000000, 0x00000000), false); + assertEquals('0', result); + + result = convert(toHashString(0x00000000, 0x00000000), true); + assertEquals('0', result); + + result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false); + assertEquals('18446744073709551615', result); + + result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true); + assertEquals('-1', result); + + result = convert(toHashString(0x00000000, 0x80000000), false); + assertEquals('9223372036854775808', result); + + result = convert(toHashString(0x00000000, 0x80000000), true); + assertEquals('-9223372036854775808', result); + + result = convert(toHashString(0xacd05f15, 0x01b69b4b), false); + assertEquals('123456789123456789', result); + + result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true); + assertEquals('-123456789123456789', result); + + // And converting arrays of hashes should work the same way. + result = jspb.utils.hash64ArrayToDecimalStrings([ + toHashString(0xFFFFFFFF, 0xFFFFFFFF), + toHashString(0x00000000, 0x80000000), + toHashString(0xacd05f15, 0x01b69b4b)], false); + assertEquals(3, result.length); + assertEquals('18446744073709551615', result[0]); + assertEquals('9223372036854775808', result[1]); + assertEquals('123456789123456789', result[2]); + }); + + /* + * Going from decimal strings to hash strings should be lossless. + */ + it('testDecimalToHashConversion', function() { + var result; + var convert = jspb.utils.decimalStringToHash64; + + result = convert('0'); + assertEquals(String.fromCharCode.apply(null, + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result); + + result = convert('-1'); + assertEquals(String.fromCharCode.apply(null, + [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); + + result = convert('18446744073709551615'); + assertEquals(String.fromCharCode.apply(null, + [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); + + result = convert('9223372036854775808'); + assertEquals(String.fromCharCode.apply(null, + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result); + + result = convert('-9223372036854775808'); + assertEquals(String.fromCharCode.apply(null, + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result); + + result = convert('123456789123456789'); + assertEquals(String.fromCharCode.apply(null, + [0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01]), result); + + result = convert('-123456789123456789'); + assertEquals(String.fromCharCode.apply(null, + [0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE]), result); + }); + + /** + * Going from hash strings to hex strings should be lossless. + */ + it('testHashToHexConversion', function() { + var result; + var convert = jspb.utils.hash64ToHexString; + + result = convert(toHashString(0x00000000, 0x00000000)); + assertEquals('0x0000000000000000', result); + + result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF)); + assertEquals('0xffffffffffffffff', result); + + result = convert(toHashString(0x12345678, 0x9ABCDEF0)); + assertEquals('0x9abcdef012345678', result); + }); + + + /** + * Going from hex strings to hash strings should be lossless. + */ + it('testHexToHashConversion', function() { + var result; + var convert = jspb.utils.hexStringToHash64; + + result = convert('0x0000000000000000'); + assertEquals(String.fromCharCode.apply(null, + [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result); + + result = convert('0xffffffffffffffff'); + assertEquals(String.fromCharCode.apply(null, + [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); + + // Hex string is big-endian, hash string is little-endian. + result = convert('0x123456789ABCDEF0'); + assertEquals(String.fromCharCode.apply(null, + [0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]), result); + + // Capitalization should not matter. + result = convert('0x0000abcdefABCDEF'); + assertEquals(String.fromCharCode.apply(null, + [0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]), result); + }); + + + /** + * Going from numbers to hash strings should be lossless for up to 53 bits of + * precision. + */ + it('testNumberToHashConversion', function() { + var result; + var convert = jspb.utils.numberToHash64; + + result = convert(0x0000000000000); + assertEquals('0x0000000000000000', jspb.utils.hash64ToHexString(result)); + + result = convert(0xFFFFFFFFFFFFF); + assertEquals('0x000fffffffffffff', jspb.utils.hash64ToHexString(result)); + + result = convert(0x123456789ABCD); + assertEquals('0x000123456789abcd', jspb.utils.hash64ToHexString(result)); + + result = convert(0xDCBA987654321); + assertEquals('0x000dcba987654321', jspb.utils.hash64ToHexString(result)); + + // 53 bits of precision should not be truncated. + result = convert(0x10000000000001); + assertEquals('0x0010000000000001', jspb.utils.hash64ToHexString(result)); + + // 54 bits of precision should be truncated. + result = convert(0x20000000000001); + assertNotEquals( + '0x0020000000000001', jspb.utils.hash64ToHexString(result)); + }); + + + /** + * Sanity check the behavior of Javascript's strings when doing funny things + * with unicode characters. + */ + it('sanityCheckUnicodeStrings', function() { + var strings = new Array(65536); + + // All possible unsigned 16-bit values should be storable in a string, they + // shouldn't do weird things with the length of the string, and they should + // come back out of the string unchanged. + for (var i = 0; i < 65536; i++) { + strings[i] = 'a' + String.fromCharCode(i) + 'a'; + if (3 != strings[i].length) throw 'fail!'; + if (i != strings[i].charCodeAt(1)) throw 'fail!'; + } + + // Each unicode character should compare equal to itself and not equal to a + // different unicode character. + for (var i = 0; i < 65536; i++) { + if (strings[i] != strings[i]) throw 'fail!'; + if (strings[i] == strings[(i + 1) % 65536]) throw 'fail!'; + } + }); + + + /** + * Tests conversion from 32-bit floating point numbers to split64 numbers. + */ + it('testFloat32ToSplit64', function() { + var f32_eps = jspb.BinaryConstants.FLOAT32_EPS; + var f32_min = jspb.BinaryConstants.FLOAT32_MIN; + var f32_max = jspb.BinaryConstants.FLOAT32_MAX; + + // NaN. + jspb.utils.splitFloat32(NaN); + if (!isNaN(jspb.utils.joinFloat32(jspb.utils.split64Low, + jspb.utils.split64High))) { + throw 'fail!'; + } + + /** + * @param {number} x + * @param {number=} opt_bits + */ + function test(x, opt_bits) { + jspb.utils.splitFloat32(x); + if (goog.isDef(opt_bits)) { + if (opt_bits != jspb.utils.split64Low) throw 'fail!'; + } + if (truncate(x) != jspb.utils.joinFloat32(jspb.utils.split64Low, + jspb.utils.split64High)) { + throw 'fail!'; + } + } + + // Positive and negative infinity. + test(Infinity, 0x7f800000); + test(-Infinity, 0xff800000); + + // Positive and negative zero. + test(0, 0x00000000); + test(-0, 0x80000000); + + // Positive and negative epsilon. + test(f32_eps, 0x00000001); + test(-f32_eps, 0x80000001); + + // Positive and negative min. + test(f32_min, 0x00800000); + test(-f32_min, 0x80800000); + + // Positive and negative max. + test(f32_max, 0x7F7FFFFF); + test(-f32_max, 0xFF7FFFFF); + + // Various positive values. + var cursor = f32_eps * 10; + while (cursor != Infinity) { + test(cursor); + cursor *= 1.1; + } + + // Various negative values. + cursor = -f32_eps * 10; + while (cursor != -Infinity) { + test(cursor); + cursor *= 1.1; + } + }); + + + /** + * Tests conversion from 64-bit floating point numbers to split64 numbers. + */ + it('testFloat64ToSplit64', function() { + var f64_eps = jspb.BinaryConstants.FLOAT64_EPS; + var f64_min = jspb.BinaryConstants.FLOAT64_MIN; + var f64_max = jspb.BinaryConstants.FLOAT64_MAX; + + // NaN. + jspb.utils.splitFloat64(NaN); + if (!isNaN(jspb.utils.joinFloat64(jspb.utils.split64Low, + jspb.utils.split64High))) { + throw 'fail!'; + } + + /** + * @param {number} x + * @param {number=} opt_highBits + * @param {number=} opt_lowBits + */ + function test(x, opt_highBits, opt_lowBits) { + jspb.utils.splitFloat64(x); + if (goog.isDef(opt_highBits)) { + if (opt_highBits != jspb.utils.split64High) throw 'fail!'; + } + if (goog.isDef(opt_lowBits)) { + if (opt_lowBits != jspb.utils.split64Low) throw 'fail!'; + } + if (x != jspb.utils.joinFloat64(jspb.utils.split64Low, + jspb.utils.split64High)) { + throw 'fail!'; + } + } + + // Positive and negative infinity. + test(Infinity, 0x7ff00000, 0x00000000); + test(-Infinity, 0xfff00000, 0x00000000); + + // Positive and negative zero. + test(0, 0x00000000, 0x00000000); + test(-0, 0x80000000, 0x00000000); + + // Positive and negative epsilon. + test(f64_eps, 0x00000000, 0x00000001); + test(-f64_eps, 0x80000000, 0x00000001); + + // Positive and negative min. + test(f64_min, 0x00100000, 0x00000000); + test(-f64_min, 0x80100000, 0x00000000); + + // Positive and negative max. + test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF); + test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF); + + // Various positive values. + var cursor = f64_eps * 10; + while (cursor != Infinity) { + test(cursor); + cursor *= 1.1; + } + + // Various negative values. + cursor = -f64_eps * 10; + while (cursor != -Infinity) { + test(cursor); + cursor *= 1.1; + } + }); + + + /** + * Tests counting packed varints. + */ + it('testCountVarints', function() { + var values = []; + for (var i = 1; i < 1000000000; i *= 1.1) { + values.push(Math.floor(i)); + } + + var writer = new jspb.BinaryWriter(); + writer.writePackedUint64(1, values); + + var buffer = new Uint8Array(writer.getResultBuffer()); + + // We should have two more varints than we started with - one for the field + // tag, one for the packed length. + assertEquals(values.length + 2, + jspb.utils.countVarints(buffer, 0, buffer.length)); + }); + + + /** + * Tests counting matching varint fields. + */ + it('testCountVarintFields', function() { + var writer = new jspb.BinaryWriter(); + + var count = 0; + for (var i = 1; i < 1000000000; i *= 1.1) { + writer.writeUint64(1, Math.floor(i)); + count++; + } + writer.writeString(2, 'terminator'); + + var buffer = new Uint8Array(writer.getResultBuffer()); + assertEquals(count, + jspb.utils.countVarintFields(buffer, 0, buffer.length, 1)); + + writer = new jspb.BinaryWriter(); + + count = 0; + for (var i = 1; i < 1000000000; i *= 1.1) { + writer.writeUint64(123456789, Math.floor(i)); + count++; + } + writer.writeString(2, 'terminator'); + + buffer = new Uint8Array(writer.getResultBuffer()); + assertEquals(count, + jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789)); + }); + + + /** + * Tests counting matching fixed32 fields. + */ + it('testCountFixed32Fields', function() { + var writer = new jspb.BinaryWriter(); + + var count = 0; + for (var i = 1; i < 1000000000; i *= 1.1) { + writer.writeFixed32(1, Math.floor(i)); + count++; + } + writer.writeString(2, 'terminator'); + + var buffer = new Uint8Array(writer.getResultBuffer()); + assertEquals(count, + jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1)); + + writer = new jspb.BinaryWriter(); + + count = 0; + for (var i = 1; i < 1000000000; i *= 1.1) { + writer.writeFixed32(123456789, Math.floor(i)); + count++; + } + writer.writeString(2, 'terminator'); + + buffer = new Uint8Array(writer.getResultBuffer()); + assertEquals(count, + jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789)); + }); + + + /** + * Tests counting matching fixed64 fields. + */ + it('testCountFixed64Fields', function() { + var writer = new jspb.BinaryWriter(); + + var count = 0; + for (var i = 1; i < 1000000000; i *= 1.1) { + writer.writeDouble(1, i); + count++; + } + writer.writeString(2, 'terminator'); + + var buffer = new Uint8Array(writer.getResultBuffer()); + assertEquals(count, + jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1)); + + writer = new jspb.BinaryWriter(); + + count = 0; + for (var i = 1; i < 1000000000; i *= 1.1) { + writer.writeDouble(123456789, i); + count++; + } + writer.writeString(2, 'terminator'); + + buffer = new Uint8Array(writer.getResultBuffer()); + assertEquals(count, + jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789)); + }); + + + /** + * Tests counting matching delimited fields. + */ + it('testCountDelimitedFields', function() { + var writer = new jspb.BinaryWriter(); + + var count = 0; + for (var i = 1; i < 1000; i *= 1.1) { + writer.writeBytes(1, [Math.floor(i)]); + count++; + } + writer.writeString(2, 'terminator'); + + var buffer = new Uint8Array(writer.getResultBuffer()); + assertEquals(count, + jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1)); + + writer = new jspb.BinaryWriter(); + + count = 0; + for (var i = 1; i < 1000; i *= 1.1) { + writer.writeBytes(123456789, [Math.floor(i)]); + count++; + } + writer.writeString(2, 'terminator'); + + buffer = new Uint8Array(writer.getResultBuffer()); + assertEquals(count, + jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789)); + }); + + + /** + * Tests byte format for debug strings. + */ + it('testDebugBytesToTextFormat', function() { + assertEquals('""', jspb.utils.debugBytesToTextFormat(null)); + assertEquals('"\\x00\\x10\\xff"', + jspb.utils.debugBytesToTextFormat([0, 16, 255])); + }); + + + /** + * Tests converting byte blob sources into byte blobs. + */ + it('testByteSourceToUint8Array', function() { + var convert = jspb.utils.byteSourceToUint8Array; + + var sourceData = []; + for (var i = 0; i < 256; i++) { + sourceData.push(i); + } + + var sourceBytes = new Uint8Array(sourceData); + var sourceBuffer = sourceBytes.buffer; + var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData); + var sourceString = String.fromCharCode.apply(null, sourceData); + + function check(result) { + assertEquals(Uint8Array, result.constructor); + assertEquals(sourceData.length, result.length); + for (var i = 0; i < result.length; i++) { + assertEquals(sourceData[i], result[i]); + } + } + + // Converting Uint8Arrays into Uint8Arrays should be a no-op. + assertEquals(sourceBytes, convert(sourceBytes)); + + // Converting Array.<numbers> into Uint8Arrays should work. + check(convert(sourceData)); + + // Converting ArrayBuffers into Uint8Arrays should work. + check(convert(sourceBuffer)); + + // Converting base64-encoded strings into Uint8Arrays should work. + check(convert(sourceBase64)); + }); +}); diff --git a/js/compatibility_tests/v3.1.0/binary/writer_test.js b/js/compatibility_tests/v3.1.0/binary/writer_test.js new file mode 100644 index 00000000..d5dadb41 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/binary/writer_test.js @@ -0,0 +1,122 @@ +// 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. + +/** + * @fileoverview Test cases for jspb's binary protocol buffer writer. In + * practice BinaryWriter is used to drive the Decoder and Reader test cases, + * so only writer-specific tests are here. + * + * Test suite is written using Jasmine -- see http://jasmine.github.io/ + * + * @author aappleby@google.com (Austin Appleby) + */ + +goog.require('goog.crypt'); +goog.require('goog.testing.asserts'); +goog.require('jspb.BinaryWriter'); + + +/** + * @param {function()} func This function should throw an error when run. + */ +function assertFails(func) { + var e = assertThrows(func); + //assertNotNull(e.toString().match(/Error/)); +} + + +describe('binaryWriterTest', function() { + /** + * Verifies that misuse of the writer class triggers assertions. + */ + it('testWriteErrors', function() { + // Submessages with invalid field indices should assert. + var writer = new jspb.BinaryWriter(); + var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); + + assertFails(function() { + writer.writeMessage(-1, dummyMessage, goog.nullFunction); + }); + + // Writing invalid field indices should assert. + writer = new jspb.BinaryWriter(); + assertFails(function() {writer.writeUint64(-1, 1);}); + + // Writing out-of-range field values should assert. + writer = new jspb.BinaryWriter(); + + assertFails(function() {writer.writeInt32(1, -Infinity);}); + assertFails(function() {writer.writeInt32(1, Infinity);}); + + assertFails(function() {writer.writeInt64(1, -Infinity);}); + assertFails(function() {writer.writeInt64(1, Infinity);}); + + assertFails(function() {writer.writeUint32(1, -1);}); + assertFails(function() {writer.writeUint32(1, Infinity);}); + + assertFails(function() {writer.writeUint64(1, -1);}); + assertFails(function() {writer.writeUint64(1, Infinity);}); + + assertFails(function() {writer.writeSint32(1, -Infinity);}); + assertFails(function() {writer.writeSint32(1, Infinity);}); + + assertFails(function() {writer.writeSint64(1, -Infinity);}); + assertFails(function() {writer.writeSint64(1, Infinity);}); + + assertFails(function() {writer.writeFixed32(1, -1);}); + assertFails(function() {writer.writeFixed32(1, Infinity);}); + + assertFails(function() {writer.writeFixed64(1, -1);}); + assertFails(function() {writer.writeFixed64(1, Infinity);}); + + assertFails(function() {writer.writeSfixed32(1, -Infinity);}); + assertFails(function() {writer.writeSfixed32(1, Infinity);}); + + assertFails(function() {writer.writeSfixed64(1, -Infinity);}); + assertFails(function() {writer.writeSfixed64(1, Infinity);}); + }); + + + /** + * Basic test of retrieving the result as a Uint8Array buffer + */ + it('testGetResultBuffer', function() { + var expected = '0864120b48656c6c6f20776f726c641a0301020320c801'; + + var writer = new jspb.BinaryWriter(); + writer.writeUint32(1, 100); + writer.writeString(2, 'Hello world'); + writer.writeBytes(3, new Uint8Array([1, 2, 3])); + writer.writeUint32(4, 200); + + var buffer = writer.getResultBuffer(); + assertEquals(expected, goog.crypt.byteArrayToHex(buffer)); + }); +}); diff --git a/js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto b/js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto new file mode 100644 index 00000000..a060925f --- /dev/null +++ b/js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto @@ -0,0 +1,40 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2016 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "com.google.apps.jspb.proto"; +option java_multiple_files = true; + +package jspb.test.importing; + +message ImportedMessage { + string string_value = 1; +} diff --git a/js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto b/js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto new file mode 100644 index 00000000..f5574a3d --- /dev/null +++ b/js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto @@ -0,0 +1,42 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2016 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_package = "com.google.apps.jspb.proto"; +option java_multiple_files = true; + +package jspb.test.framing; + +import "test6/test6.proto"; + +message FramingMessage { + jspb.test.importing.ImportedMessage imported_message = 1; +} diff --git a/js/compatibility_tests/v3.1.0/data.proto b/js/compatibility_tests/v3.1.0/data.proto new file mode 100644 index 00000000..74a8a994 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/data.proto @@ -0,0 +1,51 @@ +// 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: mwr@google.com (Mark Rawling) + +syntax = "proto2"; + +option java_package = "com.google.apps.jspb.proto"; +option java_multiple_files = true; + +package jspb.test; + +// legacy data, must be nested +message data { + message NestedData { + required string str = 1; + } +} + +// new data, does not require nesting +message UnnestedData { + required string str = 1; +} + diff --git a/js/compatibility_tests/v3.1.0/debug_test.js b/js/compatibility_tests/v3.1.0/debug_test.js new file mode 100644 index 00000000..702cc76e --- /dev/null +++ b/js/compatibility_tests/v3.1.0/debug_test.js @@ -0,0 +1,105 @@ +// 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. + +goog.setTestOnly(); + +goog.require('goog.testing.asserts'); + +// CommonJS-LoadFromFile: google-protobuf +goog.require('jspb.debug'); + +// CommonJS-LoadFromFile: test_pb +goog.require('proto.jspb.test.HasExtensions'); +goog.require('proto.jspb.test.IsExtension'); +goog.require('proto.jspb.test.Simple1'); + + + +describe('debugTest', function() { + it('testSimple1', function() { + if (COMPILED) { + return; + } + var message = new proto.jspb.test.Simple1(); + message.setAString('foo'); + assertObjectEquals({ + $name: 'proto.jspb.test.Simple1', + 'aString': 'foo', + 'aRepeatedStringList': [] + }, jspb.debug.dump(message)); + + message.setABoolean(true); + message.setARepeatedStringList(['1', '2']); + + assertObjectEquals({ + $name: 'proto.jspb.test.Simple1', + 'aString': 'foo', + 'aRepeatedStringList': ['1', '2'], + 'aBoolean': true + }, jspb.debug.dump(message)); + + message.clearAString(); + + assertObjectEquals({ + $name: 'proto.jspb.test.Simple1', + 'aRepeatedStringList': ['1', '2'], + 'aBoolean': true + }, jspb.debug.dump(message)); + }); + + + it('testExtensions', function() { + if (COMPILED) { + return; + } + var extension = new proto.jspb.test.IsExtension(); + extension.setExt1('ext1field'); + var extendable = new proto.jspb.test.HasExtensions(); + extendable.setStr1('v1'); + extendable.setStr2('v2'); + extendable.setStr3('v3'); + extendable.setExtension(proto.jspb.test.IsExtension.extField, extension); + + assertObjectEquals({ + '$name': 'proto.jspb.test.HasExtensions', + 'str1': 'v1', + 'str2': 'v2', + 'str3': 'v3', + '$extensions': { + 'extField': { + '$name': 'proto.jspb.test.IsExtension', + 'ext1': 'ext1field' + }, + 'repeatedSimpleList': [] + } + }, jspb.debug.dump(extendable)); + }); + +}); diff --git a/js/compatibility_tests/v3.1.0/maps_test.js b/js/compatibility_tests/v3.1.0/maps_test.js new file mode 100644 index 00000000..0d442f4f --- /dev/null +++ b/js/compatibility_tests/v3.1.0/maps_test.js @@ -0,0 +1,301 @@ +// 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. + +goog.require('goog.testing.asserts'); +goog.require('goog.userAgent'); + +// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test +goog.require('proto.jspb.test.MapValueEnum'); +goog.require('proto.jspb.test.MapValueMessage'); +goog.require('proto.jspb.test.TestMapFields'); + +// CommonJS-LoadFromFile: test_pb proto.jspb.test +goog.require('proto.jspb.test.MapValueMessageNoBinary'); +goog.require('proto.jspb.test.TestMapFieldsNoBinary'); + +/** + * Helper: check that the given map has exactly this set of (sorted) entries. + * @param {!jspb.Map} map + * @param {!Array<!Array<?>>} entries + */ +function checkMapEquals(map, entries) { + var arr = map.toArray(); + assertEquals(arr.length, entries.length); + for (var i = 0; i < arr.length; i++) { + assertElementsEquals(arr[i], entries[i]); + } +} + +/** + * Converts an ES6 iterator to an array. + * @template T + * @param {!Iterator<T>} iter an iterator + * @return {!Array<T>} + */ +function toArray(iter) { + var arr = []; + while (true) { + var val = iter.next(); + if (val.done) { + break; + } + arr.push(val.value); + } + return arr; +} + + +/** + * Helper: generate test methods for this TestMapFields class. + * @param {?} msgInfo + * @param {?} submessageCtor + * @param {!string} suffix + */ +function makeTests(msgInfo, submessageCtor, suffix) { + /** + * Helper: fill all maps on a TestMapFields. + * @param {?} msg + */ + var fillMapFields = function(msg) { + msg.getMapStringStringMap().set('asdf', 'jkl;').set('key 2', 'hello world'); + msg.getMapStringInt32Map().set('a', 1).set('b', -2); + msg.getMapStringInt64Map().set('c', 0x100000000).set('d', 0x200000000); + msg.getMapStringBoolMap().set('e', true).set('f', false); + msg.getMapStringDoubleMap().set('g', 3.14159).set('h', 2.71828); + msg.getMapStringEnumMap() + .set('i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR) + .set('j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ); + msg.getMapStringMsgMap() + .set('k', new submessageCtor()) + .set('l', new submessageCtor()); + msg.getMapStringMsgMap().get('k').setFoo(42); + msg.getMapStringMsgMap().get('l').setFoo(84); + msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b'); + msg.getMapInt64StringMap().set(0x123456789abc, 'c').set(0xcba987654321, 'd'); + msg.getMapBoolStringMap().set(false, 'e').set(true, 'f'); + }; + + /** + * Helper: check all maps on a TestMapFields. + * @param {?} msg + */ + var checkMapFields = function(msg) { + checkMapEquals(msg.getMapStringStringMap(), [ + ['asdf', 'jkl;'], + ['key 2', 'hello world'] + ]); + checkMapEquals(msg.getMapStringInt32Map(), [ + ['a', 1], + ['b', -2] + ]); + checkMapEquals(msg.getMapStringInt64Map(), [ + ['c', 0x100000000], + ['d', 0x200000000] + ]); + checkMapEquals(msg.getMapStringBoolMap(), [ + ['e', true], + ['f', false] + ]); + checkMapEquals(msg.getMapStringDoubleMap(), [ + ['g', 3.14159], + ['h', 2.71828] + ]); + checkMapEquals(msg.getMapStringEnumMap(), [ + ['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR], + ['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ] + ]); + checkMapEquals(msg.getMapInt32StringMap(), [ + [-1, 'a'], + [42, 'b'] + ]); + checkMapEquals(msg.getMapInt64StringMap(), [ + [0x123456789abc, 'c'], + [0xcba987654321, 'd'] + ]); + checkMapEquals(msg.getMapBoolStringMap(), [ + [false, 'e'], + [true, 'f'] + ]); + + assertEquals(msg.getMapStringMsgMap().getLength(), 2); + assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42); + assertEquals(msg.getMapStringMsgMap().get('l').getFoo(), 84); + + var entries = toArray(msg.getMapStringMsgMap().entries()); + assertEquals(entries.length, 2); + entries.forEach(function(entry) { + var key = entry[0]; + var val = entry[1]; + assert(val === msg.getMapStringMsgMap().get(key)); + }); + + msg.getMapStringMsgMap().forEach(function(val, key) { + assert(val === msg.getMapStringMsgMap().get(key)); + }); + }; + + it('testMapStringStringField' + suffix, function() { + var msg = new msgInfo.constructor(); + assertEquals(msg.getMapStringStringMap().getLength(), 0); + assertEquals(msg.getMapStringInt32Map().getLength(), 0); + assertEquals(msg.getMapStringInt64Map().getLength(), 0); + assertEquals(msg.getMapStringBoolMap().getLength(), 0); + assertEquals(msg.getMapStringDoubleMap().getLength(), 0); + assertEquals(msg.getMapStringEnumMap().getLength(), 0); + assertEquals(msg.getMapStringMsgMap().getLength(), 0); + + // Re-create to clear out any internally-cached wrappers, etc. + msg = new msgInfo.constructor(); + var m = msg.getMapStringStringMap(); + assertEquals(m.has('asdf'), false); + assertEquals(m.get('asdf'), undefined); + m.set('asdf', 'hello world'); + assertEquals(m.has('asdf'), true); + assertEquals(m.get('asdf'), 'hello world'); + m.set('jkl;', 'key 2'); + assertEquals(m.has('jkl;'), true); + assertEquals(m.get('jkl;'), 'key 2'); + assertEquals(m.getLength(), 2); + var it = m.entries(); + assertElementsEquals(it.next().value, ['asdf', 'hello world']); + assertElementsEquals(it.next().value, ['jkl;', 'key 2']); + assertEquals(it.next().done, true); + checkMapEquals(m, [ + ['asdf', 'hello world'], + ['jkl;', 'key 2'] + ]); + m.del('jkl;'); + assertEquals(m.has('jkl;'), false); + assertEquals(m.get('jkl;'), undefined); + assertEquals(m.getLength(), 1); + it = m.keys(); + assertEquals(it.next().value, 'asdf'); + assertEquals(it.next().done, true); + it = m.values(); + assertEquals(it.next().value, 'hello world'); + assertEquals(it.next().done, true); + + var count = 0; + m.forEach(function(value, key, map) { + assertEquals(map, m); + assertEquals(key, 'asdf'); + assertEquals(value, 'hello world'); + count++; + }); + assertEquals(count, 1); + + m.clear(); + assertEquals(m.getLength(), 0); + }); + + + /** + * Tests operations on maps with all key and value types. + */ + it('testAllMapTypes' + suffix, function() { + var msg = new msgInfo.constructor(); + fillMapFields(msg); + checkMapFields(msg); + }); + + + if (msgInfo.deserializeBinary) { + /** + * Tests serialization and deserialization in binary format. + */ + it('testBinaryFormat' + suffix, function() { + if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) { + // IE8/9 currently doesn't support binary format because they lack + // TypedArray. + return; + } + + // Check that the format is correct. + var msg = new msgInfo.constructor(); + msg.getMapStringStringMap().set('A', 'a'); + var serialized = msg.serializeBinary(); + var expectedSerialized = [ + 0x0a, 0x6, // field 1 (map_string_string), delimited, length 6 + 0x0a, 0x1, // field 1 in submessage (key), delimited, length 1 + 0x41, // ASCII 'A' + 0x12, 0x1, // field 2 in submessage (value), delimited, length 1 + 0x61 // ASCII 'a' + ]; + assertEquals(serialized.length, expectedSerialized.length); + for (var i = 0; i < serialized.length; i++) { + assertEquals(serialized[i], expectedSerialized[i]); + } + + // Check that all map fields successfully round-trip. + msg = new msgInfo.constructor(); + fillMapFields(msg); + serialized = msg.serializeBinary(); + var decoded = msgInfo.deserializeBinary(serialized); + checkMapFields(decoded); + }); + } + + /** + * Exercises the lazy map<->underlying array sync. + */ + it('testLazyMapSync' + suffix, function() { + // Start with a JSPB array containing a few map entries. + var entries = [ + ['a', 'entry 1'], + ['c', 'entry 2'], + ['b', 'entry 3'] + ]; + var msg = new msgInfo.constructor([entries]); + assertEquals(entries.length, 3); + assertEquals(entries[0][0], 'a'); + assertEquals(entries[1][0], 'c'); + assertEquals(entries[2][0], 'b'); + msg.getMapStringStringMap().del('a'); + assertEquals(entries.length, 3); // not yet sync'd + msg.toArray(); // force a sync + assertEquals(entries.length, 2); + assertEquals(entries[0][0], 'b'); // now in sorted order + assertEquals(entries[1][0], 'c'); + + var a = msg.toArray(); + assertEquals(a[0], entries); // retains original reference + }); +} + +describe('mapsTest', function() { + makeTests({ + constructor: proto.jspb.test.TestMapFields, + deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary + }, proto.jspb.test.MapValueMessage, "_Binary"); + makeTests({ + constructor: proto.jspb.test.TestMapFieldsNoBinary, + deserializeBinary: null + }, proto.jspb.test.MapValueMessageNoBinary, "_NoBinary"); +}); diff --git a/js/compatibility_tests/v3.1.0/message_test.js b/js/compatibility_tests/v3.1.0/message_test.js new file mode 100644 index 00000000..b46e50d3 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/message_test.js @@ -0,0 +1,1037 @@ +// 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. + +// Test suite is written using Jasmine -- see http://jasmine.github.io/ + +goog.setTestOnly(); + +goog.require('goog.json'); +goog.require('goog.testing.asserts'); +goog.require('goog.userAgent'); + +// CommonJS-LoadFromFile: google-protobuf jspb +goog.require('jspb.Message'); + +// CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta +goog.require('proto.jspb.exttest.beta.floatingStrField'); + +// CommonJS-LoadFromFile: test3_pb proto.jspb.exttest +goog.require('proto.jspb.exttest.floatingMsgField'); + +// CommonJS-LoadFromFile: test4_pb proto.jspb.exttest +goog.require('proto.jspb.exttest.floatingMsgFieldTwo'); + +// CommonJS-LoadFromFile: test_pb proto.jspb.test +goog.require('proto.jspb.test.CloneExtension'); +goog.require('proto.jspb.test.Complex'); +goog.require('proto.jspb.test.DefaultValues'); +goog.require('proto.jspb.test.Empty'); +goog.require('proto.jspb.test.EnumContainer'); +goog.require('proto.jspb.test.floatingMsgField'); +goog.require('proto.jspb.test.FloatingPointFields'); +goog.require('proto.jspb.test.floatingStrField'); +goog.require('proto.jspb.test.HasExtensions'); +goog.require('proto.jspb.test.IndirectExtension'); +goog.require('proto.jspb.test.IsExtension'); +goog.require('proto.jspb.test.OptionalFields'); +goog.require('proto.jspb.test.OuterEnum'); +goog.require('proto.jspb.test.OuterMessage.Complex'); +goog.require('proto.jspb.test.Simple1'); +goog.require('proto.jspb.test.Simple2'); +goog.require('proto.jspb.test.SpecialCases'); +goog.require('proto.jspb.test.TestClone'); +goog.require('proto.jspb.test.TestEndsWithBytes'); +goog.require('proto.jspb.test.TestGroup'); +goog.require('proto.jspb.test.TestGroup1'); +goog.require('proto.jspb.test.TestMessageWithOneof'); +goog.require('proto.jspb.test.TestReservedNames'); +goog.require('proto.jspb.test.TestReservedNamesExtension'); + +// CommonJS-LoadFromFile: test2_pb proto.jspb.test +goog.require('proto.jspb.test.ExtensionMessage'); +goog.require('proto.jspb.test.TestExtensionsMessage'); + + + + +describe('Message test suite', function() { + it('testEmptyProto', function() { + var empty1 = new proto.jspb.test.Empty([]); + var empty2 = new proto.jspb.test.Empty([]); + assertObjectEquals({}, empty1.toObject()); + assertObjectEquals('Message should not be corrupted:', empty2, empty1); + }); + + it('testTopLevelEnum', function() { + var response = new proto.jspb.test.EnumContainer([]); + response.setOuterEnum(proto.jspb.test.OuterEnum.FOO); + assertEquals(proto.jspb.test.OuterEnum.FOO, response.getOuterEnum()); + }); + + it('testByteStrings', function() { + var data = new proto.jspb.test.DefaultValues([]); + data.setBytesField('some_bytes'); + assertEquals('some_bytes', data.getBytesField()); + }); + + it('testComplexConversion', function() { + var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1]; + var data2 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1]; + var foo = new proto.jspb.test.Complex(data1); + var bar = new proto.jspb.test.Complex(data2); + var result = foo.toObject(); + assertObjectEquals({ + aString: 'a', + anOutOfOrderBool: 1, + aNestedMessage: { + anInt: 11 + }, + aRepeatedMessageList: [{anInt: 22}, {anInt: 33}], + aRepeatedStringList: ['s1', 's2'] + }, result); + + // Now test with the jspb instances included. + result = foo.toObject(true /* opt_includeInstance */); + assertObjectEquals({ + aString: 'a', + anOutOfOrderBool: 1, + aNestedMessage: { + anInt: 11, + $jspbMessageInstance: foo.getANestedMessage() + }, + aRepeatedMessageList: [ + {anInt: 22, $jspbMessageInstance: foo.getARepeatedMessageList()[0]}, + {anInt: 33, $jspbMessageInstance: foo.getARepeatedMessageList()[1]} + ], + aRepeatedStringList: ['s1', 's2'], + $jspbMessageInstance: foo + }, result); + + }); + + it('testMissingFields', function() { + var foo = new proto.jspb.test.Complex([ + undefined, undefined, undefined, [], + undefined, undefined, undefined, undefined]); + var bar = new proto.jspb.test.Complex([ + undefined, undefined, undefined, [], + undefined, undefined, undefined, undefined]); + var result = foo.toObject(); + assertObjectEquals({ + aString: undefined, + anOutOfOrderBool: undefined, + aNestedMessage: { + anInt: undefined + }, + // Note: JsPb converts undefined repeated fields to empty arrays. + aRepeatedMessageList: [], + aRepeatedStringList: [] + }, result); + + }); + + it('testNestedComplexMessage', function() { + // Instantiate the message and set a unique field, just to ensure that we + // are not getting jspb.test.Complex instead. + var msg = new proto.jspb.test.OuterMessage.Complex(); + msg.setInnerComplexField(5); + }); + + it('testSpecialCases', function() { + // Note: Some property names are reserved in JavaScript. + // These names are converted to the Js property named pb_<reserved_name>. + var special = + new proto.jspb.test.SpecialCases(['normal', 'default', 'function', + 'var']); + var result = special.toObject(); + assertObjectEquals({ + normal: 'normal', + pb_default: 'default', + pb_function: 'function', + pb_var: 'var' + }, result); + }); + + it('testDefaultValues', function() { + var defaultString = "default<>\'\"abc"; + var response = new proto.jspb.test.DefaultValues(); + + // Test toObject + var expectedObject = { + stringField: defaultString, + boolField: true, + intField: 11, + enumField: 13, + emptyField: '', + bytesField: 'bW9v' + }; + assertObjectEquals(expectedObject, response.toObject()); + + + // Test getters + response = new proto.jspb.test.DefaultValues(); + assertEquals(defaultString, response.getStringField()); + assertEquals(true, response.getBoolField()); + assertEquals(11, response.getIntField()); + assertEquals(13, response.getEnumField()); + assertEquals('', response.getEmptyField()); + assertEquals('bW9v', response.getBytesField()); + + function makeDefault(values) { + return new proto.jspb.test.DefaultValues(values); + } + + // Test with undefined values, + // Use push to workaround IE treating undefined array elements as holes. + response = makeDefault([undefined, undefined, undefined, undefined]); + assertEquals(defaultString, response.getStringField()); + assertEquals(true, response.getBoolField()); + assertEquals(11, response.getIntField()); + assertEquals(13, response.getEnumField()); + assertFalse(response.hasStringField()); + assertFalse(response.hasBoolField()); + assertFalse(response.hasIntField()); + assertFalse(response.hasEnumField()); + + // Test with null values, as would be returned by a JSON serializer. + response = makeDefault([null, null, null, null]); + assertEquals(defaultString, response.getStringField()); + assertEquals(true, response.getBoolField()); + assertEquals(11, response.getIntField()); + assertEquals(13, response.getEnumField()); + assertFalse(response.hasStringField()); + assertFalse(response.hasBoolField()); + assertFalse(response.hasIntField()); + assertFalse(response.hasEnumField()); + + // Test with false-like values. + response = makeDefault(['', false, 0, 0]); + assertEquals('', response.getStringField()); + assertEquals(false, response.getBoolField()); + assertEquals(true, response.getIntField() == 0); + assertEquals(true, response.getEnumField() == 0); + assertTrue(response.hasStringField()); + assertTrue(response.hasBoolField()); + assertTrue(response.hasIntField()); + assertTrue(response.hasEnumField()); + + // Test that clearing the values reverts them to the default state. + response = makeDefault(['blah', false, 111, 77]); + response.clearStringField(); response.clearBoolField(); + response.clearIntField(); response.clearEnumField(); + assertEquals(defaultString, response.getStringField()); + assertEquals(true, response.getBoolField()); + assertEquals(11, response.getIntField()); + assertEquals(13, response.getEnumField()); + assertFalse(response.hasStringField()); + assertFalse(response.hasBoolField()); + assertFalse(response.hasIntField()); + assertFalse(response.hasEnumField()); + + // Test that setFoo(null) clears the values. + response = makeDefault(['blah', false, 111, 77]); + response.setStringField(null); response.setBoolField(null); + response.setIntField(undefined); response.setEnumField(undefined); + assertEquals(defaultString, response.getStringField()); + assertEquals(true, response.getBoolField()); + assertEquals(11, response.getIntField()); + assertEquals(13, response.getEnumField()); + assertFalse(response.hasStringField()); + assertFalse(response.hasBoolField()); + assertFalse(response.hasIntField()); + assertFalse(response.hasEnumField()); + }); + + it('testClearFields', function() { + var data = ['str', true, [11], [[22], [33]], ['s1', 's2']]; + var foo = new proto.jspb.test.OptionalFields(data); + foo.clearAString(); + foo.clearABool(); + foo.clearANestedMessage(); + foo.clearARepeatedMessageList(); + foo.clearARepeatedStringList(); + assertEquals('', foo.getAString()); + assertEquals(false, foo.getABool()); + assertUndefined(foo.getANestedMessage()); + assertFalse(foo.hasAString()); + assertFalse(foo.hasABool()); + assertObjectEquals([], foo.getARepeatedMessageList()); + assertObjectEquals([], foo.getARepeatedStringList()); + // NOTE: We want the missing fields in 'expected' to be undefined, + // but we actually get a sparse array instead. We could use something + // like [1,undefined,2] to avoid this, except that this is still + // sparse on IE. No comment... + var expected = [,,, [], []]; + expected[0] = expected[1] = expected[2] = undefined; + assertObjectEquals(expected, foo.toArray()); + }); + + it('testDifferenceRawObject', /** @suppress {visibility} */ function() { + var p1 = new proto.jspb.test.HasExtensions(['hi', 'diff', {}]); + var p2 = new proto.jspb.test.HasExtensions(['hi', 'what', + {1000: 'unique'}]); + var diff = /** @type {proto.jspb.test.HasExtensions} */ + (jspb.Message.difference(p1, p2)); + assertEquals('', diff.getStr1()); + assertEquals('what', diff.getStr2()); + assertEquals('', diff.getStr3()); + assertEquals('unique', diff.extensionObject_[1000]); + }); + + it('testEqualsSimple', function() { + var s1 = new proto.jspb.test.Simple1(['hi']); + assertTrue(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi']))); + assertFalse(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['bye']))); + var s1b = new proto.jspb.test.Simple1(['hi', ['hello']]); + assertTrue(jspb.Message.equals(s1b, + new proto.jspb.test.Simple1(['hi', ['hello']]))); + assertTrue(jspb.Message.equals(s1b, + new proto.jspb.test.Simple1(['hi', ['hello', undefined, + undefined, undefined]]))); + assertFalse(jspb.Message.equals(s1b, + new proto.jspb.test.Simple1(['no', ['hello']]))); + // Test with messages of different types + var s2 = new proto.jspb.test.Simple2(['hi']); + assertFalse(jspb.Message.equals(s1, s2)); + }); + + it('testEquals_softComparison', function() { + var s1 = new proto.jspb.test.Simple1(['hi', [], null]); + assertTrue(jspb.Message.equals(s1, + new proto.jspb.test.Simple1(['hi', []]))); + + var s1b = new proto.jspb.test.Simple1(['hi', [], true]); + assertTrue(jspb.Message.equals(s1b, + new proto.jspb.test.Simple1(['hi', [], 1]))); + }); + + it('testEqualsComplex', function() { + var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1]; + var data2 = ['a',,, [, 11], [[, 22], [, 34]],, ['s1', 's2'],, 1]; + var data3 = ['a',,, [, 11], [[, 22]],, ['s1', 's2'],, 1]; + var data4 = ['hi']; + var c1a = new proto.jspb.test.Complex(data1); + var c1b = new proto.jspb.test.Complex(data1); + var c2 = new proto.jspb.test.Complex(data2); + var c3 = new proto.jspb.test.Complex(data3); + var s1 = new proto.jspb.test.Simple1(data4); + + assertTrue(jspb.Message.equals(c1a, c1b)); + assertFalse(jspb.Message.equals(c1a, c2)); + assertFalse(jspb.Message.equals(c2, c3)); + assertFalse(jspb.Message.equals(c1a, s1)); + }); + + it('testEqualsExtensionsConstructed', function() { + assertTrue(jspb.Message.equals( + new proto.jspb.test.HasExtensions([]), + new proto.jspb.test.HasExtensions([{}]) + )); + assertTrue(jspb.Message.equals( + new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), + new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]) + )); + assertFalse(jspb.Message.equals( + new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), + new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}]) + )); + assertTrue(jspb.Message.equals( + new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]), + new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]) + )); + assertTrue(jspb.Message.equals( + new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]), + new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}]) + )); + assertTrue(jspb.Message.equals( + new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}]), + new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]) + )); + assertTrue(jspb.Message.equals( + new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), + new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}]) + )); + assertTrue(jspb.Message.equals( + new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}]), + new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]) + )); + }); + + it('testEqualsExtensionsUnconstructed', function() { + assertTrue(jspb.Message.compareFields([], [{}])); + assertTrue(jspb.Message.compareFields([,,, {}], [])); + assertTrue(jspb.Message.compareFields([,,, {}], [,, {}])); + assertTrue(jspb.Message.compareFields( + ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}])); + assertFalse(jspb.Message.compareFields( + ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'b'}]}])); + assertTrue(jspb.Message.compareFields( + [{100: [{200: 'a'}]}], [{100: [{200: 'a'}]}])); + assertTrue(jspb.Message.compareFields( + [{100: [{200: 'a'}]}], [,,, {100: [{200: 'a'}]}])); + assertTrue(jspb.Message.compareFields( + [,,, {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}])); + assertTrue(jspb.Message.compareFields( + ['hi', {100: [{200: 'a'}]}], ['hi',,, {100: [{200: 'a'}]}])); + assertTrue(jspb.Message.compareFields( + ['hi',,, {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}])); + }); + + it('testToMap', function() { + var p1 = new proto.jspb.test.Simple1(['k', ['v']]); + var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]); + var soymap = jspb.Message.toMap([p1, p2], + proto.jspb.test.Simple1.prototype.getAString, + proto.jspb.test.Simple1.prototype.toObject); + assertEquals('k', soymap['k'].aString); + assertArrayEquals(['v'], soymap['k'].aRepeatedStringList); + var protomap = jspb.Message.toMap([p1, p2], + proto.jspb.test.Simple1.prototype.getAString); + assertEquals('k', protomap['k'].getAString()); + assertArrayEquals(['v'], protomap['k'].getARepeatedStringList()); + }); + + it('testClone', function() { + var supportsUint8Array = + !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'); + var original = new proto.jspb.test.TestClone(); + original.setStr('v1'); + var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]); + var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]); + var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]); + original.setSimple1(simple1); + original.setSimple2List([simple2, simple3]); + var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123'; + original.setBytesField(bytes1); + var extension = new proto.jspb.test.CloneExtension(); + extension.setExt('e1'); + original.setExtension(proto.jspb.test.IsExtension.extField, extension); + var clone = original.clone(); + assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],, + [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }], + clone.toArray()); + clone.setStr('v2'); + var simple4 = new proto.jspb.test.Simple1(['a1', ['b1', 'c1']]); + var simple5 = new proto.jspb.test.Simple1(['a2', ['b2', 'c2']]); + var simple6 = new proto.jspb.test.Simple1(['a3', ['b3', 'c3']]); + clone.setSimple1(simple4); + clone.setSimple2List([simple5, simple6]); + if (supportsUint8Array) { + clone.getBytesField()[0] = 4; + assertObjectEquals(bytes1, original.getBytesField()); + } + var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456'; + clone.setBytesField(bytes2); + var newExtension = new proto.jspb.test.CloneExtension(); + newExtension.setExt('e2'); + clone.setExtension(proto.jspb.test.CloneExtension.extField, newExtension); + assertArrayEquals(['v2',, ['a1', ['b1', 'c1']],, + [['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]], bytes2,, { 100: [, 'e2'] }], + clone.toArray()); + assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],, + [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }], + original.toArray()); + }); + + it('testCopyInto', function() { + var supportsUint8Array = + !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'); + var original = new proto.jspb.test.TestClone(); + original.setStr('v1'); + var dest = new proto.jspb.test.TestClone(); + dest.setStr('override'); + var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]); + var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]); + var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]); + var destSimple1 = new proto.jspb.test.Simple1(['ox1', ['oy1', 'oz1']]); + var destSimple2 = new proto.jspb.test.Simple1(['ox2', ['oy2', 'oz2']]); + var destSimple3 = new proto.jspb.test.Simple1(['ox3', ['oy3', 'oz3']]); + original.setSimple1(simple1); + original.setSimple2List([simple2, simple3]); + dest.setSimple1(destSimple1); + dest.setSimple2List([destSimple2, destSimple3]); + var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123'; + var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456'; + original.setBytesField(bytes1); + dest.setBytesField(bytes2); + var extension = new proto.jspb.test.CloneExtension(); + extension.setExt('e1'); + original.setExtension(proto.jspb.test.CloneExtension.extField, extension); + + jspb.Message.copyInto(original, dest); + assertArrayEquals(original.toArray(), dest.toArray()); + assertEquals('x1', dest.getSimple1().getAString()); + assertEquals('e1', + dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt()); + dest.getSimple1().setAString('new value'); + assertNotEquals(dest.getSimple1().getAString(), + original.getSimple1().getAString()); + if (supportsUint8Array) { + dest.getBytesField()[0] = 7; + assertObjectEquals(bytes1, original.getBytesField()); + assertObjectEquals(new Uint8Array([7, 2, 3]), dest.getBytesField()); + } else { + dest.setBytesField('789'); + assertObjectEquals(bytes1, original.getBytesField()); + assertObjectEquals('789', dest.getBytesField()); + } + dest.getExtension(proto.jspb.test.CloneExtension.extField). + setExt('new value'); + assertNotEquals( + dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt(), + original.getExtension( + proto.jspb.test.CloneExtension.extField).getExt()); + }); + + it('testCopyInto_notSameType', function() { + var a = new proto.jspb.test.TestClone(); + var b = new proto.jspb.test.Simple1(['str', ['s1', 's2']]); + + var e = assertThrows(function() { + jspb.Message.copyInto(a, b); + }); + assertContains('should have the same type', e.message); + }); + + it('testExtensions', function() { + var extension1 = new proto.jspb.test.IsExtension(['ext1field']); + var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2']]); + var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); + extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1); + extendable.setExtension(proto.jspb.test.IndirectExtension.simple, + extension2); + extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy'); + extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList, + ['a', 'b']); + var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]); + var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2']]); + extendable.setExtension( + proto.jspb.test.IndirectExtension.repeatedSimpleList, + [s1, s2]); + assertObjectEquals(extension1, + extendable.getExtension(proto.jspb.test.IsExtension.extField)); + assertObjectEquals(extension2, + extendable.getExtension(proto.jspb.test.IndirectExtension.simple)); + assertObjectEquals('xyzzy', + extendable.getExtension(proto.jspb.test.IndirectExtension.str)); + assertObjectEquals(['a', 'b'], extendable.getExtension( + proto.jspb.test.IndirectExtension.repeatedStrList)); + assertObjectEquals([s1, s2], extendable.getExtension( + proto.jspb.test.IndirectExtension.repeatedSimpleList)); + // Not supported yet, but it should work... + extendable.setExtension(proto.jspb.test.IndirectExtension.simple, null); + assertNull( + extendable.getExtension(proto.jspb.test.IndirectExtension.simple)); + extendable.setExtension(proto.jspb.test.IndirectExtension.str, null); + assertNull(extendable.getExtension(proto.jspb.test.IndirectExtension.str)); + + + // Extension fields with jspb.ignore = true are ignored. + assertUndefined(proto.jspb.test.IndirectExtension['ignored']); + assertUndefined(proto.jspb.test.HasExtensions['ignoredFloating']); + }); + + it('testFloatingExtensions', function() { + // From an autogenerated container. + var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); + var extension = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]); + extendable.setExtension(proto.jspb.test.simple1, extension); + assertObjectEquals(extension, + extendable.getExtension(proto.jspb.test.simple1)); + + // From _lib mode. + extension = new proto.jspb.test.ExtensionMessage(['s1']); + extendable = new proto.jspb.test.TestExtensionsMessage([16]); + extendable.setExtension(proto.jspb.test.floatingMsgField, extension); + extendable.setExtension(proto.jspb.test.floatingStrField, 's2'); + assertObjectEquals(extension, + extendable.getExtension(proto.jspb.test.floatingMsgField)); + assertObjectEquals('s2', + extendable.getExtension(proto.jspb.test.floatingStrField)); + assertNotUndefined(proto.jspb.exttest.floatingMsgField); + assertNotUndefined(proto.jspb.exttest.floatingMsgFieldTwo); + assertNotUndefined(proto.jspb.exttest.beta.floatingStrField); + }); + + it('testToObject_extendedObject', function() { + var extension1 = new proto.jspb.test.IsExtension(['ext1field']); + var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2'], true]); + var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); + extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1); + extendable.setExtension(proto.jspb.test.IndirectExtension.simple, + extension2); + extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy'); + extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList, + ['a', 'b']); + var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2'], true]); + var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2'], false]); + extendable.setExtension( + proto.jspb.test.IndirectExtension.repeatedSimpleList, + [s1, s2]); + assertObjectEquals({ + str1: 'v1', str2: 'v2', str3: 'v3', + extField: { ext1: 'ext1field' }, + simple: { + aString: 'str', aRepeatedStringList: ['s1', 's2'], aBoolean: true + }, + str: 'xyzzy', + repeatedStrList: ['a', 'b'], + repeatedSimpleList: [ + { aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true}, + { aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false} + ] + }, extendable.toObject()); + + // Now, with instances included. + assertObjectEquals({ + str1: 'v1', str2: 'v2', str3: 'v3', + extField: { + ext1: 'ext1field', + $jspbMessageInstance: + extendable.getExtension(proto.jspb.test.IsExtension.extField) + }, + simple: { + aString: 'str', + aRepeatedStringList: ['s1', 's2'], + aBoolean: true, + $jspbMessageInstance: + extendable.getExtension(proto.jspb.test.IndirectExtension.simple) + }, + str: 'xyzzy', + repeatedStrList: ['a', 'b'], + repeatedSimpleList: [{ + aString: 'foo', + aRepeatedStringList: ['s1', 's2'], + aBoolean: true, + $jspbMessageInstance: s1 + }, { + aString: 'bar', + aRepeatedStringList: ['t1', 't2'], + aBoolean: false, + $jspbMessageInstance: s2 + }], + $jspbMessageInstance: extendable + }, extendable.toObject(true /* opt_includeInstance */)); + }); + + it('testInitialization_emptyArray', function() { + var msg = new proto.jspb.test.HasExtensions([]); + if (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) { + assertArrayEquals([], msg.toArray()); + } else { + // Extension object is created past all regular fields. + assertArrayEquals([,,, {}], msg.toArray()); + } + }); + + it('testInitialization_justExtensionObject', function() { + var msg = new proto.jspb.test.Empty([{1: 'hi'}]); + // The extensionObject is not moved from its original location. + assertArrayEquals([{1: 'hi'}], msg.toArray()); + }); + + it('testInitialization_incompleteList', function() { + var msg = new proto.jspb.test.Empty([1, {4: 'hi'}]); + // The extensionObject is not moved from its original location. + assertArrayEquals([1, {4: 'hi'}], msg.toArray()); + }); + + it('testInitialization_forwardCompatible', function() { + var msg = new proto.jspb.test.Empty([1, 2, 3, {1: 'hi'}]); + assertArrayEquals([1, 2, 3, {1: 'hi'}], msg.toArray()); + }); + + it('testExtendedMessageEnsureObject', + /** @suppress {visibility} */ function() { + var data = + new proto.jspb.test.HasExtensions(['str1', {'a_key': 'an_object'}]); + assertEquals('an_object', data.extensionObject_['a_key']); + }); + + it('testToObject_hasExtensionField', function() { + var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]); + var obj = data.toObject(); + assertEquals('str1', obj.str1); + assertEquals('ext1', obj.extField.ext1); + }); + + it('testGetExtension', function() { + var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]); + assertEquals('str1', data.getStr1()); + var extension = data.getExtension(proto.jspb.test.IsExtension.extField); + assertNotNull(extension); + assertEquals('ext1', extension.getExt1()); + }); + + it('testSetExtension', function() { + var data = new proto.jspb.test.HasExtensions(); + var extensionMessage = new proto.jspb.test.IsExtension(['is_extension']); + data.setExtension(proto.jspb.test.IsExtension.extField, extensionMessage); + var obj = data.toObject(); + assertNotNull( + data.getExtension(proto.jspb.test.IsExtension.extField)); + assertEquals('is_extension', obj.extField.ext1); + }); + + /** + * Note that group is long deprecated, we only support it because JsPb has + * a goal of being able to generate JS classes for all proto descriptors. + */ + it('testGroups', function() { + var group = new proto.jspb.test.TestGroup(); + var someGroup = new proto.jspb.test.TestGroup.RepeatedGroup(); + someGroup.setId('g1'); + someGroup.setSomeBoolList([true, false]); + group.setRepeatedGroupList([someGroup]); + var groups = group.getRepeatedGroupList(); + assertEquals('g1', groups[0].getId()); + assertObjectEquals([true, false], groups[0].getSomeBoolList()); + assertObjectEquals({id: 'g1', someBoolList: [true, false]}, + groups[0].toObject()); + assertObjectEquals({ + repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}], + requiredGroup: {id: undefined}, + optionalGroup: undefined, + requiredSimple: {aRepeatedStringList: [], aString: undefined}, + optionalSimple: undefined, + id: undefined + }, group.toObject()); + var group1 = new proto.jspb.test.TestGroup1(); + group1.setGroup(someGroup); + assertEquals(someGroup, group1.getGroup()); + }); + + it('testNonExtensionFieldsAfterExtensionRange', function() { + var data = [{'1': 'a_string'}]; + var message = new proto.jspb.test.Complex(data); + assertArrayEquals([], message.getARepeatedStringList()); + }); + + it('testReservedGetterNames', function() { + var message = new proto.jspb.test.TestReservedNames(); + message.setExtension$(11); + message.setExtension(proto.jspb.test.TestReservedNamesExtension.foo, 12); + assertEquals(11, message.getExtension$()); + assertEquals(12, message.getExtension( + proto.jspb.test.TestReservedNamesExtension.foo)); + assertObjectEquals({extension: 11, foo: 12}, message.toObject()); + }); + + it('testInitializeMessageWithUnsetOneof', function() { + var message = new proto.jspb.test.TestMessageWithOneof([]); + assertEquals( + proto.jspb.test.TestMessageWithOneof.PartialOneofCase. + PARTIAL_ONEOF_NOT_SET, + message.getPartialOneofCase()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase. + RECURSIVE_ONEOF_NOT_SET, + message.getRecursiveOneofCase()); + }); + + it('testInitializeMessageWithSingleValueSetInOneof', function() { + var message = new proto.jspb.test.TestMessageWithOneof([,, 'x']); + + assertEquals('x', message.getPone()); + assertEquals('', message.getPthree()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, + message.getPartialOneofCase()); + }); + + it('testKeepsLastWireValueSetInUnion_multipleValues', function() { + var message = new proto.jspb.test.TestMessageWithOneof([,, 'x',, 'y']); + + assertEquals('', message.getPone()); + assertEquals('y', message.getPthree()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE, + message.getPartialOneofCase()); + }); + + it('testSettingOneofFieldClearsOthers', function() { + var message = new proto.jspb.test.TestMessageWithOneof; + assertEquals('', message.getPone()); + assertEquals('', message.getPthree()); + assertFalse(message.hasPone()); + assertFalse(message.hasPthree()); + + message.setPone('hi'); + assertEquals('hi', message.getPone()); + assertEquals('', message.getPthree()); + assertTrue(message.hasPone()); + assertFalse(message.hasPthree()); + + message.setPthree('bye'); + assertEquals('', message.getPone()); + assertEquals('bye', message.getPthree()); + assertFalse(message.hasPone()); + assertTrue(message.hasPthree()); + }); + + it('testSettingOneofFieldDoesNotClearFieldsFromOtherUnions', function() { + var other = new proto.jspb.test.TestMessageWithOneof; + var message = new proto.jspb.test.TestMessageWithOneof; + assertEquals('', message.getPone()); + assertEquals('', message.getPthree()); + assertUndefined(message.getRone()); + assertFalse(message.hasPone()); + assertFalse(message.hasPthree()); + + message.setPone('hi'); + message.setRone(other); + assertEquals('hi', message.getPone()); + assertEquals('', message.getPthree()); + assertEquals(other, message.getRone()); + assertTrue(message.hasPone()); + assertFalse(message.hasPthree()); + + message.setPthree('bye'); + assertEquals('', message.getPone()); + assertEquals('bye', message.getPthree()); + assertEquals(other, message.getRone()); + assertFalse(message.hasPone()); + assertTrue(message.hasPthree()); + }); + + it('testUnsetsOneofCaseWhenFieldIsCleared', function() { + var message = new proto.jspb.test.TestMessageWithOneof; + assertEquals( + proto.jspb.test.TestMessageWithOneof.PartialOneofCase. + PARTIAL_ONEOF_NOT_SET, + message.getPartialOneofCase()); + + message.setPone('hi'); + assertEquals( + proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, + message.getPartialOneofCase()); + + message.clearPone(); + assertEquals( + proto.jspb.test.TestMessageWithOneof.PartialOneofCase. + PARTIAL_ONEOF_NOT_SET, + message.getPartialOneofCase()); + }); + + it('testMessageWithDefaultOneofValues', function() { + var message = new proto.jspb.test.TestMessageWithOneof; + assertEquals(1234, message.getAone()); + assertEquals(0, message.getAtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofACase + .DEFAULT_ONEOF_A_NOT_SET, + message.getDefaultOneofACase()); + + message.setAone(567); + assertEquals(567, message.getAone()); + assertEquals(0, message.getAtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE, + message.getDefaultOneofACase()); + + message.setAtwo(890); + assertEquals(1234, message.getAone()); + assertEquals(890, message.getAtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO, + message.getDefaultOneofACase()); + + message.clearAtwo(); + assertEquals(1234, message.getAone()); + assertEquals(0, message.getAtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofACase + .DEFAULT_ONEOF_A_NOT_SET, + message.getDefaultOneofACase()); + }); + + it('testMessageWithDefaultOneofValues_defaultNotOnFirstField', function() { + var message = new proto.jspb.test.TestMessageWithOneof; + assertEquals(0, message.getBone()); + assertEquals(1234, message.getBtwo()); + assertFalse(message.hasBone()); + assertFalse(message.hasBtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase + .DEFAULT_ONEOF_B_NOT_SET, + message.getDefaultOneofBCase()); + + message.setBone(2); + assertEquals(2, message.getBone()); + assertEquals(1234, message.getBtwo()); + assertTrue(message.hasBone()); + assertFalse(message.hasBtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE, + message.getDefaultOneofBCase()); + + message.setBtwo(3); + assertEquals(0, message.getBone()); + assertFalse(message.hasBone()); + assertTrue(message.hasBtwo()); + assertEquals(3, message.getBtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, + message.getDefaultOneofBCase()); + + message.clearBtwo(); + assertEquals(0, message.getBone()); + assertFalse(message.hasBone()); + assertFalse(message.hasBtwo()); + assertEquals(1234, message.getBtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase + .DEFAULT_ONEOF_B_NOT_SET, + message.getDefaultOneofBCase()); + }); + + it('testInitializeMessageWithOneofDefaults', function() { + var message = + new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567)); + assertEquals(567, message.getAone()); + assertEquals(0, message.getAtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE, + message.getDefaultOneofACase()); + + message = + new proto.jspb.test.TestMessageWithOneof(new Array(10).concat(890)); + assertEquals(1234, message.getAone()); + assertEquals(890, message.getAtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO, + message.getDefaultOneofACase()); + + message = + new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567, 890)); + assertEquals(1234, message.getAone()); + assertEquals(890, message.getAtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO, + message.getDefaultOneofACase()); + }); + + it('testInitializeMessageWithOneofDefaults_defaultNotSetOnFirstField', + function() { + var message; + + message = + new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567)); + assertEquals(567, message.getBone()); + assertEquals(1234, message.getBtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE, + message.getDefaultOneofBCase()); + + message = + new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890)); + assertEquals(0, message.getBone()); + assertEquals(890, message.getBtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, + message.getDefaultOneofBCase()); + + message = new proto.jspb.test.TestMessageWithOneof( + new Array(11).concat(567, 890)); + assertEquals(0, message.getBone()); + assertEquals(890, message.getBtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, + message.getDefaultOneofBCase()); + }); + + it('testOneofContainingAnotherMessage', function() { + var message = new proto.jspb.test.TestMessageWithOneof; + assertEquals( + proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase. + RECURSIVE_ONEOF_NOT_SET, + message.getRecursiveOneofCase()); + + var other = new proto.jspb.test.TestMessageWithOneof; + message.setRone(other); + assertEquals(other, message.getRone()); + assertEquals('', message.getRtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RONE, + message.getRecursiveOneofCase()); + + message.setRtwo('hi'); + assertUndefined(message.getRone()); + assertEquals('hi', message.getRtwo()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RTWO, + message.getRecursiveOneofCase()); + }); + + it('testQueryingOneofCaseEnsuresOnlyOneFieldIsSetInUnderlyingArray', + function() { + var message = new proto.jspb.test.TestMessageWithOneof; + message.setPone('x'); + assertEquals('x', message.getPone()); + assertEquals('', message.getPthree()); + assertEquals( + proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, + message.getPartialOneofCase()); + + var array = message.toArray(); + assertEquals('x', array[2]); + assertUndefined(array[4]); + array[4] = 'y'; + + assertEquals( + proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE, + message.getPartialOneofCase()); + assertUndefined(array[2]); + assertEquals('y', array[4]); + }); + + it('testFloatingPointFieldsSupportNan', function() { + var assertNan = function(x) { + assertTrue('Expected ' + x + ' (' + goog.typeOf(x) + ') to be NaN.', + goog.isNumber(x) && isNaN(x)); + }; + + var message = new proto.jspb.test.FloatingPointFields([ + 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN', + 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN' + ]); + assertNan(message.getOptionalFloatField()); + assertNan(message.getRequiredFloatField()); + assertNan(message.getRepeatedFloatFieldList()[0]); + assertNan(message.getRepeatedFloatFieldList()[1]); + assertNan(message.getDefaultFloatField()); + assertNan(message.getOptionalDoubleField()); + assertNan(message.getRequiredDoubleField()); + assertNan(message.getRepeatedDoubleFieldList()[0]); + assertNan(message.getRepeatedDoubleFieldList()[1]); + assertNan(message.getDefaultDoubleField()); + }); + +}); diff --git a/js/compatibility_tests/v3.1.0/proto3_test.js b/js/compatibility_tests/v3.1.0/proto3_test.js new file mode 100644 index 00000000..3c929eff --- /dev/null +++ b/js/compatibility_tests/v3.1.0/proto3_test.js @@ -0,0 +1,329 @@ +// 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. + +goog.require('goog.crypt.base64'); +goog.require('goog.testing.asserts'); + +// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test +goog.require('proto.jspb.test.ForeignMessage'); + +// CommonJS-LoadFromFile: proto3_test_pb proto.jspb.test +goog.require('proto.jspb.test.Proto3Enum'); +goog.require('proto.jspb.test.TestProto3'); + + +var BYTES = new Uint8Array([1, 2, 8, 9]); +var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES); + + +/** + * Helper: compare a bytes field to an expected value + * @param {Uint8Array|string} arr + * @param {Uint8Array} expected + * @return {boolean} + */ +function bytesCompare(arr, expected) { + if (goog.isString(arr)) { + arr = goog.crypt.base64.decodeStringToUint8Array(arr); + } + if (arr.length != expected.length) { + return false; + } + for (var i = 0; i < arr.length; i++) { + if (arr[i] != expected[i]) { + return false; + } + } + return true; +} + + +describe('proto3Test', function() { + /** + * Test defaults for proto3 message fields. + */ + it('testProto3FieldDefaults', function() { + var msg = new proto.jspb.test.TestProto3(); + + assertEquals(msg.getOptionalInt32(), 0); + assertEquals(msg.getOptionalInt64(), 0); + assertEquals(msg.getOptionalUint32(), 0); + assertEquals(msg.getOptionalUint64(), 0); + assertEquals(msg.getOptionalSint32(), 0); + assertEquals(msg.getOptionalSint64(), 0); + assertEquals(msg.getOptionalFixed32(), 0); + assertEquals(msg.getOptionalFixed64(), 0); + assertEquals(msg.getOptionalSfixed32(), 0); + assertEquals(msg.getOptionalSfixed64(), 0); + assertEquals(msg.getOptionalFloat(), 0); + assertEquals(msg.getOptionalDouble(), 0); + assertEquals(msg.getOptionalString(), ''); + + // TODO(b/26173701): when we change bytes fields default getter to return + // Uint8Array, we'll want to switch this assertion to match the u8 case. + assertEquals(typeof msg.getOptionalBytes(), 'string'); + assertEquals(msg.getOptionalBytes_asU8() instanceof Uint8Array, true); + assertEquals(typeof msg.getOptionalBytes_asB64(), 'string'); + assertEquals(msg.getOptionalBytes().length, 0); + assertEquals(msg.getOptionalBytes_asU8().length, 0); + assertEquals(msg.getOptionalBytes_asB64(), ''); + + assertEquals(msg.getOptionalForeignEnum(), + proto.jspb.test.Proto3Enum.PROTO3_FOO); + assertEquals(msg.getOptionalForeignMessage(), undefined); + assertEquals(msg.getOptionalForeignMessage(), undefined); + + assertEquals(msg.getRepeatedInt32List().length, 0); + assertEquals(msg.getRepeatedInt64List().length, 0); + assertEquals(msg.getRepeatedUint32List().length, 0); + assertEquals(msg.getRepeatedUint64List().length, 0); + assertEquals(msg.getRepeatedSint32List().length, 0); + assertEquals(msg.getRepeatedSint64List().length, 0); + assertEquals(msg.getRepeatedFixed32List().length, 0); + assertEquals(msg.getRepeatedFixed64List().length, 0); + assertEquals(msg.getRepeatedSfixed32List().length, 0); + assertEquals(msg.getRepeatedSfixed64List().length, 0); + assertEquals(msg.getRepeatedFloatList().length, 0); + assertEquals(msg.getRepeatedDoubleList().length, 0); + assertEquals(msg.getRepeatedStringList().length, 0); + assertEquals(msg.getRepeatedBytesList().length, 0); + assertEquals(msg.getRepeatedForeignEnumList().length, 0); + assertEquals(msg.getRepeatedForeignMessageList().length, 0); + + }); + + + /** + * Test that all fields can be set and read via a serialization roundtrip. + */ + it('testProto3FieldSetGet', function() { + var msg = new proto.jspb.test.TestProto3(); + + msg.setOptionalInt32(-42); + msg.setOptionalInt64(-0x7fffffff00000000); + msg.setOptionalUint32(0x80000000); + msg.setOptionalUint64(0xf000000000000000); + msg.setOptionalSint32(-100); + msg.setOptionalSint64(-0x8000000000000000); + msg.setOptionalFixed32(1234); + msg.setOptionalFixed64(0x1234567800000000); + msg.setOptionalSfixed32(-1234); + msg.setOptionalSfixed64(-0x1234567800000000); + msg.setOptionalFloat(1.5); + msg.setOptionalDouble(-1.5); + msg.setOptionalBool(true); + msg.setOptionalString('hello world'); + msg.setOptionalBytes(BYTES); + var submsg = new proto.jspb.test.ForeignMessage(); + submsg.setC(16); + msg.setOptionalForeignMessage(submsg); + msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); + + msg.setRepeatedInt32List([-42]); + msg.setRepeatedInt64List([-0x7fffffff00000000]); + msg.setRepeatedUint32List([0x80000000]); + msg.setRepeatedUint64List([0xf000000000000000]); + msg.setRepeatedSint32List([-100]); + msg.setRepeatedSint64List([-0x8000000000000000]); + msg.setRepeatedFixed32List([1234]); + msg.setRepeatedFixed64List([0x1234567800000000]); + msg.setRepeatedSfixed32List([-1234]); + msg.setRepeatedSfixed64List([-0x1234567800000000]); + msg.setRepeatedFloatList([1.5]); + msg.setRepeatedDoubleList([-1.5]); + msg.setRepeatedBoolList([true]); + msg.setRepeatedStringList(['hello world']); + msg.setRepeatedBytesList([BYTES]); + submsg = new proto.jspb.test.ForeignMessage(); + submsg.setC(1000); + msg.setRepeatedForeignMessageList([submsg]); + msg.setRepeatedForeignEnumList([proto.jspb.test.Proto3Enum.PROTO3_BAR]); + + msg.setOneofString('asdf'); + + var serialized = msg.serializeBinary(); + msg = proto.jspb.test.TestProto3.deserializeBinary(serialized); + + assertEquals(msg.getOptionalInt32(), -42); + assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000); + assertEquals(msg.getOptionalUint32(), 0x80000000); + assertEquals(msg.getOptionalUint64(), 0xf000000000000000); + assertEquals(msg.getOptionalSint32(), -100); + assertEquals(msg.getOptionalSint64(), -0x8000000000000000); + assertEquals(msg.getOptionalFixed32(), 1234); + assertEquals(msg.getOptionalFixed64(), 0x1234567800000000); + assertEquals(msg.getOptionalSfixed32(), -1234); + assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000); + assertEquals(msg.getOptionalFloat(), 1.5); + assertEquals(msg.getOptionalDouble(), -1.5); + assertEquals(msg.getOptionalBool(), true); + assertEquals(msg.getOptionalString(), 'hello world'); + assertEquals(true, bytesCompare(msg.getOptionalBytes(), BYTES)); + assertEquals(msg.getOptionalForeignMessage().getC(), 16); + assertEquals(msg.getOptionalForeignEnum(), + proto.jspb.test.Proto3Enum.PROTO3_BAR); + + assertElementsEquals(msg.getRepeatedInt32List(), [-42]); + assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]); + assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]); + assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]); + assertElementsEquals(msg.getRepeatedSint32List(), [-100]); + assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]); + assertElementsEquals(msg.getRepeatedFixed32List(), [1234]); + assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]); + assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]); + assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]); + assertElementsEquals(msg.getRepeatedFloatList(), [1.5]); + assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]); + assertElementsEquals(msg.getRepeatedBoolList(), [true]); + assertElementsEquals(msg.getRepeatedStringList(), ['hello world']); + assertEquals(msg.getRepeatedBytesList().length, 1); + assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES)); + assertEquals(msg.getRepeatedForeignMessageList().length, 1); + assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000); + assertElementsEquals(msg.getRepeatedForeignEnumList(), + [proto.jspb.test.Proto3Enum.PROTO3_BAR]); + + assertEquals(msg.getOneofString(), 'asdf'); + }); + + + /** + * Test that oneofs continue to have a notion of field presence. + */ + it('testOneofs', function() { + var msg = new proto.jspb.test.TestProto3(); + + assertEquals(msg.getOneofUint32(), 0); + assertEquals(msg.getOneofForeignMessage(), undefined); + assertEquals(msg.getOneofString(), ''); + assertEquals(msg.getOneofBytes(), ''); + assertFalse(msg.hasOneofUint32()); + assertFalse(msg.hasOneofString()); + assertFalse(msg.hasOneofBytes()); + + msg.setOneofUint32(42); + assertEquals(msg.getOneofUint32(), 42); + assertEquals(msg.getOneofForeignMessage(), undefined); + assertEquals(msg.getOneofString(), ''); + assertEquals(msg.getOneofBytes(), ''); + assertTrue(msg.hasOneofUint32()); + assertFalse(msg.hasOneofString()); + assertFalse(msg.hasOneofBytes()); + + + var submsg = new proto.jspb.test.ForeignMessage(); + msg.setOneofForeignMessage(submsg); + assertEquals(msg.getOneofUint32(), 0); + assertEquals(msg.getOneofForeignMessage(), submsg); + assertEquals(msg.getOneofString(), ''); + assertEquals(msg.getOneofBytes(), ''); + assertFalse(msg.hasOneofUint32()); + assertFalse(msg.hasOneofString()); + assertFalse(msg.hasOneofBytes()); + + msg.setOneofString('hello'); + assertEquals(msg.getOneofUint32(), 0); + assertEquals(msg.getOneofForeignMessage(), undefined); + assertEquals(msg.getOneofString(), 'hello'); + assertEquals(msg.getOneofBytes(), ''); + assertFalse(msg.hasOneofUint32()); + assertTrue(msg.hasOneofString()); + assertFalse(msg.hasOneofBytes()); + + msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); + assertEquals(msg.getOneofUint32(), 0); + assertEquals(msg.getOneofForeignMessage(), undefined); + assertEquals(msg.getOneofString(), ''); + assertEquals(msg.getOneofBytes_asB64(), + goog.crypt.base64.encodeString('\u00FF\u00FF')); + assertFalse(msg.hasOneofUint32()); + assertFalse(msg.hasOneofString()); + assertTrue(msg.hasOneofBytes()); + }); + + + /** + * Test that "default"-valued primitive fields are not emitted on the wire. + */ + it('testNoSerializeDefaults', function() { + var msg = new proto.jspb.test.TestProto3(); + + // Set each primitive to a non-default value, then back to its default, to + // ensure that the serialization is actually checking the value and not just + // whether it has ever been set. + msg.setOptionalInt32(42); + msg.setOptionalInt32(0); + msg.setOptionalDouble(3.14); + msg.setOptionalDouble(0.0); + msg.setOptionalBool(true); + msg.setOptionalBool(false); + msg.setOptionalString('hello world'); + msg.setOptionalString(''); + msg.setOptionalBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); + msg.setOptionalBytes(''); + msg.setOptionalForeignMessage(new proto.jspb.test.ForeignMessage()); + msg.setOptionalForeignMessage(null); + msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); + msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO); + msg.setOneofUint32(32); + msg.clearOneofUint32(); + + + var serialized = msg.serializeBinary(); + assertEquals(0, serialized.length); + }); + + /** + * Test that base64 string and Uint8Array are interchangeable in bytes fields. + */ + it('testBytesFieldsInterop', function() { + var msg = new proto.jspb.test.TestProto3(); + // Set as a base64 string and check all the getters work. + msg.setOptionalBytes(BYTES_B64); + assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + + // Test binary serialize round trip doesn't break it. + msg = proto.jspb.test.TestProto3.deserializeBinary(msg.serializeBinary()); + assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + + msg = new proto.jspb.test.TestProto3(); + // Set as a Uint8Array and check all the getters work. + msg.setOptionalBytes(BYTES); + assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); + assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + + }); +}); diff --git a/js/compatibility_tests/v3.1.0/proto3_test.proto b/js/compatibility_tests/v3.1.0/proto3_test.proto new file mode 100644 index 00000000..acb67164 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/proto3_test.proto @@ -0,0 +1,89 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +import "testbinary.proto"; + +package jspb.test; + +message TestProto3 { + int32 optional_int32 = 1; + int64 optional_int64 = 2; + uint32 optional_uint32 = 3; + uint64 optional_uint64 = 4; + sint32 optional_sint32 = 5; + sint64 optional_sint64 = 6; + fixed32 optional_fixed32 = 7; + fixed64 optional_fixed64 = 8; + sfixed32 optional_sfixed32 = 9; + sfixed64 optional_sfixed64 = 10; + float optional_float = 11; + double optional_double = 12; + bool optional_bool = 13; + string optional_string = 14; + bytes optional_bytes = 15; + + ForeignMessage optional_foreign_message = 19; + Proto3Enum optional_foreign_enum = 22; + + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; + repeated sfixed32 repeated_sfixed32 = 39; + repeated sfixed64 repeated_sfixed64 = 40; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; + + repeated ForeignMessage repeated_foreign_message = 49; + repeated Proto3Enum repeated_foreign_enum = 52; + + + oneof oneof_field { + uint32 oneof_uint32 = 111; + ForeignMessage oneof_foreign_message = 112; + string oneof_string = 113; + bytes oneof_bytes = 114; + } +} + +enum Proto3Enum { + PROTO3_FOO = 0; + PROTO3_BAR = 1; + PROTO3_BAZ = 2; +} diff --git a/js/compatibility_tests/v3.1.0/test.proto b/js/compatibility_tests/v3.1.0/test.proto new file mode 100644 index 00000000..48cb37e1 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/test.proto @@ -0,0 +1,262 @@ +// 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: mwr@google.com (Mark Rawling) + +syntax = "proto2"; + +option java_package = "com.google.apps.jspb.proto"; +option java_multiple_files = true; + +import "google/protobuf/descriptor.proto"; + +package jspb.test; + +message Empty { +} + +enum OuterEnum { + FOO = 1; + BAR = 2; +} + +message EnumContainer { + optional OuterEnum outer_enum = 1; +} + +message Simple1 { + required string a_string = 1; + repeated string a_repeated_string = 2; + optional bool a_boolean = 3; +} + +// A message that differs from Simple1 only by name +message Simple2 { + required string a_string = 1; + repeated string a_repeated_string = 2; +} + +message SpecialCases { + required string normal = 1; + // Examples of Js reserved names that are converted to pb_<name>. + required string default = 2; + required string function = 3; + required string var = 4; +} + +message OptionalFields { + message Nested { + optional int32 an_int = 1; + } + optional string a_string = 1; + required bool a_bool = 2; + optional Nested a_nested_message = 3; + repeated Nested a_repeated_message = 4; + repeated string a_repeated_string = 5; +} + +message HasExtensions { + optional string str1 = 1; + optional string str2 = 2; + optional string str3 = 3; + extensions 10 to max; +} + +message Complex { + message Nested { + required int32 an_int = 2; + } + required string a_string = 1; + required bool an_out_of_order_bool = 9; + optional Nested a_nested_message = 4; + repeated Nested a_repeated_message = 5; + repeated string a_repeated_string = 7; +} + +message OuterMessage { + // Make sure this doesn't conflict with the other Complex message. + message Complex { + optional int32 inner_complex_field = 1; + } +} + +message IsExtension { + extend HasExtensions { + optional IsExtension ext_field = 100; + } + optional string ext1 = 1; + + // Extensions of proto2 Descriptor messages will be ignored. + extend google.protobuf.EnumOptions { + optional string simple_option = 42113038; + } +} + +message IndirectExtension { + extend HasExtensions { + optional Simple1 simple = 101; + optional string str = 102; + repeated string repeated_str = 103; + repeated Simple1 repeated_simple = 104; + } +} + +extend HasExtensions { + optional Simple1 simple1 = 105; +} + +message DefaultValues { + enum Enum { + E1 = 13; + E2 = 77; + } + optional string string_field = 1 [default="default<>\'\"abc"]; + optional bool bool_field = 2 [default=true]; + optional int64 int_field = 3 [default=11]; + optional Enum enum_field = 4 [default=E1]; + optional string empty_field = 6 [default=""]; + optional bytes bytes_field = 8 [default="moo"]; // Base64 encoding is "bW9v" +} + +message FloatingPointFields { + optional float optional_float_field = 1; + required float required_float_field = 2; + repeated float repeated_float_field = 3; + optional float default_float_field = 4 [default = 2.0]; + optional double optional_double_field = 5; + required double required_double_field = 6; + repeated double repeated_double_field = 7; + optional double default_double_field = 8 [default = 2.0]; +} + +message TestClone { + optional string str = 1; + optional Simple1 simple1 = 3; + repeated Simple1 simple2 = 5; + optional bytes bytes_field = 6; + optional string unused = 7; + extensions 10 to max; +} + +message CloneExtension { + extend TestClone { + optional CloneExtension ext_field = 100; + } + optional string ext = 2; +} + +message TestGroup { + repeated group RepeatedGroup = 1 { + required string id = 1; + repeated bool some_bool = 2; + } + required group RequiredGroup = 2 { + required string id = 1; + } + optional group OptionalGroup = 3 { + required string id = 1; + } + optional string id = 4; + required Simple2 required_simple = 5; + optional Simple2 optional_simple = 6; +} + +message TestGroup1 { + optional TestGroup.RepeatedGroup group = 1; +} + +message TestReservedNames { + optional int32 extension = 1; + extensions 10 to max; +} + +message TestReservedNamesExtension { + extend TestReservedNames { + optional int32 foo = 10; + } +} + +message TestMessageWithOneof { + + oneof partial_oneof { + string pone = 3; + string pthree = 5; + } + + oneof recursive_oneof { + TestMessageWithOneof rone = 6; + string rtwo = 7; + } + + optional bool normal_field = 8; + repeated string repeated_field = 9; + + oneof default_oneof_a { + int32 aone = 10 [default = 1234]; + int32 atwo = 11; + } + + oneof default_oneof_b { + int32 bone = 12; + int32 btwo = 13 [default = 1234]; + } +} + +message TestEndsWithBytes { + optional int32 value = 1; + optional bytes data = 2; +} + +message TestMapFieldsNoBinary { + map<string, string> map_string_string = 1; + map<string, int32> map_string_int32 = 2; + map<string, int64> map_string_int64 = 3; + map<string, bool> map_string_bool = 4; + map<string, double> map_string_double = 5; + map<string, MapValueEnumNoBinary> map_string_enum = 6; + map<string, MapValueMessageNoBinary> map_string_msg = 7; + + map<int32, string> map_int32_string = 8; + map<int64, string> map_int64_string = 9; + map<bool, string> map_bool_string = 10; + + optional TestMapFieldsNoBinary test_map_fields = 11; + map<string, TestMapFieldsNoBinary> map_string_testmapfields = 12; +} + +enum MapValueEnumNoBinary { + MAP_VALUE_FOO_NOBINARY = 0; + MAP_VALUE_BAR_NOBINARY = 1; + MAP_VALUE_BAZ_NOBINARY = 2; +} + +message MapValueMessageNoBinary { + optional int32 foo = 1; +} diff --git a/src/google/protobuf/compiler/profile.proto b/js/compatibility_tests/v3.1.0/test2.proto index 09ebe091..44e55eff 100644 --- a/src/google/protobuf/compiler/profile.proto +++ b/js/compatibility_tests/v3.1.0/test2.proto @@ -28,41 +28,27 @@ // (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; +option java_package = "com.google.apps.jspb.proto"; +option java_multiple_files = true; + +package jspb.test; -// 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; +message TestExtensionsMessage { + optional int32 intfield = 1; + extensions 100 to max; } -// "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 ExtensionMessage { + extend TestExtensionsMessage { + optional ExtensionMessage ext_field = 100; + } + optional string ext1 = 1; } -message AccessInfo { - repeated MessageAccessInfo message = 1; +// Floating extensions are only supported when generating a _lib.js library. +extend TestExtensionsMessage { + optional ExtensionMessage floating_msg_field = 101; + optional string floating_str_field = 102; } diff --git a/js/compatibility_tests/v3.1.0/test3.proto b/js/compatibility_tests/v3.1.0/test3.proto new file mode 100644 index 00000000..940a552e --- /dev/null +++ b/js/compatibility_tests/v3.1.0/test3.proto @@ -0,0 +1,53 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +option java_package = "com.google.apps.jspb.proto"; +option java_multiple_files = true; + +package jspb.exttest; + +message TestExtensionsMessage { + optional int32 intfield = 1; + extensions 100 to max; +} + +message ExtensionMessage { + extend TestExtensionsMessage { + optional ExtensionMessage ext_field = 100; + } + optional string ext1 = 1; +} + +extend TestExtensionsMessage { + optional ExtensionMessage floating_msg_field = 101; + optional string floating_str_field = 102; +} diff --git a/js/compatibility_tests/v3.1.0/test4.proto b/js/compatibility_tests/v3.1.0/test4.proto new file mode 100644 index 00000000..cf2451e9 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/test4.proto @@ -0,0 +1,42 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +option java_package = "com.google.apps.jspb.proto"; +option java_multiple_files = true; + +package jspb.exttest; + +import "test3.proto"; + +extend TestExtensionsMessage { + optional ExtensionMessage floating_msg_field_two = 103; +} diff --git a/js/compatibility_tests/v3.1.0/test5.proto b/js/compatibility_tests/v3.1.0/test5.proto new file mode 100644 index 00000000..34979517 --- /dev/null +++ b/js/compatibility_tests/v3.1.0/test5.proto @@ -0,0 +1,44 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +option java_package = "com.google.apps.jspb.proto"; +option java_multiple_files = true; + +package jspb.exttest.beta; + +message TestBetaExtensionsMessage { + extensions 100 to max; +} + +extend TestBetaExtensionsMessage { + optional string floating_str_field = 101; +} diff --git a/js/compatibility_tests/v3.1.0/testbinary.proto b/js/compatibility_tests/v3.1.0/testbinary.proto new file mode 100644 index 00000000..116f17fb --- /dev/null +++ b/js/compatibility_tests/v3.1.0/testbinary.proto @@ -0,0 +1,212 @@ +// 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. + +// LINT: ALLOW_GROUPS + +syntax = "proto2"; + + +package jspb.test; + +// These types are borrowed from `unittest.proto` in the protobuf tree. We want +// to ensure that the binary-format support will handle all field types +// properly. +message TestAllTypes { + optional int32 optional_int32 = 1; + optional int64 optional_int64 = 2; + optional uint32 optional_uint32 = 3; + optional uint64 optional_uint64 = 4; + optional sint32 optional_sint32 = 5; + optional sint64 optional_sint64 = 6; + optional fixed32 optional_fixed32 = 7; + optional fixed64 optional_fixed64 = 8; + optional sfixed32 optional_sfixed32 = 9; + optional sfixed64 optional_sfixed64 = 10; + optional float optional_float = 11; + optional double optional_double = 12; + optional bool optional_bool = 13; + optional string optional_string = 14; + optional bytes optional_bytes = 15; + optional group OptionalGroup = 16 { + optional int32 a = 17; + } + + optional ForeignMessage optional_foreign_message = 19; + optional ForeignEnum optional_foreign_enum = 22; + + // Repeated + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; + repeated sfixed32 repeated_sfixed32 = 39; + repeated sfixed64 repeated_sfixed64 = 40; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; + + repeated group RepeatedGroup = 46 { + optional int32 a = 47; + } + + repeated ForeignMessage repeated_foreign_message = 49; + repeated ForeignEnum repeated_foreign_enum = 52; + + // Packed repeated + repeated int32 packed_repeated_int32 = 61 [packed=true]; + repeated int64 packed_repeated_int64 = 62 [packed=true]; + repeated uint32 packed_repeated_uint32 = 63 [packed=true]; + repeated uint64 packed_repeated_uint64 = 64 [packed=true]; + repeated sint32 packed_repeated_sint32 = 65 [packed=true]; + repeated sint64 packed_repeated_sint64 = 66 [packed=true]; + repeated fixed32 packed_repeated_fixed32 = 67 [packed=true]; + repeated fixed64 packed_repeated_fixed64 = 68 [packed=true]; + repeated sfixed32 packed_repeated_sfixed32 = 69 [packed=true]; + repeated sfixed64 packed_repeated_sfixed64 = 70 [packed=true]; + repeated float packed_repeated_float = 71 [packed=true]; + repeated double packed_repeated_double = 72 [packed=true]; + repeated bool packed_repeated_bool = 73 [packed=true]; + + oneof oneof_field { + uint32 oneof_uint32 = 111; + ForeignMessage oneof_foreign_message = 112; + string oneof_string = 113; + bytes oneof_bytes = 114; + } + +} + +message ForeignMessage { + optional int32 c = 1; +} + +enum ForeignEnum { + FOREIGN_FOO = 4; + FOREIGN_BAR = 5; + FOREIGN_BAZ = 6; +} + +message TestExtendable { + extensions 1 to max; +} + +message ExtendsWithMessage { + extend TestExtendable { + optional ExtendsWithMessage optional_extension = 19; + repeated ExtendsWithMessage repeated_extension = 49; + } + optional int32 foo = 1; +} + +extend TestExtendable { + optional int32 extend_optional_int32 = 1; + optional int64 extend_optional_int64 = 2; + optional uint32 extend_optional_uint32 = 3; + optional uint64 extend_optional_uint64 = 4; + optional sint32 extend_optional_sint32 = 5; + optional sint64 extend_optional_sint64 = 6; + optional fixed32 extend_optional_fixed32 = 7; + optional fixed64 extend_optional_fixed64 = 8; + optional sfixed32 extend_optional_sfixed32 = 9; + optional sfixed64 extend_optional_sfixed64 = 10; + optional float extend_optional_float = 11; + optional double extend_optional_double = 12; + optional bool extend_optional_bool = 13; + optional string extend_optional_string = 14; + optional bytes extend_optional_bytes = 15; + optional ForeignEnum extend_optional_foreign_enum = 22; + + repeated int32 extend_repeated_int32 = 31; + repeated int64 extend_repeated_int64 = 32; + repeated uint32 extend_repeated_uint32 = 33; + repeated uint64 extend_repeated_uint64 = 34; + repeated sint32 extend_repeated_sint32 = 35; + repeated sint64 extend_repeated_sint64 = 36; + repeated fixed32 extend_repeated_fixed32 = 37; + repeated fixed64 extend_repeated_fixed64 = 38; + repeated sfixed32 extend_repeated_sfixed32 = 39; + repeated sfixed64 extend_repeated_sfixed64 = 40; + repeated float extend_repeated_float = 41; + repeated double extend_repeated_double = 42; + repeated bool extend_repeated_bool = 43; + repeated string extend_repeated_string = 44; + repeated bytes extend_repeated_bytes = 45; + repeated ForeignEnum extend_repeated_foreign_enum = 52; + + repeated int32 extend_packed_repeated_int32 = 61 [packed=true]; + repeated int64 extend_packed_repeated_int64 = 62 [packed=true]; + repeated uint32 extend_packed_repeated_uint32 = 63 [packed=true]; + repeated uint64 extend_packed_repeated_uint64 = 64 [packed=true]; + repeated sint32 extend_packed_repeated_sint32 = 65 [packed=true]; + repeated sint64 extend_packed_repeated_sint64 = 66 [packed=true]; + repeated fixed32 extend_packed_repeated_fixed32 = 67 [packed=true]; + repeated fixed64 extend_packed_repeated_fixed64 = 68 [packed=true]; + repeated sfixed32 extend_packed_repeated_sfixed32 = 69 [packed=true]; + repeated sfixed64 extend_packed_repeated_sfixed64 = 70 [packed=true]; + repeated float extend_packed_repeated_float = 71 [packed=true]; + repeated double extend_packed_repeated_double = 72 [packed=true]; + repeated bool extend_packed_repeated_bool = 73 [packed=true]; + repeated ForeignEnum extend_packed_repeated_foreign_enum = 82 + [packed=true]; + +} + +message TestMapFields { + map<string, string> map_string_string = 1; + map<string, int32> map_string_int32 = 2; + map<string, int64> map_string_int64 = 3; + map<string, bool> map_string_bool = 4; + map<string, double> map_string_double = 5; + map<string, MapValueEnum> map_string_enum = 6; + map<string, MapValueMessage> map_string_msg = 7; + + map<int32, string> map_int32_string = 8; + map<int64, string> map_int64_string = 9; + map<bool, string> map_bool_string = 10; + + optional TestMapFields test_map_fields = 11; + map<string, TestMapFields> map_string_testmapfields = 12; +} + +enum MapValueEnum { + MAP_VALUE_FOO = 0; + MAP_VALUE_BAR = 1; + MAP_VALUE_BAZ = 2; +} + +message MapValueMessage { + optional int32 foo = 1; +} diff --git a/js/compatibility_tests/v3.1.0/testempty.proto b/js/compatibility_tests/v3.1.0/testempty.proto new file mode 100644 index 00000000..960bce4e --- /dev/null +++ b/js/compatibility_tests/v3.1.0/testempty.proto @@ -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. + +syntax = "proto2"; + +package javatests.com.google.apps.jspb; + diff --git a/js/message.js b/js/message.js index 1f6bf16b..f7dcfa96 100644 --- a/js/message.js +++ b/js/message.js @@ -41,7 +41,6 @@ goog.provide('jspb.Message'); goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.crypt.base64'); -goog.require('goog.json'); goog.require('jspb.Map'); // Not needed in compilation units that have no protos with xids. @@ -192,8 +191,8 @@ goog.define('jspb.Message.GENERATE_FROM_OBJECT', !goog.DISALLOW_TEST_ONLY_CODE); /** * @define {boolean} Whether to generate toString methods for objects. Turn - * this off if you do use toString in your project and want to trim it from - * compiled JS. + * this off if you do not use toString in your project and want to trim it + * from the compiled JS. */ goog.define('jspb.Message.GENERATE_TO_STRING', true); @@ -351,7 +350,7 @@ jspb.Message.initialize = function( // which would otherwise go unused. msg.arrayIndexOffset_ = messageId === 0 ? -1 : 0; msg.array = data; - jspb.Message.materializeExtensionObject_(msg, suggestedPivot); + jspb.Message.initPivotAndExtensionObject_(msg, suggestedPivot); msg.convertedFloatingPointFields_ = {}; if (repeatedFields) { @@ -364,6 +363,7 @@ jspb.Message.initialize = function( jspb.Message.EMPTY_LIST_SENTINEL_ : []); } else { + jspb.Message.maybeInitEmptyExtensionObject_(msg); msg.extensionObject_[fieldNumber] = msg.extensionObject_[fieldNumber] || (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ? @@ -408,17 +408,16 @@ jspb.Message.isArray_ = function(o) { /** - * Ensures that the array contains an extension object if necessary. * If the array contains an extension object in its last position, then the - * object is kept in place and its position is used as the pivot. If not, then - * create an extension object using suggestedPivot. If suggestedPivot is -1, - * we don't have an extension object at all, in which case all fields are stored - * in the array. + * object is kept in place and its position is used as the pivot. If not, + * decides the pivot of the message based on suggestedPivot without + * materializing the extension object. + * * @param {!jspb.Message} msg The JsPb proto to modify. * @param {number} suggestedPivot See description for initialize(). * @private */ -jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) { +jspb.Message.initPivotAndExtensionObject_ = function(msg, suggestedPivot) { if (msg.array.length) { var foundIndex = msg.array.length - 1; var obj = msg.array[foundIndex]; @@ -434,26 +433,17 @@ jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) { return; } } - // This complexity exists because we keep all extension fields in the - // extensionObject_ regardless of proto field number. Changing this would - // simplify the code here, but it would require changing the serialization - // format from the server, which is not backwards compatible. - // TODO(jshneier): Should we just treat extension fields the same as - // non-extension fields, and select whether they appear in the object or in - // the array purely based on tag number? This would allow simplifying all the - // get/setExtension logic, but it would require the breaking change described - // above. + if (suggestedPivot > -1) { msg.pivot_ = suggestedPivot; - var pivotIndex = jspb.Message.getIndex_(msg, suggestedPivot); - if (!jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) { - msg.extensionObject_ = msg.array[pivotIndex] = {}; - } else { - // Initialize to null to avoid changing the shape of the proto when it - // gets eventually set. - msg.extensionObject_ = null; - } + // Avoid changing the shape of the proto with an empty extension object by + // deferring the materialization of the extension object until the first + // time a field set into it (may be due to getting a repeated proto field + // from it, in which case a new empty array is set into it at first). + msg.extensionObject_ = null; } else { + // suggestedPivot is -1, which means that we don't have an extension object + // at all, in which case all fields are stored in the array. msg.pivot_ = Number.MAX_VALUE; } }; @@ -513,7 +503,7 @@ jspb.Message.toObjectExtension = function(proto, obj, extensions, for (var fieldNumber in extensions) { var fieldInfo = extensions[fieldNumber]; var value = getExtensionFn.call(proto, fieldInfo); - if (goog.isDefAndNotNull(value)) { + if (value != null) { for (var name in fieldInfo.fieldName) { if (fieldInfo.fieldName.hasOwnProperty(name)) { break; // the compiled field name @@ -557,7 +547,7 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, 'without binary serialization support'); } var value = getExtensionFn.call(proto, fieldInfo); - if (goog.isDefAndNotNull(value)) { + if (value != null) { if (fieldInfo.isMessageType()) { // If the message type of the extension was generated without binary // support, there may not be a binary message serializer function, and @@ -647,6 +637,9 @@ jspb.Message.getField = function(msg, fieldNumber) { } return val; } else { + if (!msg.extensionObject_) { + return undefined; + } var val = msg.extensionObject_[fieldNumber]; if (val === jspb.Message.EMPTY_LIST_SENTINEL_) { return msg.extensionObject_[fieldNumber] = []; @@ -657,6 +650,32 @@ jspb.Message.getField = function(msg, fieldNumber) { /** + * Gets the value of a non-extension repeated field. + * @param {!jspb.Message} msg A jspb proto. + * @param {number} fieldNumber The field number. + * @return {!Array} + * The field's value. + * @protected + */ +jspb.Message.getRepeatedField = function(msg, fieldNumber) { + if (fieldNumber < msg.pivot_) { + var index = jspb.Message.getIndex_(msg, fieldNumber); + var val = msg.array[index]; + if (val === jspb.Message.EMPTY_LIST_SENTINEL_) { + return msg.array[index] = []; + } + return val; + } + + var val = msg.extensionObject_[fieldNumber]; + if (val === jspb.Message.EMPTY_LIST_SENTINEL_) { + return msg.extensionObject_[fieldNumber] = []; + } + return val; +}; + + +/** * Gets the value of an optional float or double field. * @param {!jspb.Message} msg A jspb proto. * @param {number} fieldNumber The field number. @@ -678,7 +697,7 @@ jspb.Message.getOptionalFloatingPointField = function(msg, fieldNumber) { * @protected */ jspb.Message.getRepeatedFloatingPointField = function(msg, fieldNumber) { - var values = jspb.Message.getField(msg, fieldNumber); + var values = jspb.Message.getRepeatedField(msg, fieldNumber); if (!msg.convertedFloatingPointFields_) { msg.convertedFloatingPointFields_ = {}; } @@ -864,6 +883,7 @@ jspb.Message.setField = function(msg, fieldNumber, value) { if (fieldNumber < msg.pivot_) { msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value; } else { + jspb.Message.maybeInitEmptyExtensionObject_(msg); msg.extensionObject_[fieldNumber] = value; } }; @@ -878,7 +898,7 @@ jspb.Message.setField = function(msg, fieldNumber, value) { * @protected */ jspb.Message.addToRepeatedField = function(msg, fieldNumber, value, opt_index) { - var arr = jspb.Message.getField(msg, fieldNumber); + var arr = jspb.Message.getRepeatedField(msg, fieldNumber); if (opt_index != undefined) { arr.splice(opt_index, 0, value); } else { @@ -1006,7 +1026,7 @@ jspb.Message.wrapRepeatedField_ = function(msg, ctor, fieldNumber) { msg.wrappers_ = {}; } if (!msg.wrappers_[fieldNumber]) { - var data = jspb.Message.getField(msg, fieldNumber); + var data = jspb.Message.getRepeatedField(msg, fieldNumber); for (var wrappers = [], i = 0; i < data.length; i++) { wrappers[i] = new ctor(data[i]); } @@ -1101,7 +1121,7 @@ jspb.Message.addToRepeatedWrapperField = function( wrapperArray = msg.wrappers_[fieldNumber] = []; } var insertedValue = value ? value : new ctor(); - var array = jspb.Message.getField(msg, fieldNumber); + var array = jspb.Message.getRepeatedField(msg, fieldNumber); if (index != undefined) { wrapperArray.splice(index, 0, insertedValue); array.splice(index, 0, insertedValue.toArray()); diff --git a/js/message_test.js b/js/message_test.js index dc0ae211..7d61dacb 100644 --- a/js/message_test.js +++ b/js/message_test.js @@ -33,6 +33,7 @@ goog.setTestOnly(); goog.require('goog.json'); +goog.require('goog.string'); goog.require('goog.testing.asserts'); goog.require('goog.userAgent'); @@ -83,8 +84,6 @@ goog.require('proto.jspb.test.ExtensionMessage'); goog.require('proto.jspb.test.TestExtensionsMessage'); - - describe('Message test suite', function() { it('testEmptyProto', function() { var empty1 = new proto.jspb.test.Empty([]); @@ -273,12 +272,6 @@ describe('Message test suite', function() { assertFalse(response.hasEnumField()); }); - it('testMessageRegistration', /** @suppress {visibility} */ function() { - // goog.require(SomeResponse) will include its library, which will in - // turn add SomeResponse to the message registry. - assertEquals(jspb.Message.registry_['res'], proto.jspb.test.SomeResponse); - }); - it('testClearFields', function() { var data = ['str', true, [11], [[22], [33]], ['s1', 's2']]; var foo = new proto.jspb.test.OptionalFields(data); @@ -661,12 +654,7 @@ describe('Message test suite', function() { it('testInitialization_emptyArray', function() { var msg = new proto.jspb.test.HasExtensions([]); - if (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) { - assertArrayEquals([], msg.toArray()); - } else { - // Extension object is created past all regular fields. - assertArrayEquals([,,, {}], msg.toArray()); - } + assertArrayEquals([], msg.toArray()); }); it('testInitialization_justExtensionObject', function() { diff --git a/js/package.json b/js/package.json index afb223db..c8b75385 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "google-protobuf", - "version": "3.3.2", + "version": "3.4.0", "description": "Protocol Buffers for JavaScript", "main": "google-protobuf.js", "files": [ diff --git a/js/proto3_test.proto b/js/proto3_test.proto index acb67164..0d073ea0 100644 --- a/js/proto3_test.proto +++ b/js/proto3_test.proto @@ -86,4 +86,5 @@ enum Proto3Enum { PROTO3_FOO = 0; PROTO3_BAR = 1; PROTO3_BAZ = 2; + MSG_PROTO3_BAH = 3; } diff --git a/js/test.proto b/js/test.proto index 2be5b8c1..7c881c0d 100644 --- a/js/test.proto +++ b/js/test.proto @@ -235,6 +235,13 @@ message TestEndsWithBytes { } +message Int64Types { + optional int64 int64_normal = 1 [jstype=JS_NORMAL]; + optional sint64 int64_string = 2 [jstype=JS_STRING]; + optional uint64 int64_number = 3 [jstype=JS_NUMBER]; + +} + message TestMapFieldsNoBinary { map<string, string> map_string_string = 1; @@ -271,3 +278,4 @@ message Deeply { } } } + diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 index b61fcb63..d3288e2f 100644 --- a/m4/ax_cxx_compile_stdcxx.m4 +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -180,6 +180,8 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ #else +#include <utility> + namespace cxx11 { @@ -445,6 +447,23 @@ namespace cxx11 } + namespace test_std_move_and_forward + { + struct message {}; + char foo(message&) { return '\0'; } + int foo(message&&) { return 0; } + + template<typename Arg, typename RT> + void check(Arg&& arg, RT rt) { + static_assert(sizeof(rt) == sizeof(foo(std::forward<Arg>(arg))), ""); + } + void test() { + message a; + check(a, char()); + check(std::move(a), int()); + } + } + } // namespace cxx11 #endif // __cplusplus >= 201103L diff --git a/objectivec/google/protobuf/Any.pbobjc.h b/objectivec/google/protobuf/Any.pbobjc.h index d236e4b2..b17e76f0 100644 --- a/objectivec/google/protobuf/Any.pbobjc.h +++ b/objectivec/google/protobuf/Any.pbobjc.h @@ -87,6 +87,16 @@ typedef GPB_ENUM(GPBAny_FieldNumber) { * any.Unpack(foo) * ... * + * Example 4: Pack and unpack a message in Go + * + * foo := &pb.Foo{...} + * any, err := ptypes.MarshalAny(foo) + * ... + * foo := &pb.Foo{} + * if err := ptypes.UnmarshalAny(any, foo); err != nil { + * ... + * } + * * The pack methods provided by protobuf library will by default use * 'type.googleapis.com/full.type.name' as the type URL and the unpack * methods only use the fully qualified type name after the last '/' diff --git a/objectivec/google/protobuf/Api.pbobjc.h b/objectivec/google/protobuf/Api.pbobjc.h index 742a8122..095fc2cd 100644 --- a/objectivec/google/protobuf/Api.pbobjc.h +++ b/objectivec/google/protobuf/Api.pbobjc.h @@ -63,34 +63,41 @@ typedef GPB_ENUM(GPBApi_FieldNumber) { }; /** - * Api is a light-weight descriptor for a protocol buffer service. + * Api is a light-weight descriptor for an API Interface. + * + * Interfaces are also described as "protocol buffer services" in some contexts, + * such as by the "service" keyword in a .proto file, but they are different + * from API Services, which represent a concrete implementation of an interface + * as opposed to simply a description of methods and bindings. They are also + * sometimes simply referred to as "APIs" in other contexts, such as the name of + * this message itself. See https://cloud.google.com/apis/design/glossary for + * detailed terminology. **/ @interface GPBApi : GPBMessage /** - * The fully qualified name of this api, including package name - * followed by the api's simple name. + * The fully qualified name of this interface, including package name + * followed by the interface's simple name. **/ @property(nonatomic, readwrite, copy, null_resettable) NSString *name; -/** The methods of this api, in unspecified order. */ +/** The methods of this interface, in unspecified order. */ @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBMethod*> *methodsArray; /** The number of items in @c methodsArray without causing the array to be created. */ @property(nonatomic, readonly) NSUInteger methodsArray_Count; -/** Any metadata attached to the API. */ +/** Any metadata attached to the interface. */ @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray; /** The number of items in @c optionsArray without causing the array to be created. */ @property(nonatomic, readonly) NSUInteger optionsArray_Count; /** - * A version string for this api. If specified, must have the form - * `major-version.minor-version`, as in `1.10`. If the minor version - * is omitted, it defaults to zero. If the entire version field is - * empty, the major version is derived from the package name, as - * outlined below. If the field is not empty, the version in the - * package name will be verified to be consistent with what is - * provided here. + * A version string for this interface. If specified, must have the form + * `major-version.minor-version`, as in `1.10`. If the minor version is + * omitted, it defaults to zero. If the entire version field is empty, the + * major version is derived from the package name, as outlined below. If the + * field is not empty, the version in the package name will be verified to be + * consistent with what is provided here. * * The versioning schema uses [semantic * versioning](http://semver.org) where the major version number @@ -100,10 +107,10 @@ typedef GPB_ENUM(GPBApi_FieldNumber) { * chosen based on the product plan. * * The major version is also reflected in the package name of the - * API, which must end in `v<major-version>`, as in + * interface, which must end in `v<major-version>`, as in * `google.feature.v1`. For major versions 0 and 1, the suffix can * be omitted. Zero major versions must only be used for - * experimental, none-GA apis. + * experimental, non-GA interfaces. **/ @property(nonatomic, readwrite, copy, null_resettable) NSString *version; @@ -115,7 +122,7 @@ typedef GPB_ENUM(GPBApi_FieldNumber) { /** Test to see if @c sourceContext has been set. */ @property(nonatomic, readwrite) BOOL hasSourceContext; -/** Included APIs. See [Mixin][]. */ +/** Included interfaces. See [Mixin][]. */ @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBMixin*> *mixinsArray; /** The number of items in @c mixinsArray without causing the array to be created. */ @property(nonatomic, readonly) NSUInteger mixinsArray_Count; @@ -150,7 +157,7 @@ typedef GPB_ENUM(GPBMethod_FieldNumber) { }; /** - * Method represents a method of an api. + * Method represents a method of an API interface. **/ @interface GPBMethod : GPBMessage @@ -199,9 +206,9 @@ typedef GPB_ENUM(GPBMixin_FieldNumber) { }; /** - * Declares an API to be included in this API. The including API must - * redeclare all the methods from the included API, but documentation - * and options are inherited as follows: + * Declares an API Interface to be included in this interface. The including + * interface must redeclare all the methods from the included interface, but + * documentation and options are inherited as follows: * * - If after comment and whitespace stripping, the documentation * string of the redeclared method is empty, it will be inherited @@ -213,7 +220,8 @@ typedef GPB_ENUM(GPBMixin_FieldNumber) { * * - If an http annotation is inherited, the path pattern will be * modified as follows. Any version prefix will be replaced by the - * version of the including API plus the [root][] path if specified. + * version of the including interface plus the [root][] path if + * specified. * * Example of a simple mixin: * @@ -279,7 +287,7 @@ typedef GPB_ENUM(GPBMixin_FieldNumber) { **/ @interface GPBMixin : GPBMessage -/** The fully qualified name of the API which is included. */ +/** The fully qualified name of the interface which is included. */ @property(nonatomic, readwrite, copy, null_resettable) NSString *name; /** diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index 20a45bc6..2d318517 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -13,8 +13,8 @@ <date>2017-01-13</date> <time>16:06:07</time> <version> - <release>3.3.2</release> - <api>3.3.0</api> + <release>3.4.0</release> + <api>3.4.0</api> </version> <stability> <release>stable</release> @@ -136,5 +136,21 @@ GA release. GA release. </notes> </release> + <release> + <version> + <release>3.4.0</release> + <api>3.4.0</api> + </version> + <stability> + <release>stable</release> + <api>stable</api> + </stability> + <date>2017-08-16</date> + <time>15:33:07</time> + <license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license> + <notes> +GA release. + </notes> + </release> </changelog> </package> diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index f9e9d229..b2838e56 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.3.2" +#define PHP_PROTOBUF_VERSION "3.4.0" #define MAX_LENGTH_OF_INT64 20 #define SIZEOF_INT64 8 diff --git a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php index 1e3c745e..60722d00 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php @@ -49,6 +49,7 @@ class Descriptor $pool->addMessage('google.protobuf.internal.DescriptorProto.ExtensionRange', \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class) ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2) + ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 3, 'google.protobuf.internal.ExtensionRangeOptions') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.DescriptorProto.ReservedRange', \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class) @@ -56,6 +57,10 @@ class Descriptor ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2) ->finalizeToPool(); + $pool->addMessage('google.protobuf.internal.ExtensionRangeOptions', \Google\Protobuf\Internal\ExtensionRangeOptions::class) + ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') + ->finalizeToPool(); + $pool->addMessage('google.protobuf.internal.FieldDescriptorProto', \Google\Protobuf\Internal\FieldDescriptorProto::class) ->optional('name', \Google\Protobuf\Internal\GPBType::STRING, 1) ->optional('number', \Google\Protobuf\Internal\GPBType::INT32, 3) diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php index 51d5d359..1d455995 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php @@ -25,6 +25,11 @@ class DescriptorProto_ExtensionRange extends \Google\Protobuf\Internal\Message */ private $end = 0; private $has_end = false; + /** + * Generated from protobuf field <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code> + */ + private $options = null; + private $has_options = false; public function __construct() { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); @@ -87,5 +92,33 @@ class DescriptorProto_ExtensionRange extends \Google\Protobuf\Internal\Message return $this->has_end; } + /** + * Generated from protobuf field <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code> + * @return \Google\Protobuf\Internal\ExtensionRangeOptions + */ + public function getOptions() + { + return $this->options; + } + + /** + * Generated from protobuf field <code>optional .google.protobuf.ExtensionRangeOptions options = 3;</code> + * @param \Google\Protobuf\Internal\ExtensionRangeOptions $var + * @return $this + */ + public function setOptions($var) + { + GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ExtensionRangeOptions::class); + $this->options = $var; + $this->has_options = true; + + return $this; + } + + public function hasOptions() + { + return $this->has_options; + } + } diff --git a/php/src/Google/Protobuf/Internal/FieldOptions.php b/php/src/Google/Protobuf/Internal/FieldOptions.php index 3144e670..169f860b 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions.php @@ -39,13 +39,14 @@ class FieldOptions extends \Google\Protobuf\Internal\Message /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types - * (int64, uint64, sint64, fixed64, sfixed64). By default these types are - * represented as JavaScript strings. This avoids loss of precision that can - * happen when a large value is converted to a floating point JavaScript - * numbers. Specifying JS_NUMBER for the jstype causes the generated - * JavaScript code to use the JavaScript "number" type instead of strings. - * This option is an enum to permit additional types to be added, - * e.g. goog.math.Integer. + * (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + * is represented as JavaScript string, which avoids loss of precision that + * can happen when a large value is converted to a floating point JavaScript. + * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + * use the JavaScript "number" type. The behavior of the default option + * JS_NORMAL is implementation dependent. + * This option is an enum to permit additional types to be added, e.g. + * goog.math.Integer. * * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code> */ @@ -192,13 +193,14 @@ class FieldOptions extends \Google\Protobuf\Internal\Message /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types - * (int64, uint64, sint64, fixed64, sfixed64). By default these types are - * represented as JavaScript strings. This avoids loss of precision that can - * happen when a large value is converted to a floating point JavaScript - * numbers. Specifying JS_NUMBER for the jstype causes the generated - * JavaScript code to use the JavaScript "number" type instead of strings. - * This option is an enum to permit additional types to be added, - * e.g. goog.math.Integer. + * (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + * is represented as JavaScript string, which avoids loss of precision that + * can happen when a large value is converted to a floating point JavaScript. + * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + * use the JavaScript "number" type. The behavior of the default option + * JS_NORMAL is implementation dependent. + * This option is an enum to permit additional types to be added, e.g. + * goog.math.Integer. * * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code> * @return int @@ -211,13 +213,14 @@ class FieldOptions extends \Google\Protobuf\Internal\Message /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types - * (int64, uint64, sint64, fixed64, sfixed64). By default these types are - * represented as JavaScript strings. This avoids loss of precision that can - * happen when a large value is converted to a floating point JavaScript - * numbers. Specifying JS_NUMBER for the jstype causes the generated - * JavaScript code to use the JavaScript "number" type instead of strings. - * This option is an enum to permit additional types to be added, - * e.g. goog.math.Integer. + * (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + * is represented as JavaScript string, which avoids loss of precision that + * can happen when a large value is converted to a floating point JavaScript. + * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + * use the JavaScript "number" type. The behavior of the default option + * JS_NORMAL is implementation dependent. + * This option is an enum to permit additional types to be added, e.g. + * goog.math.Integer. * * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code> * @param int $var diff --git a/protoc-artifacts/README.md b/protoc-artifacts/README.md index 50629209..17eb77f8 100644 --- a/protoc-artifacts/README.md +++ b/protoc-artifacts/README.md @@ -72,6 +72,7 @@ deployment for all platforms. Currently the following platforms are supported: - Windows (x86_32 and x86_64) with - Cygwin64 with MinGW compilers (x86_64) - MSYS with MinGW32 (x86_32) + - Cross compile in Linux with MinGW-w64 (x86_32, x86_64) - MacOSX (x86_32 and x86_64) As for MSYS2/MinGW64 for Windows: protoc will build, but it insists on @@ -98,6 +99,9 @@ $ mvn clean deploy -P release -Dstaging.repository=comgoogle-123 A 32-bit artifact can be deployed from a 64-bit host with ``-Dos.detected.arch=x86_32`` +A windows artifact can be deployed from a linux machine with +``-Dos.detected.name=windows`` + When you have done deployment for all platforms, go to https://oss.sonatype.org/#stagingRepositories, verify that the staging repository has all the binaries, close and release this repository. @@ -173,5 +177,7 @@ We have successfully built artifacts on the following environments: - Centos 6.6 (within Docker 1.6.1) - Ubuntu 14.04.2 64-bit - Windows x86_32: MSYS with ``mingw32-gcc-g++ 4.8.1-4`` on Windows 7 64-bit +- Windows x86_32: Cross compile with ``i686-w64-mingw32-g++ 4.8.2`` on Ubuntu 14.04.2 64-bit - Windows x86_64: Cygwin64 with ``mingw64-x86_64-gcc-g++ 4.8.3-1`` on Windows 7 64-bit +- Windows x86_64: Cross compile with ``x86_64-w64-mingw32-g++ 4.8.2`` on Ubuntu 14.04.2 64-bit - Mac OS X x86_32 and x86_64: Mac OS X 10.9.5 diff --git a/protoc-artifacts/build-protoc.sh b/protoc-artifacts/build-protoc.sh index e31948e9..57523a41 100755 --- a/protoc-artifacts/build-protoc.sh +++ b/protoc-artifacts/build-protoc.sh @@ -185,8 +185,6 @@ elif [[ "$(uname)" == Linux* ]]; then fi elif [[ "$OS" == windows ]]; then # Cross-compilation for Windows - # TODO(zhangkun83) MinGW 64 always adds dependency on libwinpthread-1.dll, - # which is undesirable for repository deployment. CONFIGURE_ARGS="$CONFIGURE_ARGS" if [[ "$ARCH" == x86_64 ]]; then CONFIGURE_ARGS="$CONFIGURE_ARGS --host=x86_64-w64-mingw32" @@ -215,8 +213,11 @@ fi # Statically link libgcc and libstdc++. # -s to produce stripped binary. -# And they don't work under Mac. -if [[ "$OS" != osx ]]; then +if [[ "$OS" == windows ]]; then + # Also static link libpthread required by mingw64 + LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -s" +elif [[ "$OS" != osx ]]; then + # And they don't work under Mac. LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++ -s" fi diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml index 6003f09d..d68709ea 100644 --- a/protoc-artifacts/pom.xml +++ b/protoc-artifacts/pom.xml @@ -10,7 +10,7 @@ </parent> <groupId>com.google.protobuf</groupId> <artifactId>protoc</artifactId> - <version>3.3.2</version> + <version>3.4.0</version> <packaging>pom</packaging> <name>Protobuf Compiler</name> <description> diff --git a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py index 6bf7befb..8267cd2c 100755 --- a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py +++ b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py @@ -370,9 +370,8 @@ class TextFormatTest(unittest.TestCase): def testMergeBadExtension(self): message = unittest_pb2.TestAllExtensions() text = '[unknown_extension]: 8\n' - self.assertRaisesWithMessage( + self.assertRaises( text_format.ParseError, - '1:2 : Extension "unknown_extension" not registered.', text_format.Merge, text, message) message = unittest_pb2.TestAllTypes() self.assertRaisesWithMessage( diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py index 622dfb3d..d26da0df 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.3.2' +__version__ = '3.4.0' if __name__ != '__main__': try: diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py index e1f2e3b7..b1f3ca38 100755 --- a/python/google/protobuf/descriptor.py +++ b/python/google/protobuf/descriptor.py @@ -406,6 +406,8 @@ class FieldDescriptor(DescriptorBase): containing_oneof: (OneofDescriptor) If the field is a member of a oneof union, contains its descriptor. Otherwise, None. + + file: (FileDescriptor) Reference to file descriptor. """ # Must be consistent with C++ FieldDescriptor::Type enum in @@ -490,7 +492,8 @@ class FieldDescriptor(DescriptorBase): def __new__(cls, name, full_name, index, number, type, cpp_type, label, default_value, message_type, enum_type, containing_type, is_extension, extension_scope, options=None, - has_default_value=True, containing_oneof=None, json_name=None): + has_default_value=True, containing_oneof=None, json_name=None, + file=None): _message.Message._CheckCalledFromGeneratedFile() if is_extension: return _message.default_pool.FindExtensionByName(full_name) @@ -500,7 +503,8 @@ class FieldDescriptor(DescriptorBase): def __init__(self, name, full_name, index, number, type, cpp_type, label, default_value, message_type, enum_type, containing_type, is_extension, extension_scope, options=None, - has_default_value=True, containing_oneof=None, json_name=None): + has_default_value=True, containing_oneof=None, json_name=None, + file=None): """The arguments are as described in the description of FieldDescriptor attributes above. @@ -511,6 +515,7 @@ class FieldDescriptor(DescriptorBase): super(FieldDescriptor, self).__init__(options, 'FieldOptions') self.name = name self.full_name = full_name + self.file = file self._camelcase_name = None if json_name is None: self.json_name = _ToJsonName(name) diff --git a/python/google/protobuf/descriptor_database.py b/python/google/protobuf/descriptor_database.py index 40bcdd72..eb45e127 100644 --- a/python/google/protobuf/descriptor_database.py +++ b/python/google/protobuf/descriptor_database.py @@ -134,8 +134,7 @@ def _ExtractSymbols(desc_proto, package): Yields: The fully qualified name found in the descriptor. """ - - message_name = '.'.join((package, desc_proto.name)) + message_name = package + '.' + desc_proto.name if package else desc_proto.name yield message_name for nested_type in desc_proto.nested_type: for symbol in _ExtractSymbols(nested_type, message_name): diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py index 29e9f1e3..3dbe0fd0 100644 --- a/python/google/protobuf/descriptor_pool.py +++ b/python/google/protobuf/descriptor_pool.py @@ -329,6 +329,11 @@ class DescriptorPool(object): pass try: + return self._service_descriptors[symbol].file + except KeyError: + pass + + try: return self._FindFileContainingSymbolInDb(symbol) except KeyError: pass @@ -344,7 +349,6 @@ class DescriptorPool(object): 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) @@ -557,7 +561,8 @@ class DescriptorPool(object): for index, extension_proto in enumerate(file_proto.extension): extension_desc = self._MakeFieldDescriptor( - extension_proto, file_proto.package, index, is_extension=True) + extension_proto, file_proto.package, index, file_descriptor, + is_extension=True) extension_desc.containing_type = self._GetTypeFromScope( file_descriptor.package, extension_proto.extendee, scope) self._SetFieldType(extension_proto, extension_desc, @@ -623,10 +628,10 @@ class DescriptorPool(object): enums = [ self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope) for enum in desc_proto.enum_type] - fields = [self._MakeFieldDescriptor(field, desc_name, index) + fields = [self._MakeFieldDescriptor(field, desc_name, index, file_desc) for index, field in enumerate(desc_proto.field)] extensions = [ - self._MakeFieldDescriptor(extension, desc_name, index, + self._MakeFieldDescriptor(extension, desc_name, index, file_desc, is_extension=True) for index, extension in enumerate(desc_proto.extension)] oneofs = [ @@ -708,7 +713,7 @@ class DescriptorPool(object): return desc def _MakeFieldDescriptor(self, field_proto, message_name, index, - is_extension=False): + file_desc, is_extension=False): """Creates a field descriptor from a FieldDescriptorProto. For message and enum type fields, this method will do a look up @@ -721,6 +726,7 @@ class DescriptorPool(object): field_proto: The proto describing the field. message_name: The name of the containing message. index: Index of the field + file_desc: The file containing the field descriptor. is_extension: Indication that this field is for an extension. Returns: @@ -747,7 +753,8 @@ class DescriptorPool(object): default_value=None, is_extension=is_extension, extension_scope=None, - options=_OptionsOrNone(field_proto)) + options=_OptionsOrNone(field_proto), + file=file_desc) def _SetAllFieldTypes(self, package, desc_proto, scope): """Sets all the descriptor's fields's types. diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py index 460a4a6c..422af590 100755 --- a/python/google/protobuf/internal/api_implementation.py +++ b/python/google/protobuf/internal/api_implementation.py @@ -100,6 +100,27 @@ if _implementation_version_str != '2': _implementation_version = int(_implementation_version_str) +# Detect if serialization should be deterministic by default +try: + # The presence of this module in a build allows the proto implementation to + # be upgraded merely via build deps. + # + # NOTE: Merely importing this automatically enables deterministic proto + # serialization for C++ code, but we still need to export it as a boolean so + # that we can do the same for `_implementation_type == 'python'`. + # + # NOTE2: It is possible for C++ code to enable deterministic serialization by + # default _without_ affecting Python code, if the C++ implementation is not in + # use by this module. That is intended behavior, so we don't actually expose + # this boolean outside of this module. + # + # pylint: disable=g-import-not-at-top,unused-import + from google.protobuf import enable_deterministic_proto_serialization + _python_deterministic_proto_serialization = True +except ImportError: + _python_deterministic_proto_serialization = False + + # Usage of this function is discouraged. Clients shouldn't care which # implementation of the API is in use. Note that there is no guarantee # that differences between APIs will be maintained. @@ -111,3 +132,8 @@ def Type(): # See comment on 'Type' above. def Version(): return _implementation_version + + +# For internal use only +def IsPythonDefaultSerializationDeterministic(): + return _python_deterministic_proto_serialization diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py index c1733a48..6015e6f8 100644 --- a/python/google/protobuf/internal/descriptor_pool_test.py +++ b/python/google/protobuf/internal/descriptor_pool_test.py @@ -131,11 +131,19 @@ class DescriptorPoolTest(unittest.TestCase): self.assertEqual('google/protobuf/internal/factory_test2.proto', file_desc4.name) + file_desc5 = self.pool.FindFileContainingSymbol( + 'protobuf_unittest.TestService') + self.assertIsInstance(file_desc5, descriptor.FileDescriptor) + self.assertEqual('google/protobuf/unittest.proto', + file_desc5.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') + assert descriptor_pool.Default().FindFileContainingSymbol( + 'protobuf_unittest.TestService') def testFindFileContainingSymbolFailure(self): with self.assertRaises(KeyError): @@ -506,10 +514,10 @@ class MessageType(object): subtype.CheckType(test, desc, name, file_desc) for index, (name, field) in enumerate(self.field_list): - field.CheckField(test, desc, name, index) + field.CheckField(test, desc, name, index, file_desc) for index, (name, field) in enumerate(self.extensions): - field.CheckField(test, desc, name, index) + field.CheckField(test, desc, name, index, file_desc) class EnumField(object): @@ -519,7 +527,7 @@ class EnumField(object): self.type_name = type_name self.default_value = default_value - def CheckField(self, test, msg_desc, name, index): + def CheckField(self, test, msg_desc, name, index, file_desc): field_desc = msg_desc.fields_by_name[name] enum_desc = msg_desc.enum_types_by_name[self.type_name] test.assertEqual(name, field_desc.name) @@ -536,6 +544,7 @@ class EnumField(object): test.assertFalse(enum_desc.values_by_name[self.default_value].has_options) test.assertEqual(msg_desc, field_desc.containing_type) test.assertEqual(enum_desc, field_desc.enum_type) + test.assertEqual(file_desc, enum_desc.file) class MessageField(object): @@ -544,7 +553,7 @@ class MessageField(object): self.number = number self.type_name = type_name - def CheckField(self, test, msg_desc, name, index): + def CheckField(self, test, msg_desc, name, index, file_desc): field_desc = msg_desc.fields_by_name[name] field_type_desc = msg_desc.nested_types_by_name[self.type_name] test.assertEqual(name, field_desc.name) @@ -558,6 +567,7 @@ class MessageField(object): test.assertFalse(field_desc.has_default_value) test.assertEqual(msg_desc, field_desc.containing_type) test.assertEqual(field_type_desc, field_desc.message_type) + test.assertEqual(file_desc, field_desc.file) class StringField(object): @@ -566,7 +576,7 @@ class StringField(object): self.number = number self.default_value = default_value - def CheckField(self, test, msg_desc, name, index): + def CheckField(self, test, msg_desc, name, index, file_desc): field_desc = msg_desc.fields_by_name[name] test.assertEqual(name, field_desc.name) expected_field_full_name = '.'.join([msg_desc.full_name, name]) @@ -578,6 +588,7 @@ class StringField(object): field_desc.cpp_type) test.assertTrue(field_desc.has_default_value) test.assertEqual(self.default_value, field_desc.default_value) + test.assertEqual(file_desc, field_desc.file) class ExtensionField(object): @@ -586,7 +597,7 @@ class ExtensionField(object): self.number = number self.extended_type = extended_type - def CheckField(self, test, msg_desc, name, index): + def CheckField(self, test, msg_desc, name, index, file_desc): field_desc = msg_desc.extensions_by_name[name] test.assertEqual(name, field_desc.name) expected_field_full_name = '.'.join([msg_desc.full_name, name]) @@ -601,6 +612,7 @@ class ExtensionField(object): test.assertEqual(msg_desc, field_desc.extension_scope) test.assertEqual(msg_desc, field_desc.message_type) test.assertEqual(self.extended_type, field_desc.containing_type.name) + test.assertEqual(file_desc, field_desc.file) class AddDescriptorTest(unittest.TestCase): @@ -746,15 +758,10 @@ class AddDescriptorTest(unittest.TestCase): self.assertIs(options, file_descriptor.GetOptions()) -@unittest.skipIf( - api_implementation.Type() != 'cpp', - 'default_pool is only supported by the C++ implementation') class DefaultPoolTest(unittest.TestCase): def testFindMethods(self): - # pylint: disable=g-import-not-at-top - from google.protobuf.pyext import _message - pool = _message.default_pool + pool = descriptor_pool.Default() self.assertIs( pool.FindFileByName('google/protobuf/unittest.proto'), unittest_pb2.DESCRIPTOR) @@ -765,19 +772,22 @@ class DefaultPoolTest(unittest.TestCase): pool.FindFieldByName('protobuf_unittest.TestAllTypes.optional_int32'), unittest_pb2.TestAllTypes.DESCRIPTOR.fields_by_name['optional_int32']) self.assertIs( - pool.FindExtensionByName('protobuf_unittest.optional_int32_extension'), - unittest_pb2.DESCRIPTOR.extensions_by_name['optional_int32_extension']) - self.assertIs( pool.FindEnumTypeByName('protobuf_unittest.ForeignEnum'), unittest_pb2.ForeignEnum.DESCRIPTOR) + if api_implementation.Type() != 'cpp': + self.skipTest('Only the C++ implementation correctly indexes all types') + self.assertIs( + pool.FindExtensionByName('protobuf_unittest.optional_int32_extension'), + unittest_pb2.DESCRIPTOR.extensions_by_name['optional_int32_extension']) self.assertIs( pool.FindOneofByName('protobuf_unittest.TestAllTypes.oneof_field'), unittest_pb2.TestAllTypes.DESCRIPTOR.oneofs_by_name['oneof_field']) + self.assertIs( + pool.FindServiceByName('protobuf_unittest.TestService'), + unittest_pb2.DESCRIPTOR.services_by_name['TestService']) def testAddFileDescriptor(self): - # pylint: disable=g-import-not-at-top - from google.protobuf.pyext import _message - pool = _message.default_pool + pool = descriptor_pool.Default() file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto') pool.Add(file_desc) pool.AddSerializedFile(file_desc.SerializeToString()) diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py index 1f148ab9..c0010081 100755 --- a/python/google/protobuf/internal/descriptor_test.py +++ b/python/google/protobuf/internal/descriptor_test.py @@ -521,6 +521,12 @@ class GeneratedDescriptorTest(unittest.TestCase): del enum self.assertEqual('FOO', next(values_iter).name) + def testServiceDescriptor(self): + service_descriptor = unittest_pb2.DESCRIPTOR.services_by_name['TestService'] + self.assertEqual(service_descriptor.name, 'TestService') + self.assertEqual(service_descriptor.methods[0].name, 'Foo') + self.assertIs(service_descriptor.file, unittest_pb2.DESCRIPTOR) + class DescriptorCopyToProtoTest(unittest.TestCase): """Tests for CopyTo functions of Descriptor.""" diff --git a/python/google/protobuf/internal/encoder.py b/python/google/protobuf/internal/encoder.py index 80e59cab..ebec42e5 100755 --- a/python/google/protobuf/internal/encoder.py +++ b/python/google/protobuf/internal/encoder.py @@ -372,7 +372,7 @@ def MapSizer(field_descriptor, is_message_map): def _VarintEncoder(): """Return an encoder for a basic varint value (does not include tag).""" - def EncodeVarint(write, value): + def EncodeVarint(write, value, unused_deterministic): bits = value & 0x7f value >>= 7 while value: @@ -388,7 +388,7 @@ def _SignedVarintEncoder(): """Return an encoder for a basic signed varint value (does not include tag).""" - def EncodeSignedVarint(write, value): + def EncodeSignedVarint(write, value, unused_deterministic): if value < 0: value += (1 << 64) bits = value & 0x7f @@ -411,7 +411,7 @@ def _VarintBytes(value): called at startup time so it doesn't need to be fast.""" pieces = [] - _EncodeVarint(pieces.append, value) + _EncodeVarint(pieces.append, value, True) return b"".join(pieces) @@ -440,27 +440,27 @@ def _SimpleEncoder(wire_type, encode_value, compute_value_size): if is_packed: tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value): + def EncodePackedField(write, value, deterministic): write(tag_bytes) size = 0 for element in value: size += compute_value_size(element) - local_EncodeVarint(write, size) + local_EncodeVarint(write, size, deterministic) for element in value: - encode_value(write, element) + encode_value(write, element, deterministic) return EncodePackedField elif is_repeated: tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value): + def EncodeRepeatedField(write, value, deterministic): for element in value: write(tag_bytes) - encode_value(write, element) + encode_value(write, element, deterministic) return EncodeRepeatedField else: tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value): + def EncodeField(write, value, deterministic): write(tag_bytes) - return encode_value(write, value) + return encode_value(write, value, deterministic) return EncodeField return SpecificEncoder @@ -474,27 +474,27 @@ def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value): if is_packed: tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value): + def EncodePackedField(write, value, deterministic): write(tag_bytes) size = 0 for element in value: size += compute_value_size(modify_value(element)) - local_EncodeVarint(write, size) + local_EncodeVarint(write, size, deterministic) for element in value: - encode_value(write, modify_value(element)) + encode_value(write, modify_value(element), deterministic) return EncodePackedField elif is_repeated: tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value): + def EncodeRepeatedField(write, value, deterministic): for element in value: write(tag_bytes) - encode_value(write, modify_value(element)) + encode_value(write, modify_value(element), deterministic) return EncodeRepeatedField else: tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value): + def EncodeField(write, value, deterministic): write(tag_bytes) - return encode_value(write, modify_value(value)) + return encode_value(write, modify_value(value), deterministic) return EncodeField return SpecificEncoder @@ -515,22 +515,22 @@ def _StructPackEncoder(wire_type, format): if is_packed: tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value): + def EncodePackedField(write, value, deterministic): write(tag_bytes) - local_EncodeVarint(write, len(value) * value_size) + local_EncodeVarint(write, len(value) * value_size, deterministic) for element in value: write(local_struct_pack(format, element)) return EncodePackedField elif is_repeated: tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value): + def EncodeRepeatedField(write, value, unused_deterministic): for element in value: write(tag_bytes) write(local_struct_pack(format, element)) return EncodeRepeatedField else: tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value): + def EncodeField(write, value, unused_deterministic): write(tag_bytes) return write(local_struct_pack(format, value)) return EncodeField @@ -581,9 +581,9 @@ def _FloatingPointEncoder(wire_type, format): if is_packed: tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value): + def EncodePackedField(write, value, deterministic): write(tag_bytes) - local_EncodeVarint(write, len(value) * value_size) + local_EncodeVarint(write, len(value) * value_size, deterministic) for element in value: # This try/except block is going to be faster than any code that # we could write to check whether element is finite. @@ -594,7 +594,7 @@ def _FloatingPointEncoder(wire_type, format): return EncodePackedField elif is_repeated: tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value): + def EncodeRepeatedField(write, value, unused_deterministic): for element in value: write(tag_bytes) try: @@ -604,7 +604,7 @@ def _FloatingPointEncoder(wire_type, format): return EncodeRepeatedField else: tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value): + def EncodeField(write, value, unused_deterministic): write(tag_bytes) try: write(local_struct_pack(format, value)) @@ -650,9 +650,9 @@ def BoolEncoder(field_number, is_repeated, is_packed): if is_packed: tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value): + def EncodePackedField(write, value, deterministic): write(tag_bytes) - local_EncodeVarint(write, len(value)) + local_EncodeVarint(write, len(value), deterministic) for element in value: if element: write(true_byte) @@ -661,7 +661,7 @@ def BoolEncoder(field_number, is_repeated, is_packed): return EncodePackedField elif is_repeated: tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) - def EncodeRepeatedField(write, value): + def EncodeRepeatedField(write, value, unused_deterministic): for element in value: write(tag_bytes) if element: @@ -671,7 +671,7 @@ def BoolEncoder(field_number, is_repeated, is_packed): return EncodeRepeatedField else: tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT) - def EncodeField(write, value): + def EncodeField(write, value, unused_deterministic): write(tag_bytes) if value: return write(true_byte) @@ -687,18 +687,18 @@ def StringEncoder(field_number, is_repeated, is_packed): local_len = len assert not is_packed if is_repeated: - def EncodeRepeatedField(write, value): + def EncodeRepeatedField(write, value, deterministic): for element in value: encoded = element.encode('utf-8') write(tag) - local_EncodeVarint(write, local_len(encoded)) + local_EncodeVarint(write, local_len(encoded), deterministic) write(encoded) return EncodeRepeatedField else: - def EncodeField(write, value): + def EncodeField(write, value, deterministic): encoded = value.encode('utf-8') write(tag) - local_EncodeVarint(write, local_len(encoded)) + local_EncodeVarint(write, local_len(encoded), deterministic) return write(encoded) return EncodeField @@ -711,16 +711,16 @@ def BytesEncoder(field_number, is_repeated, is_packed): local_len = len assert not is_packed if is_repeated: - def EncodeRepeatedField(write, value): + def EncodeRepeatedField(write, value, deterministic): for element in value: write(tag) - local_EncodeVarint(write, local_len(element)) + local_EncodeVarint(write, local_len(element), deterministic) write(element) return EncodeRepeatedField else: - def EncodeField(write, value): + def EncodeField(write, value, deterministic): write(tag) - local_EncodeVarint(write, local_len(value)) + local_EncodeVarint(write, local_len(value), deterministic) return write(value) return EncodeField @@ -732,16 +732,16 @@ def GroupEncoder(field_number, is_repeated, is_packed): end_tag = TagBytes(field_number, wire_format.WIRETYPE_END_GROUP) assert not is_packed if is_repeated: - def EncodeRepeatedField(write, value): + def EncodeRepeatedField(write, value, deterministic): for element in value: write(start_tag) - element._InternalSerialize(write) + element._InternalSerialize(write, deterministic) write(end_tag) return EncodeRepeatedField else: - def EncodeField(write, value): + def EncodeField(write, value, deterministic): write(start_tag) - value._InternalSerialize(write) + value._InternalSerialize(write, deterministic) return write(end_tag) return EncodeField @@ -753,17 +753,17 @@ def MessageEncoder(field_number, is_repeated, is_packed): local_EncodeVarint = _EncodeVarint assert not is_packed if is_repeated: - def EncodeRepeatedField(write, value): + def EncodeRepeatedField(write, value, deterministic): for element in value: write(tag) - local_EncodeVarint(write, element.ByteSize()) - element._InternalSerialize(write) + local_EncodeVarint(write, element.ByteSize(), deterministic) + element._InternalSerialize(write, deterministic) return EncodeRepeatedField else: - def EncodeField(write, value): + def EncodeField(write, value, deterministic): write(tag) - local_EncodeVarint(write, value.ByteSize()) - return value._InternalSerialize(write) + local_EncodeVarint(write, value.ByteSize(), deterministic) + return value._InternalSerialize(write, deterministic) return EncodeField @@ -790,10 +790,10 @@ def MessageSetItemEncoder(field_number): end_bytes = TagBytes(1, wire_format.WIRETYPE_END_GROUP) local_EncodeVarint = _EncodeVarint - def EncodeField(write, value): + def EncodeField(write, value, deterministic): write(start_bytes) - local_EncodeVarint(write, value.ByteSize()) - value._InternalSerialize(write) + local_EncodeVarint(write, value.ByteSize(), deterministic) + value._InternalSerialize(write, deterministic) return write(end_bytes) return EncodeField @@ -818,9 +818,10 @@ def MapEncoder(field_descriptor): message_type = field_descriptor.message_type encode_message = MessageEncoder(field_descriptor.number, False, False) - def EncodeField(write, value): - for key in value: + def EncodeField(write, value, deterministic): + value_keys = sorted(value.keys()) if deterministic else value.keys() + for key in value_keys: entry_msg = message_type._concrete_class(key=key, value=value[key]) - encode_message(write, entry_msg) + encode_message(write, entry_msg, deterministic) return EncodeField diff --git a/python/google/protobuf/internal/factory_test2.proto b/python/google/protobuf/internal/factory_test2.proto index bb1b54ad..5fcbc5ac 100644 --- a/python/google/protobuf/internal/factory_test2.proto +++ b/python/google/protobuf/internal/factory_test2.proto @@ -97,3 +97,8 @@ message MessageWithNestedEnumOnly { extend Factory1Message { optional string another_field = 1002; } + +message MessageWithOption { + option no_standard_descriptor_accessor = true; + optional int32 field1 = 1; +} diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py index 5ed65622..077b64db 100644 --- a/python/google/protobuf/internal/json_format_test.py +++ b/python/google/protobuf/internal/json_format_test.py @@ -49,6 +49,7 @@ from google.protobuf import field_mask_pb2 from google.protobuf import struct_pb2 from google.protobuf import timestamp_pb2 from google.protobuf import wrappers_pb2 +from google.protobuf import unittest_mset_pb2 from google.protobuf.internal import well_known_types from google.protobuf import json_format from google.protobuf.util import json_format_proto3_pb2 @@ -158,6 +159,84 @@ class JsonFormatTest(JsonFormatBase): json_format.Parse(text, parsed_message) self.assertEqual(message, parsed_message) + def testExtensionToJsonAndBack(self): + message = unittest_mset_pb2.TestMessageSetContainer() + ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension + ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension + message.message_set.Extensions[ext1].i = 23 + message.message_set.Extensions[ext2].str = 'foo' + message_text = json_format.MessageToJson( + message + ) + parsed_message = unittest_mset_pb2.TestMessageSetContainer() + json_format.Parse(message_text, parsed_message) + self.assertEqual(message, parsed_message) + + def testExtensionToDictAndBack(self): + message = unittest_mset_pb2.TestMessageSetContainer() + ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension + ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension + message.message_set.Extensions[ext1].i = 23 + message.message_set.Extensions[ext2].str = 'foo' + message_dict = json_format.MessageToDict( + message + ) + parsed_message = unittest_mset_pb2.TestMessageSetContainer() + json_format.ParseDict(message_dict, parsed_message) + self.assertEqual(message, parsed_message) + + def testExtensionSerializationDictMatchesProto3Spec(self): + """See go/proto3-json-spec for spec. + """ + message = unittest_mset_pb2.TestMessageSetContainer() + ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension + ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension + message.message_set.Extensions[ext1].i = 23 + message.message_set.Extensions[ext2].str = 'foo' + message_dict = json_format.MessageToDict( + message + ) + golden_dict = { + 'messageSet': { + '[protobuf_unittest.' + 'TestMessageSetExtension1.messageSetExtension]': { + 'i': 23, + }, + '[protobuf_unittest.' + 'TestMessageSetExtension2.messageSetExtension]': { + 'str': u'foo', + }, + }, + } + self.assertEqual(golden_dict, message_dict) + + + def testExtensionSerializationJsonMatchesProto3Spec(self): + """See go/proto3-json-spec for spec. + """ + message = unittest_mset_pb2.TestMessageSetContainer() + ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension + ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension + message.message_set.Extensions[ext1].i = 23 + message.message_set.Extensions[ext2].str = 'foo' + message_text = json_format.MessageToJson( + message + ) + ext1_text = ('protobuf_unittest.TestMessageSetExtension1.' + 'messageSetExtension') + ext2_text = ('protobuf_unittest.TestMessageSetExtension2.' + 'messageSetExtension') + golden_text = ('{"messageSet": {' + ' "[%s]": {' + ' "i": 23' + ' },' + ' "[%s]": {' + ' "str": "foo"' + ' }' + '}}') % (ext1_text, ext2_text) + self.assertEqual(json.loads(golden_text), json.loads(message_text)) + + def testJsonEscapeString(self): message = json_format_proto3_pb2.TestMessage() if sys.version_info[0] < 3: @@ -768,7 +847,7 @@ class JsonFormatTest(JsonFormatBase): text = '{"value": "0000-01-01T00:00:00Z"}' self.assertRaisesRegexp( json_format.ParseError, - 'Failed to parse value field: year is out of range.', + 'Failed to parse value field: year (0 )?is out of range.', json_format.Parse, text, message) # Time bigger than maxinum time. message.value.seconds = 253402300800 @@ -840,6 +919,12 @@ class JsonFormatTest(JsonFormatBase): json_format.Parse('{"int32_value": 12345}', message) self.assertEqual(12345, message.int32_value) + def testIndent(self): + message = json_format_proto3_pb2.TestMessage() + message.int32_value = 12345 + self.assertEqual('{\n"int32Value": 12345\n}', + json_format.MessageToJson(message, indent=0)) + def testParseDict(self): expected = 12345 js_dict = {'int32Value': expected} @@ -862,6 +947,22 @@ class JsonFormatTest(JsonFormatBase): parsed_message = json_format_proto3_pb2.TestCustomJsonName() self.CheckParseBack(message, parsed_message) + def testSortKeys(self): + # Testing sort_keys is not perfectly working, as by random luck we could + # get the output sorted. We just use a selection of names. + message = json_format_proto3_pb2.TestMessage(bool_value=True, + int32_value=1, + int64_value=3, + uint32_value=4, + string_value='bla') + self.assertEqual( + json_format.MessageToJson(message, sort_keys=True), + # We use json.dumps() instead of a hardcoded string due to differences + # between Python 2 and Python 3. + json.dumps({'boolValue': True, 'int32Value': 1, 'int64Value': '3', + 'uint32Value': 4, 'stringValue': 'bla'}, + indent=2, sort_keys=True)) + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index 3373b21f..dda72cdd 100755 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -140,6 +140,42 @@ class MessageTest(BaseTestCase): golden_copy = copy.deepcopy(golden_message) self.assertEqual(golden_data, golden_copy.SerializeToString()) + def testDeterminismParameters(self, message_module): + # This message is always deterministically serialized, even if determinism + # is disabled, so we can use it to verify that all the determinism + # parameters work correctly. + golden_data = (b'\xe2\x02\nOne string' + b'\xe2\x02\nTwo string' + b'\xe2\x02\nRed string' + b'\xe2\x02\x0bBlue string') + golden_message = message_module.TestAllTypes() + golden_message.repeated_string.extend([ + 'One string', + 'Two string', + 'Red string', + 'Blue string', + ]) + self.assertEqual(golden_data, + golden_message.SerializeToString(deterministic=None)) + self.assertEqual(golden_data, + golden_message.SerializeToString(deterministic=False)) + self.assertEqual(golden_data, + golden_message.SerializeToString(deterministic=True)) + + class BadArgError(Exception): + pass + + class BadArg(object): + + def __nonzero__(self): + raise BadArgError() + + def __bool__(self): + raise BadArgError() + + with self.assertRaises(BadArgError): + golden_message.SerializeToString(deterministic=BadArg()) + def testPickleSupport(self, message_module): golden_data = test_util.GoldenFileData('golden_message') golden_message = message_module.TestAllTypes() @@ -381,6 +417,7 @@ class MessageTest(BaseTestCase): self.assertEqual(message.repeated_int32[0], 1) self.assertEqual(message.repeated_int32[1], 2) self.assertEqual(message.repeated_int32[2], 3) + self.assertEqual(str(message.repeated_int32), str([1, 2, 3])) message.repeated_float.append(1.1) message.repeated_float.append(1.3) @@ -397,6 +434,7 @@ class MessageTest(BaseTestCase): self.assertEqual(message.repeated_string[0], 'a') self.assertEqual(message.repeated_string[1], 'b') self.assertEqual(message.repeated_string[2], 'c') + self.assertEqual(str(message.repeated_string), str([u'a', u'b', u'c'])) message.repeated_bytes.append(b'a') message.repeated_bytes.append(b'c') @@ -405,6 +443,7 @@ class MessageTest(BaseTestCase): self.assertEqual(message.repeated_bytes[0], b'a') self.assertEqual(message.repeated_bytes[1], b'b') self.assertEqual(message.repeated_bytes[2], b'c') + self.assertEqual(str(message.repeated_bytes), str([b'a', b'b', b'c'])) def testSortingRepeatedScalarFieldsCustomComparator(self, message_module): """Check some different types with custom comparator.""" @@ -443,6 +482,8 @@ class MessageTest(BaseTestCase): self.assertEqual(message.repeated_nested_message[3].bb, 4) self.assertEqual(message.repeated_nested_message[4].bb, 5) self.assertEqual(message.repeated_nested_message[5].bb, 6) + self.assertEqual(str(message.repeated_nested_message), + '[bb: 1\n, bb: 2\n, bb: 3\n, bb: 4\n, bb: 5\n, bb: 6\n]') def testSortingRepeatedCompositeFieldsStable(self, message_module): """Check passing a custom comparator to sort a repeated composite field.""" @@ -1270,6 +1311,14 @@ class Proto3Test(BaseTestCase): self.assertEqual(1234567, m2.optional_nested_enum) self.assertEqual(7654321, m2.repeated_nested_enum[0]) + # ParseFromString in Proto2 should accept unknown enums too. + m3 = unittest_pb2.TestAllTypes() + m3.ParseFromString(serialized) + m2.Clear() + m2.ParseFromString(m3.SerializeToString()) + self.assertEqual(1234567, m2.optional_nested_enum) + self.assertEqual(7654321, m2.repeated_nested_enum[0]) + # Map isn't really a proto3-only feature. But there is no proto2 equivalent # of google/protobuf/map_unittest.proto right now, so it's not easy to # test both with the same test like we do for the other proto2/proto3 tests. @@ -1441,6 +1490,23 @@ class Proto3Test(BaseTestCase): self.assertIn(-456, msg2.map_int32_foreign_message) self.assertEqual(2, len(msg2.map_int32_foreign_message)) + def testNestedMessageMapItemDelete(self): + msg = map_unittest_pb2.TestMap() + msg.map_int32_all_types[1].optional_nested_message.bb = 1 + del msg.map_int32_all_types[1] + msg.map_int32_all_types[2].optional_nested_message.bb = 2 + self.assertEqual(1, len(msg.map_int32_all_types)) + msg.map_int32_all_types[1].optional_nested_message.bb = 1 + self.assertEqual(2, len(msg.map_int32_all_types)) + + serialized = msg.SerializeToString() + msg2 = map_unittest_pb2.TestMap() + msg2.ParseFromString(serialized) + keys = [1, 2] + # The loop triggers PyErr_Occurred() in c extension. + for key in keys: + del msg2.map_int32_all_types[key] + def testMapByteSize(self): msg = map_unittest_pb2.TestMap() msg.map_int32_int32[1] = 1 @@ -1655,6 +1721,35 @@ class Proto3Test(BaseTestCase): items2 = msg.map_string_string.items() self.assertEqual(items1, items2) + def testMapDeterministicSerialization(self): + golden_data = (b'r\x0c\n\x07init_op\x12\x01d' + b'r\n\n\x05item1\x12\x01e' + b'r\n\n\x05item2\x12\x01f' + b'r\n\n\x05item3\x12\x01g' + b'r\x0b\n\x05item4\x12\x02QQ' + b'r\x12\n\rlocal_init_op\x12\x01a' + b'r\x0e\n\tsummaries\x12\x01e' + b'r\x18\n\x13trainable_variables\x12\x01b' + b'r\x0e\n\tvariables\x12\x01c') + msg = map_unittest_pb2.TestMap() + msg.map_string_string['local_init_op'] = 'a' + msg.map_string_string['trainable_variables'] = 'b' + msg.map_string_string['variables'] = 'c' + msg.map_string_string['init_op'] = 'd' + msg.map_string_string['summaries'] = 'e' + msg.map_string_string['item1'] = 'e' + msg.map_string_string['item2'] = 'f' + msg.map_string_string['item3'] = 'g' + msg.map_string_string['item4'] = 'QQ' + + # If deterministic serialization is not working correctly, this will be + # "flaky" depending on the exact python dict hash seed. + # + # Fortunately, there are enough items in this map that it is extremely + # unlikely to ever hit the "right" in-order combination, so the test + # itself should fail reliably. + self.assertEqual(golden_data, msg.SerializeToString(deterministic=True)) + def testMapIterationClearMessage(self): # Iterator needs to work even if message and map are deleted. msg = map_unittest_pb2.TestMap() diff --git a/python/google/protobuf/internal/more_extensions_dynamic.proto b/python/google/protobuf/internal/more_extensions_dynamic.proto index 11f85ef6..98fcbcb6 100644 --- a/python/google/protobuf/internal/more_extensions_dynamic.proto +++ b/python/google/protobuf/internal/more_extensions_dynamic.proto @@ -47,4 +47,5 @@ message DynamicMessageType { extend ExtendedMessage { optional int32 dynamic_int32_extension = 100; optional DynamicMessageType dynamic_message_extension = 101; + repeated DynamicMessageType repeated_dynamic_message_extension = 102; } diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py index cb97cb28..c363d843 100755 --- a/python/google/protobuf/internal/python_message.py +++ b/python/google/protobuf/internal/python_message.py @@ -58,6 +58,7 @@ import weakref import six # We use "as" to avoid name collisions with variables. +from google.protobuf.internal import api_implementation from google.protobuf.internal import containers from google.protobuf.internal import decoder from google.protobuf.internal import encoder @@ -1026,29 +1027,34 @@ def _AddByteSizeMethod(message_descriptor, cls): def _AddSerializeToStringMethod(message_descriptor, cls): """Helper for _AddMessageMethods().""" - def SerializeToString(self): + def SerializeToString(self, **kwargs): # Check if the message has all of its required fields set. errors = [] if not self.IsInitialized(): raise message_mod.EncodeError( 'Message %s is missing required fields: %s' % ( self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors()))) - return self.SerializePartialToString() + return self.SerializePartialToString(**kwargs) cls.SerializeToString = SerializeToString def _AddSerializePartialToStringMethod(message_descriptor, cls): """Helper for _AddMessageMethods().""" - def SerializePartialToString(self): + def SerializePartialToString(self, **kwargs): out = BytesIO() - self._InternalSerialize(out.write) + self._InternalSerialize(out.write, **kwargs) return out.getvalue() cls.SerializePartialToString = SerializePartialToString - def InternalSerialize(self, write_bytes): + def InternalSerialize(self, write_bytes, deterministic=None): + if deterministic is None: + deterministic = ( + api_implementation.IsPythonDefaultSerializationDeterministic()) + else: + deterministic = bool(deterministic) for field_descriptor, field_value in self.ListFields(): - field_descriptor._encoder(write_bytes, field_value) + field_descriptor._encoder(write_bytes, field_value, deterministic) for tag_bytes, value_bytes in self._unknown_fields: write_bytes(tag_bytes) write_bytes(value_bytes) diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py index 188310b2..424b29cc 100755 --- a/python/google/protobuf/internal/text_format_test.py +++ b/python/google/protobuf/internal/text_format_test.py @@ -452,16 +452,18 @@ class TextFormatTest(TextFormatBase): text_format.Parse(text_format.MessageToString(m), m2) self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field')) + def testMergeMultipleOneof(self, message_module): + m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"']) + m2 = message_module.TestAllTypes() + text_format.Merge(m_string, m2) + self.assertEqual('oneof_string', m2.WhichOneof('oneof_field')) + def testParseMultipleOneof(self, message_module): m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"']) m2 = message_module.TestAllTypes() - if message_module is unittest_pb2: - with self.assertRaisesRegexp(text_format.ParseError, - ' is specified along with field '): - text_format.Parse(m_string, m2) - else: + with self.assertRaisesRegexp(text_format.ParseError, + ' is specified along with field '): text_format.Parse(m_string, m2) - self.assertEqual('oneof_string', m2.WhichOneof('oneof_field')) # These are tests that aren't fundamentally specific to proto2, but are at @@ -1026,8 +1028,7 @@ class Proto3Tests(unittest.TestCase): packed_message.data = 'string1' message.repeated_any_value.add().Pack(packed_message) self.assertEqual( - text_format.MessageToString(message, - descriptor_pool=descriptor_pool.Default()), + text_format.MessageToString(message), 'repeated_any_value {\n' ' [type.googleapis.com/protobuf_unittest.OneString] {\n' ' data: "string0"\n' @@ -1039,18 +1040,6 @@ class Proto3Tests(unittest.TestCase): ' }\n' '}\n') - def testPrintMessageExpandAnyNoDescriptorPool(self): - packed_message = unittest_pb2.OneString() - packed_message.data = 'string' - message = any_test_pb2.TestAny() - message.any_value.Pack(packed_message) - self.assertEqual( - text_format.MessageToString(message, descriptor_pool=None), - 'any_value {\n' - ' type_url: "type.googleapis.com/protobuf_unittest.OneString"\n' - ' value: "\\n\\006string"\n' - '}\n') - def testPrintMessageExpandAnyDescriptorPoolMissingType(self): packed_message = unittest_pb2.OneString() packed_message.data = 'string' @@ -1071,8 +1060,7 @@ class Proto3Tests(unittest.TestCase): message.any_value.Pack(packed_message) self.assertEqual( text_format.MessageToString(message, - pointy_brackets=True, - descriptor_pool=descriptor_pool.Default()), + pointy_brackets=True), 'any_value <\n' ' [type.googleapis.com/protobuf_unittest.OneString] <\n' ' data: "string"\n' @@ -1086,8 +1074,7 @@ class Proto3Tests(unittest.TestCase): message.any_value.Pack(packed_message) self.assertEqual( text_format.MessageToString(message, - as_one_line=True, - descriptor_pool=descriptor_pool.Default()), + as_one_line=True), 'any_value {' ' [type.googleapis.com/protobuf_unittest.OneString]' ' { data: "string" } ' @@ -1115,12 +1102,12 @@ class Proto3Tests(unittest.TestCase): ' data: "string"\n' ' }\n' '}\n') - text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default()) + text_format.Merge(text, message) 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()) + text_format.Parse(text, message) packed_message = unittest_pb2.OneString() message.any_value.Unpack(packed_message) self.assertEqual('string', packed_message.data) @@ -1137,7 +1124,7 @@ class Proto3Tests(unittest.TestCase): ' data: "string1"\n' ' }\n' '}\n') - text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default()) + text_format.Merge(text, message) packed_message = unittest_pb2.OneString() message.repeated_any_value[0].Unpack(packed_message) self.assertEqual('string0', packed_message.data) @@ -1151,22 +1138,22 @@ class Proto3Tests(unittest.TestCase): ' data: "string"\n' ' >\n' '}\n') - text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default()) + text_format.Merge(text, message) packed_message = unittest_pb2.OneString() message.any_value.Unpack(packed_message) self.assertEqual('string', packed_message.data) - def testMergeExpandedAnyNoDescriptorPool(self): + def testMergeAlternativeUrl(self): message = any_test_pb2.TestAny() text = ('any_value {\n' - ' [type.googleapis.com/protobuf_unittest.OneString] {\n' + ' [type.otherapi.com/protobuf_unittest.OneString] {\n' ' data: "string"\n' ' }\n' '}\n') - with self.assertRaises(text_format.ParseError) as e: - text_format.Merge(text, message, descriptor_pool=None) - self.assertEqual(str(e.exception), - 'Descriptor pool required to parse expanded Any field') + text_format.Merge(text, message) + packed_message = unittest_pb2.OneString() + self.assertEqual('type.otherapi.com/protobuf_unittest.OneString', + message.any_value.type_url) def testMergeExpandedAnyDescriptorPoolMissingType(self): message = any_test_pb2.TestAny() @@ -1425,5 +1412,101 @@ class TokenizerTest(unittest.TestCase): tokenizer.ConsumeCommentOrTrailingComment()) self.assertTrue(tokenizer.AtEnd()) + +# Tests for pretty printer functionality. +@_parameterized.Parameters((unittest_pb2), (unittest_proto3_arena_pb2)) +class PrettyPrinterTest(TextFormatBase): + + def testPrettyPrintNoMatch(self, message_module): + + def printer(message, indent, as_one_line): + del message, indent, as_one_line + return None + + message = message_module.TestAllTypes() + msg = message.repeated_nested_message.add() + msg.bb = 42 + self.CompareToGoldenText( + text_format.MessageToString( + message, as_one_line=True, message_formatter=printer), + 'repeated_nested_message { bb: 42 }') + + def testPrettyPrintOneLine(self, message_module): + + def printer(m, indent, as_one_line): + del indent, as_one_line + if m.DESCRIPTOR == message_module.TestAllTypes.NestedMessage.DESCRIPTOR: + return 'My lucky number is %s' % m.bb + + message = message_module.TestAllTypes() + msg = message.repeated_nested_message.add() + msg.bb = 42 + self.CompareToGoldenText( + text_format.MessageToString( + message, as_one_line=True, message_formatter=printer), + 'repeated_nested_message { My lucky number is 42 }') + + def testPrettyPrintMultiLine(self, message_module): + + def printer(m, indent, as_one_line): + if m.DESCRIPTOR == message_module.TestAllTypes.NestedMessage.DESCRIPTOR: + line_deliminator = (' ' if as_one_line else '\n') + ' ' * indent + return 'My lucky number is:%s%s' % (line_deliminator, m.bb) + return None + + message = message_module.TestAllTypes() + msg = message.repeated_nested_message.add() + msg.bb = 42 + self.CompareToGoldenText( + text_format.MessageToString( + message, as_one_line=True, message_formatter=printer), + 'repeated_nested_message { My lucky number is: 42 }') + self.CompareToGoldenText( + text_format.MessageToString( + message, as_one_line=False, message_formatter=printer), + 'repeated_nested_message {\n My lucky number is:\n 42\n}\n') + + def testPrettyPrintEntireMessage(self, message_module): + + def printer(m, indent, as_one_line): + del indent, as_one_line + if m.DESCRIPTOR == message_module.TestAllTypes.DESCRIPTOR: + return 'The is the message!' + return None + + message = message_module.TestAllTypes() + self.CompareToGoldenText( + text_format.MessageToString( + message, as_one_line=False, message_formatter=printer), + 'The is the message!\n') + self.CompareToGoldenText( + text_format.MessageToString( + message, as_one_line=True, message_formatter=printer), + 'The is the message!') + + def testPrettyPrintMultipleParts(self, message_module): + + def printer(m, indent, as_one_line): + del indent, as_one_line + if m.DESCRIPTOR == message_module.TestAllTypes.NestedMessage.DESCRIPTOR: + return 'My lucky number is %s' % m.bb + return None + + message = message_module.TestAllTypes() + message.optional_int32 = 61 + msg = message.repeated_nested_message.add() + msg.bb = 42 + msg = message.repeated_nested_message.add() + msg.bb = 99 + msg = message.optional_nested_message + msg.bb = 1 + self.CompareToGoldenText( + text_format.MessageToString( + message, as_one_line=True, message_formatter=printer), + ('optional_int32: 61 ' + 'optional_nested_message { My lucky number is 1 } ' + 'repeated_nested_message { My lucky number is 42 } ' + 'repeated_nested_message { My lucky number is 99 }')) + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/well_known_types.py b/python/google/protobuf/internal/well_known_types.py index d631abee..d0c7ffda 100644 --- a/python/google/protobuf/internal/well_known_types.py +++ b/python/google/protobuf/internal/well_known_types.py @@ -350,12 +350,12 @@ class Duration(object): self.nanos, _NANOS_PER_MICROSECOND)) def FromTimedelta(self, td): - """Convertd timedelta to Duration.""" + """Converts timedelta to Duration.""" self._NormalizeDuration(td.seconds + td.days * _SECONDS_PER_DAY, td.microseconds * _NANOS_PER_MICROSECOND) def _NormalizeDuration(self, seconds, nanos): - """Set Duration by seconds and nonas.""" + """Set Duration by seconds and nanos.""" # Force nanos to be negative if the duration is negative. if seconds < 0 and nanos > 0: seconds += 1 diff --git a/python/google/protobuf/internal/well_known_types_test.py b/python/google/protobuf/internal/well_known_types_test.py index 077f630f..123a537c 100644 --- a/python/google/protobuf/internal/well_known_types_test.py +++ b/python/google/protobuf/internal/well_known_types_test.py @@ -284,7 +284,7 @@ class TimeUtilTest(TimeUtilTestBase): '1972-01-01T01:00:00.01+08',) self.assertRaisesRegexp( ValueError, - 'year is out of range', + 'year (0 )?is out of range', message.FromJsonString, '0000-01-01T00:00:00Z') message.seconds = 253402300800 diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index 937285b0..801eed60 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -74,6 +74,9 @@ _UNPAIRED_SURROGATE_PATTERN = re.compile(six.u( r'[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]' )) +_VALID_EXTENSION_NAME = re.compile(r'\[[a-zA-Z0-9\._]*\]$') + + class Error(Exception): """Top-level module error for json_format.""" @@ -88,7 +91,9 @@ class ParseError(Error): def MessageToJson(message, including_default_value_fields=False, - preserving_proto_field_name=False): + preserving_proto_field_name=False, + indent=2, + sort_keys=False): """Converts protobuf message to JSON format. Args: @@ -100,19 +105,24 @@ def MessageToJson(message, preserving_proto_field_name: If True, use the original proto field names as defined in the .proto file. If False, convert the field names to lowerCamelCase. + indent: The JSON object will be pretty-printed with this indent level. + An indent level of 0 or negative will only insert newlines. + sort_keys: If True, then the output will be sorted by field names. Returns: A string containing the JSON formatted protocol buffer message. """ printer = _Printer(including_default_value_fields, preserving_proto_field_name) - return printer.ToJsonString(message) + return printer.ToJsonString(message, indent, sort_keys) def MessageToDict(message, including_default_value_fields=False, preserving_proto_field_name=False): - """Converts protobuf message to a JSON dictionary. + """Converts protobuf message to a dictionary. + + When the dictionary is encoded to JSON, it conforms to proto3 JSON spec. Args: message: The protocol buffers message instance to serialize. @@ -125,7 +135,7 @@ def MessageToDict(message, names to lowerCamelCase. Returns: - A dict representation of the JSON formatted protocol buffer message. + A dict representation of the protocol buffer message. """ printer = _Printer(including_default_value_fields, preserving_proto_field_name) @@ -148,9 +158,9 @@ class _Printer(object): self.including_default_value_fields = including_default_value_fields self.preserving_proto_field_name = preserving_proto_field_name - def ToJsonString(self, message): + def ToJsonString(self, message, indent, sort_keys): js = self._MessageToJsonObject(message) - return json.dumps(js, indent=2) + return json.dumps(js, indent=indent, sort_keys=sort_keys) def _MessageToJsonObject(self, message): """Converts message to an object according to Proto3 JSON Specification.""" @@ -192,6 +202,14 @@ class _Printer(object): # Convert a repeated field. js[name] = [self._FieldToJsonObject(field, k) for k in value] + elif field.is_extension: + f = field + if (f.containing_type.GetOptions().message_set_wire_format and + f.type == descriptor.FieldDescriptor.TYPE_MESSAGE and + f.label == descriptor.FieldDescriptor.LABEL_OPTIONAL): + f = f.message_type + name = '[%s.%s]' % (f.full_name, name) + js[name] = self._FieldToJsonObject(field, value) else: js[name] = self._FieldToJsonObject(field, value) @@ -433,12 +451,23 @@ class _Parser(object): field = fields_by_json_name.get(name, None) if not field: field = message_descriptor.fields_by_name.get(name, None) + if not field and _VALID_EXTENSION_NAME.match(name): + if not message_descriptor.is_extendable: + raise ParseError('Message type {0} does not have extensions'.format( + message_descriptor.full_name)) + identifier = name[1:-1] # strip [] brackets + identifier = '.'.join(identifier.split('.')[:-1]) + # pylint: disable=protected-access + field = message.Extensions._FindExtensionByName(identifier) + # pylint: enable=protected-access if not field: if self.ignore_unknown_fields: continue raise ParseError( - 'Message type "{0}" has no field named "{1}".'.format( - message_descriptor.full_name, name)) + ('Message type "{0}" has no field named "{1}".\n' + ' Available Fields(except extensions): {2}').format( + message_descriptor.full_name, name, + message_descriptor.fields)) if name in names: raise ParseError('Message type "{0}" should not have multiple ' '"{1}" fields.'.format( @@ -491,7 +520,10 @@ class _Parser(object): getattr(message, field.name).append( _ConvertScalarFieldValue(item, field)) elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - sub_message = getattr(message, field.name) + if field.is_extension: + sub_message = message.Extensions[field] + else: + sub_message = getattr(message, field.name) sub_message.SetInParent() self.ConvertMessage(value, sub_message) else: diff --git a/python/google/protobuf/message.py b/python/google/protobuf/message.py index aab250e4..eeb0d576 100755 --- a/python/google/protobuf/message.py +++ b/python/google/protobuf/message.py @@ -184,9 +184,15 @@ class Message(object): self.Clear() self.MergeFromString(serialized) - def SerializeToString(self): + def SerializeToString(self, **kwargs): """Serializes the protocol message to a binary string. + Arguments: + **kwargs: Keyword arguments to the serialize method, accepts + the following keyword args: + deterministic: If true, requests deterministic serialization of the + protobuf, with predictable ordering of map keys. + Returns: A binary string representation of the message if all of the required fields in the message are set (i.e. the message is initialized). @@ -196,12 +202,18 @@ class Message(object): """ raise NotImplementedError - def SerializePartialToString(self): + def SerializePartialToString(self, **kwargs): """Serializes the protocol message to a binary string. This method is similar to SerializeToString but doesn't check if the message is initialized. + Arguments: + **kwargs: Keyword arguments to the serialize method, accepts + the following keyword args: + deterministic: If true, requests deterministic serialization of the + protobuf, with predictable ordering of map keys. + Returns: A string representation of the partial message. """ diff --git a/python/google/protobuf/message_factory.py b/python/google/protobuf/message_factory.py index 8ab1c513..15740280 100644 --- a/python/google/protobuf/message_factory.py +++ b/python/google/protobuf/message_factory.py @@ -66,7 +66,7 @@ class MessageFactory(object): Returns: A class describing the passed in descriptor. """ - if descriptor.full_name not in self._classes: + if descriptor not in self._classes: descriptor_name = descriptor.name if str is bytes: # PY2 descriptor_name = descriptor.name.encode('ascii', 'ignore') @@ -75,16 +75,16 @@ class MessageFactory(object): (message.Message,), {'DESCRIPTOR': descriptor, '__module__': None}) # If module not set, it wrongly points to the reflection.py module. - self._classes[descriptor.full_name] = result_class + self._classes[descriptor] = result_class for field in descriptor.fields: if field.message_type: self.GetPrototype(field.message_type) for extension in result_class.DESCRIPTOR.extensions: - if extension.containing_type.full_name not in self._classes: + if extension.containing_type not in self._classes: self.GetPrototype(extension.containing_type) - extended_class = self._classes[extension.containing_type.full_name] + extended_class = self._classes[extension.containing_type] extended_class.RegisterExtension(extension) - return self._classes[descriptor.full_name] + return self._classes[descriptor] def GetMessages(self, files): """Gets all the messages from a specified file. @@ -116,9 +116,9 @@ class MessageFactory(object): # an error if they were different. for extension in file_desc.extensions_by_name.values(): - if extension.containing_type.full_name not in self._classes: + if extension.containing_type not in self._classes: self.GetPrototype(extension.containing_type) - extended_class = self._classes[extension.containing_type.full_name] + extended_class = self._classes[extension.containing_type] extended_class.RegisterExtension(extension) return result diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index f13e1bc1..9634ea05 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -709,6 +709,10 @@ static PyObject* GetJsonName(PyBaseDescriptor* self, void *closure) { return PyString_FromCppString(_GetDescriptor(self)->json_name()); } +static PyObject* GetFile(PyBaseDescriptor *self, void *closure) { + return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file()); +} + static PyObject* GetType(PyBaseDescriptor *self, void *closure) { return PyInt_FromLong(_GetDescriptor(self)->type()); } @@ -899,6 +903,7 @@ static PyGetSetDef Getters[] = { { "name", (getter)GetName, NULL, "Unqualified name"}, { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"}, { "json_name", (getter)GetJsonName, NULL, "Json name"}, + { "file", (getter)GetFile, NULL, "File Descriptor"}, { "type", (getter)GetType, NULL, "C++ Type"}, { "cpp_type", (getter)GetCppType, NULL, "C++ Type"}, { "label", (getter)GetLabel, NULL, "Label"}, @@ -1570,6 +1575,10 @@ static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) { return PyString_FromCppString(_GetDescriptor(self)->full_name()); } +static PyObject* GetFile(PyBaseDescriptor *self, void *closure) { + return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file()); +} + static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) { return PyInt_FromLong(_GetDescriptor(self)->index()); } @@ -1611,6 +1620,7 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { static PyGetSetDef Getters[] = { { "name", (getter)GetName, NULL, "Name", NULL}, { "full_name", (getter)GetFullName, NULL, "Full name", NULL}, + { "file", (getter)GetFile, NULL, "File descriptor"}, { "index", (getter)GetIndex, NULL, "Index", NULL}, { "methods", (getter)GetMethods, NULL, "Methods", NULL}, diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc index 088ddf93..43be0701 100644 --- a/python/google/protobuf/pyext/map_container.cc +++ b/python/google/protobuf/pyext/map_container.cc @@ -712,8 +712,30 @@ int MapReflectionFriend::MessageMapSetItem(PyObject* _self, PyObject* key, } // Delete key from map. - if (reflection->DeleteMapValue(message, self->parent_field_descriptor, + if (reflection->ContainsMapKey(*message, self->parent_field_descriptor, map_key)) { + // Delete key from CMessage dict. + MapValueRef value; + reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor, + map_key, &value); + ScopedPyObjectPtr key(PyLong_FromVoidPtr(value.MutableMessageValue())); + + // PyDict_DelItem will have key error if the key is not in the map. We do + // not want to call PyErr_Clear() which may clear other errors. Thus + // PyDict_Contains() check is called before delete. + int contains = PyDict_Contains(self->message_dict, key.get()); + if (contains < 0) { + return -1; + } + if (contains) { + if (PyDict_DelItem(self->message_dict, key.get()) < 0) { + return -1; + } + } + + // Delete key from map. + reflection->DeleteMapValue(message, self->parent_field_descriptor, + map_key); return 0; } else { PyErr_Format(PyExc_KeyError, "Key not present in map"); diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index 49113c7c..702c5d03 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -52,6 +52,7 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include <google/protobuf/util/message_differencer.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/message.h> @@ -1810,8 +1811,25 @@ static string GetMessageName(CMessage* self) { } } -static PyObject* SerializeToString(CMessage* self, PyObject* args) { - if (!self->message->IsInitialized()) { +static PyObject* InternalSerializeToString( + CMessage* self, PyObject* args, PyObject* kwargs, + bool require_initialized) { + // Parse the "deterministic" kwarg; defaults to False. + static char* kwlist[] = { "deterministic", 0 }; + PyObject* deterministic_obj = Py_None; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, + &deterministic_obj)) { + return NULL; + } + // Preemptively convert to a bool first, so we don't need to back out of + // allocating memory if this raises an exception. + // NOTE: This is unused later if deterministic == Py_None, but that's fine. + int deterministic = PyObject_IsTrue(deterministic_obj); + if (deterministic < 0) { + return NULL; + } + + if (require_initialized && !self->message->IsInitialized()) { ScopedPyObjectPtr errors(FindInitializationErrors(self)); if (errors == NULL) { return NULL; @@ -1849,24 +1867,36 @@ static PyObject* SerializeToString(CMessage* self, PyObject* args) { GetMessageName(self).c_str(), PyString_AsString(joined.get())); return NULL; } - int size = self->message->ByteSize(); - if (size <= 0) { + + // Ok, arguments parsed and errors checked, now encode to a string + const size_t size = self->message->ByteSizeLong(); + if (size == 0) { return PyBytes_FromString(""); } PyObject* result = PyBytes_FromStringAndSize(NULL, size); if (result == NULL) { return NULL; } - char* buffer = PyBytes_AS_STRING(result); - self->message->SerializeWithCachedSizesToArray( - reinterpret_cast<uint8*>(buffer)); + io::ArrayOutputStream out(PyBytes_AS_STRING(result), size); + io::CodedOutputStream coded_out(&out); + if (deterministic_obj != Py_None) { + coded_out.SetSerializationDeterministic(deterministic); + } + self->message->SerializeWithCachedSizes(&coded_out); + GOOGLE_CHECK(!coded_out.HadError()); return result; } -static PyObject* SerializePartialToString(CMessage* self) { - string contents; - self->message->SerializePartialToString(&contents); - return PyBytes_FromStringAndSize(contents.c_str(), contents.size()); +static PyObject* SerializeToString( + CMessage* self, PyObject* args, PyObject* kwargs) { + return InternalSerializeToString(self, args, kwargs, + /*require_initialized=*/true); +} + +static PyObject* SerializePartialToString( + CMessage* self, PyObject* args, PyObject* kwargs) { + return InternalSerializeToString(self, args, kwargs, + /*require_initialized=*/false); } // Formats proto fields for ascii dumps using python formatting functions where @@ -2537,7 +2567,10 @@ PyObject* Reduce(CMessage* self) { if (state == NULL) { return NULL; } - ScopedPyObjectPtr serialized(SerializePartialToString(self)); + string contents; + self->message->SerializePartialToString(&contents); + ScopedPyObjectPtr serialized( + PyBytes_FromStringAndSize(contents.c_str(), contents.size())); if (serialized == NULL) { return NULL; } @@ -2658,9 +2691,10 @@ static PyMethodDef Methods[] = { { "RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS, "Registers an extension with the current message." }, { "SerializePartialToString", (PyCFunction)SerializePartialToString, - METH_NOARGS, + METH_VARARGS | METH_KEYWORDS, "Serializes the message to a string, even if it isn't initialized." }, - { "SerializeToString", (PyCFunction)SerializeToString, METH_NOARGS, + { "SerializeToString", (PyCFunction)SerializeToString, + METH_VARARGS | METH_KEYWORDS, "Serializes the message to a string, only for initialized messages." }, { "SetInParent", (PyCFunction)SetInParent, METH_NOARGS, "Sets the has bit of the given field in its parent message." }, diff --git a/python/google/protobuf/pyext/message_factory.cc b/python/google/protobuf/pyext/message_factory.cc index e0b45bf2..571bae2b 100644 --- a/python/google/protobuf/pyext/message_factory.cc +++ b/python/google/protobuf/pyext/message_factory.cc @@ -133,11 +133,7 @@ int RegisterMessageClass(PyMessageFactory* self, CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self, const Descriptor* descriptor) { // This is the same implementation as MessageFactory.GetPrototype(). - ScopedPyObjectPtr py_descriptor( - PyMessageDescriptor_FromDescriptor(descriptor)); - if (py_descriptor == NULL) { - return NULL; - } + // Do not create a MessageClass that already exists. hash_map<const Descriptor*, CMessageClass*>::iterator it = self->classes_by_descriptor->find(descriptor); @@ -145,6 +141,11 @@ CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self, Py_INCREF(it->second); return it->second; } + ScopedPyObjectPtr py_descriptor( + PyMessageDescriptor_FromDescriptor(descriptor)); + if (py_descriptor == NULL) { + return NULL; + } // Create a new message class. ScopedPyObjectPtr args(Py_BuildValue( "s(){sOsOsO}", descriptor->name().c_str(), diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc index 06a976de..5ad71db5 100644 --- a/python/google/protobuf/pyext/repeated_composite_container.cc +++ b/python/google/protobuf/pyext/repeated_composite_container.cc @@ -46,6 +46,7 @@ #include <google/protobuf/pyext/descriptor.h> #include <google/protobuf/pyext/descriptor_pool.h> #include <google/protobuf/pyext/message.h> +#include <google/protobuf/pyext/message_factory.h> #include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include <google/protobuf/reflection.h> @@ -137,9 +138,12 @@ static PyObject* AddToAttached(RepeatedCompositeContainer* self, if (cmessage::AssureWritable(self->parent) == -1) return NULL; Message* message = self->message; + Message* sub_message = - message->GetReflection()->AddMessage(message, - self->parent_field_descriptor); + message->GetReflection()->AddMessage( + message, + self->parent_field_descriptor, + self->child_message_class->py_message_factory->message_factory); CMessage* cmsg = cmessage::NewEmptyMessage(self->child_message_class); if (cmsg == NULL) return NULL; @@ -336,6 +340,18 @@ static PyObject* RichCompare(RepeatedCompositeContainer* self, } } +static PyObject* ToStr(RepeatedCompositeContainer* self) { + ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); + if (full_slice == NULL) { + return NULL; + } + ScopedPyObjectPtr list(Subscript(self, full_slice.get())); + if (list == NULL) { + return NULL; + } + return PyObject_Repr(list.get()); +} + // --------------------------------------------------------------------- // sort() @@ -608,7 +624,7 @@ PyTypeObject RepeatedCompositeContainer_Type = { 0, // tp_getattr 0, // tp_setattr 0, // tp_compare - 0, // tp_repr + (reprfunc)repeated_composite_container::ToStr, // tp_repr 0, // tp_as_number &repeated_composite_container::SqMethods, // tp_as_sequence &repeated_composite_container::MpMethods, // tp_as_mapping diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc index 9fedb952..54998800 100644 --- a/python/google/protobuf/pyext/repeated_scalar_container.cc +++ b/python/google/protobuf/pyext/repeated_scalar_container.cc @@ -659,6 +659,18 @@ static PyObject* Pop(RepeatedScalarContainer* self, return item; } +static PyObject* ToStr(RepeatedScalarContainer* self) { + ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); + if (full_slice == NULL) { + return NULL; + } + ScopedPyObjectPtr list(Subscript(self, full_slice.get())); + if (list == NULL) { + return NULL; + } + return PyObject_Repr(list.get()); +} + // The private constructor of RepeatedScalarContainer objects. PyObject *NewContainer( CMessage* parent, const FieldDescriptor* parent_field_descriptor) { @@ -781,7 +793,7 @@ PyTypeObject RepeatedScalarContainer_Type = { 0, // tp_getattr 0, // tp_setattr 0, // tp_compare - 0, // tp_repr + (reprfunc)repeated_scalar_container::ToStr, // tp_repr 0, // tp_as_number &repeated_scalar_container::SqMethods, // tp_as_sequence &repeated_scalar_container::MpMethods, // tp_as_mapping diff --git a/python/google/protobuf/symbol_database.py b/python/google/protobuf/symbol_database.py index 07341efa..5ad869f4 100644 --- a/python/google/protobuf/symbol_database.py +++ b/python/google/protobuf/symbol_database.py @@ -78,10 +78,18 @@ class SymbolDatabase(message_factory.MessageFactory): """ desc = message.DESCRIPTOR - self._classes[desc.full_name] = message - self.pool.AddDescriptor(desc) + self._classes[desc] = message + self.RegisterMessageDescriptor(desc) return message + def RegisterMessageDescriptor(self, message_descriptor): + """Registers the given message descriptor in the local database. + + Args: + message_descriptor: a descriptor.MessageDescriptor. + """ + self.pool.AddDescriptor(message_descriptor) + def RegisterEnumDescriptor(self, enum_descriptor): """Registers the given enum descriptor in the local database. @@ -132,7 +140,7 @@ class SymbolDatabase(message_factory.MessageFactory): KeyError: if the symbol could not be found. """ - return self._classes[symbol] + return self._classes[self.pool.FindMessageTypeByName(symbol)] def GetMessages(self, files): # TODO(amauryfa): Fix the differences with MessageFactory. @@ -153,20 +161,20 @@ class SymbolDatabase(message_factory.MessageFactory): KeyError: if a file could not be found. """ - def _GetAllMessageNames(desc): + def _GetAllMessages(desc): """Walk a message Descriptor and recursively yields all message names.""" - yield desc.full_name + yield desc for msg_desc in desc.nested_types: - for full_name in _GetAllMessageNames(msg_desc): - yield full_name + for nested_desc in _GetAllMessages(msg_desc): + yield nested_desc result = {} for file_name in files: file_desc = self.pool.FindFileByName(file_name) for msg_desc in file_desc.message_types_by_name.values(): - for full_name in _GetAllMessageNames(msg_desc): + for desc in _GetAllMessages(msg_desc): try: - result[full_name] = self._classes[full_name] + result[desc.full_name] = self._classes[desc] except KeyError: # This descriptor has no registered class, skip it. pass diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py index c216e097..aaca78ad 100755 --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -126,7 +126,8 @@ def MessageToString(message, float_format=None, use_field_number=False, descriptor_pool=None, - indent=0): + indent=0, + message_formatter=None): """Convert protobuf message to text format. Floating point values can be formatted compactly with 15 digits of @@ -148,6 +149,9 @@ def MessageToString(message, use_field_number: If True, print field numbers instead of names. descriptor_pool: A DescriptorPool used to resolve Any types. indent: The indent level, in terms of spaces, for pretty print. + message_formatter: A function(message, indent, as_one_line): unicode|None + to custom format selected sub-messages (usually based on message type). + Use to pretty print parts of the protobuf for easier diffing. Returns: A string of the text formatted protocol buffer message. @@ -155,7 +159,7 @@ def MessageToString(message, out = TextWriter(as_utf8) printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets, use_index_order, float_format, use_field_number, - descriptor_pool) + descriptor_pool, message_formatter) printer.PrintMessage(message) result = out.getvalue() out.close() @@ -179,10 +183,11 @@ def PrintMessage(message, use_index_order=False, float_format=None, use_field_number=False, - descriptor_pool=None): + descriptor_pool=None, + message_formatter=None): printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets, use_index_order, float_format, use_field_number, - descriptor_pool) + descriptor_pool, message_formatter) printer.PrintMessage(message) @@ -194,10 +199,11 @@ def PrintField(field, as_one_line=False, pointy_brackets=False, use_index_order=False, - float_format=None): + float_format=None, + message_formatter=None): """Print a single field name/value pair.""" printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets, - use_index_order, float_format) + use_index_order, float_format, message_formatter) printer.PrintField(field, value) @@ -209,10 +215,11 @@ def PrintFieldValue(field, as_one_line=False, pointy_brackets=False, use_index_order=False, - float_format=None): + float_format=None, + message_formatter=None): """Print a single field value (not including name).""" printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets, - use_index_order, float_format) + use_index_order, float_format, message_formatter) printer.PrintFieldValue(field, value) @@ -228,6 +235,9 @@ def _BuildMessageFromTypeName(type_name, descriptor_pool): wasn't found matching type_name. """ # pylint: disable=g-import-not-at-top + if descriptor_pool is None: + from google.protobuf import descriptor_pool as pool_mod + descriptor_pool = pool_mod.Default() from google.protobuf import symbol_database database = symbol_database.Default() try: @@ -250,7 +260,8 @@ class _Printer(object): use_index_order=False, float_format=None, use_field_number=False, - descriptor_pool=None): + descriptor_pool=None, + message_formatter=None): """Initialize the Printer. Floating point values can be formatted compactly with 15 digits of @@ -273,6 +284,9 @@ class _Printer(object): used. use_field_number: If True, print field numbers instead of names. descriptor_pool: A DescriptorPool used to resolve Any types. + message_formatter: A function(message, indent, as_one_line): unicode|None + to custom format selected sub-messages (usually based on message type). + Use to pretty print parts of the protobuf for easier diffing. """ self.out = out self.indent = indent @@ -283,6 +297,7 @@ class _Printer(object): self.float_format = float_format self.use_field_number = use_field_number self.descriptor_pool = descriptor_pool + self.message_formatter = message_formatter def _TryPrintAsAnyMessage(self, message): """Serializes if message is a google.protobuf.Any field.""" @@ -297,14 +312,27 @@ class _Printer(object): else: return False + def _TryCustomFormatMessage(self, message): + formatted = self.message_formatter(message, self.indent, self.as_one_line) + if formatted is None: + return False + + out = self.out + out.write(' ' * self.indent) + out.write(formatted) + out.write(' ' if self.as_one_line else '\n') + return True + def PrintMessage(self, message): """Convert protobuf message to text format. Args: message: The protocol buffers message. """ + if self.message_formatter and self._TryCustomFormatMessage(message): + return if (message.DESCRIPTOR.full_name == _ANY_FULL_TYPE_NAME and - self.descriptor_pool and self._TryPrintAsAnyMessage(message)): + self._TryPrintAsAnyMessage(message)): return fields = message.ListFields() if self.use_index_order: @@ -426,6 +454,22 @@ def Parse(text, descriptor_pool=None): """Parses a text representation of a protocol message into a message. + NOTE: for historical reasons this function does not clear the input + message. This is different from what the binary msg.ParseFrom(...) does. + + Example + a = MyProto() + a.repeated_field.append('test') + b = MyProto() + + text_format.Parse(repr(a), b) + text_format.Parse(repr(a), b) # repeated_field contains ["test", "test"] + + # Binary version: + b.ParseFromString(a.SerializeToString()) # repeated_field is now "test" + + Caller is responsible for clearing the message as needed. + Args: text: Message text representation. message: A protocol buffer message to merge into. @@ -593,11 +637,6 @@ class _Parser(object): ParseError: In case of text parsing problems. """ message_descriptor = message.DESCRIPTOR - if (hasattr(message_descriptor, 'syntax') and - message_descriptor.syntax == 'proto3'): - # Proto3 doesn't represent presence so we can't test if multiple - # scalars have occurred. We have to allow them. - self._allow_multiple_scalars = True if tokenizer.TryConsume('['): name = [tokenizer.ConsumeIdentifier()] while tokenizer.TryConsume('.'): @@ -616,7 +655,11 @@ class _Parser(object): field = None else: raise tokenizer.ParseErrorPreviousToken( - 'Extension "%s" not registered.' % name) + 'Extension "%s" not registered. ' + 'Did you import the _pb2 module which defines it? ' + 'If you are trying to place the extension in the MessageSet ' + 'field of another message that is in an Any or MessageSet field, ' + 'that message\'s _pb2 module must be imported as well' % name) elif message_descriptor != field.containing_type: raise tokenizer.ParseErrorPreviousToken( 'Extension "%s" does not extend message type "%s".' % @@ -695,17 +738,17 @@ class _Parser(object): def _ConsumeAnyTypeUrl(self, tokenizer): """Consumes a google.protobuf.Any type URL and returns the type name.""" # Consume "type.googleapis.com/". - tokenizer.ConsumeIdentifier() + prefix = [tokenizer.ConsumeIdentifier()] tokenizer.Consume('.') - tokenizer.ConsumeIdentifier() + prefix.append(tokenizer.ConsumeIdentifier()) tokenizer.Consume('.') - tokenizer.ConsumeIdentifier() + prefix.append(tokenizer.ConsumeIdentifier()) tokenizer.Consume('/') # Consume the fully-qualified type name. name = [tokenizer.ConsumeIdentifier()] while tokenizer.TryConsume('.'): name.append(tokenizer.ConsumeIdentifier()) - return '.'.join(name) + return '.'.join(prefix), '.'.join(name) def _MergeMessageField(self, tokenizer, message, field): """Merges a single scalar field into a message. @@ -728,7 +771,7 @@ class _Parser(object): if (field.message_type.full_name == _ANY_FULL_TYPE_NAME and tokenizer.TryConsume('[')): - packed_type_name = self._ConsumeAnyTypeUrl(tokenizer) + type_url_prefix, packed_type_name = self._ConsumeAnyTypeUrl(tokenizer) tokenizer.Consume(']') tokenizer.TryConsume(':') if tokenizer.TryConsume('<'): @@ -736,8 +779,6 @@ class _Parser(object): else: tokenizer.Consume('{') expanded_any_end_token = '}' - if not self.descriptor_pool: - raise ParseError('Descriptor pool required to parse expanded Any field') expanded_any_sub_message = _BuildMessageFromTypeName(packed_type_name, self.descriptor_pool) if not expanded_any_sub_message: @@ -752,7 +793,8 @@ class _Parser(object): any_message = getattr(message, field.name).add() else: any_message = getattr(message, field.name) - any_message.Pack(expanded_any_sub_message) + any_message.Pack(expanded_any_sub_message, + type_url_prefix=type_url_prefix) elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED: if field.is_extension: sub_message = message.Extensions[field].add() @@ -780,6 +822,12 @@ class _Parser(object): else: getattr(message, field.name)[sub_message.key] = sub_message.value + @staticmethod + def _IsProto3Syntax(message): + message_descriptor = message.DESCRIPTOR + return (hasattr(message_descriptor, 'syntax') and + message_descriptor.syntax == 'proto3') + def _MergeScalarField(self, tokenizer, message, field): """Merges a single scalar field into a message. @@ -829,15 +877,20 @@ class _Parser(object): else: getattr(message, field.name).append(value) else: + # Proto3 doesn't represent presence so we can't test if multiple scalars + # have occurred. We have to allow them. + can_check_presence = not self._IsProto3Syntax(message) if field.is_extension: - if not self._allow_multiple_scalars and message.HasExtension(field): + if (not self._allow_multiple_scalars and can_check_presence and + message.HasExtension(field)): raise tokenizer.ParseErrorPreviousToken( 'Message type "%s" should not have multiple "%s" extensions.' % (message.DESCRIPTOR.full_name, field.full_name)) else: message.Extensions[field] = value else: - if not self._allow_multiple_scalars and message.HasField(field.name): + if (not self._allow_multiple_scalars and can_check_presence and + message.HasField(field.name)): raise tokenizer.ParseErrorPreviousToken( 'Message type "%s" should not have multiple "%s" fields.' % (message.DESCRIPTOR.full_name, field.name)) @@ -1088,7 +1141,7 @@ class Tokenizer(object): """ result = self.token if not self._IDENTIFIER_OR_NUMBER.match(result): - raise self.ParseError('Expected identifier or number.') + raise self.ParseError('Expected identifier or number, got %s.' % result) self.NextToken() return result diff --git a/python/release.sh b/python/release.sh new file mode 100755 index 00000000..b0bf3b3f --- /dev/null +++ b/python/release.sh @@ -0,0 +1,114 @@ +#!/bin/bash + +set -ex + +function get_source_version() { + grep "__version__ = '.*'" python/google/protobuf/__init__.py | sed -r "s/__version__ = '(.*)'/\1/" +} + +function run_install_test() { + local VERSION=$1 + local PYTHON=$2 + local PYPI=$3 + + virtualenv --no-site-packages -p `which $PYTHON` test-venv + + # Intentionally put a broken protoc in the path to make sure installation + # doesn't require protoc installed. + touch test-venv/bin/protoc + chmod +x test-venv/bin/protoc + + source test-venv/bin/activate + pip install -i ${PYPI} protobuf==${VERSION} + deactivate + rm -fr test-venv +} + + +[ $# -lt 1 ] && { + echo "Usage: $0 VERSION [" + echo "" + echo "Examples:" + echo " Test 3.3.0 release using version number 3.3.0.dev1:" + echo " $0 3.0.0 dev1" + echo " Actually release 3.3.0 to PyPI:" + echo " $0 3.3.0" + exit 1 +} +VERSION=$1 +DEV=$2 + +# Make sure we are in a protobuf source tree. +[ -f "python/google/protobuf/__init__.py" ] || { + echo "This script must be ran under root of protobuf source tree." + exit 1 +} + +# Make sure all files are world-readable. +find python -type d -exec chmod a+r,a+x {} + +find python -type f -exec chmod a+r {} + + +# Check that the supplied version number matches what's inside the source code. +SOURCE_VERSION=`get_source_version` + +[ "${VERSION}" == "${SOURCE_VERSION}" -o "${VERSION}.${DEV}" == "${SOURCE_VERSION}" ] || { + echo "Version number specified on the command line ${VERSION} doesn't match" + echo "the actual version number in the source code: ${SOURCE_VERSION}" + exit 1 +} + +TESTING_ONLY=1 +TESTING_VERSION=${VERSION}.${DEV} +if [ -z "${DEV}" ]; then + read -p "You are releasing ${VERSION} to PyPI. Are you sure? [y/n]" -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + TESTING_ONLY=0 + TESTING_VERSION=${VERSION} +else + # Use dev version number for testing. + sed -i -r "s/__version__ = '.*'/__version__ = '${VERSION}.${DEV}'/" python/google/protobuf/__init__.py +fi + +cd python + +# Run tests locally. +python setup.py build +python setup.py test + +# Deploy source package to testing PyPI +python setup.py sdist upload -r https://test.pypi.org/legacy/ + +# Test locally with different python versions. +run_install_test ${TESTING_VERSION} python2.7 https://test.pypi.org/simple +run_install_test ${TESTING_VERSION} python3.4 https://test.pypi.org/simple + +# Deploy egg/wheel packages to testing PyPI and test again. +python setup.py bdist_egg bdist_wheel upload -r https://test.pypi.org/legacy/ +run_install_test ${TESTING_VERSION} python2.7 https://test.pypi.org/simple +run_install_test ${TESTING_VERSION} python3.4 https://test.pypi.org/simple + +echo "All install tests have passed using testing PyPI." + +if [ $TESTING_ONLY -eq 0 ]; then + read -p "Publish to PyPI? [y/n]" -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + echo "Publishing to PyPI..." + # Be sure to run build before sdist, because otherwise sdist will not include + # well-known types. + python setup.py clean build sdist upload + # Be sure to run clean before bdist_xxx, because otherwise bdist_xxx will + # include files you may not want in the package. E.g., if you have built + # and tested with --cpp_implemenation, bdist_xxx will include the _message.so + # file even when you no longer pass the --cpp_implemenation flag. See: + # https://github.com/google/protobuf/issues/3042 + python setup.py clean build bdist_egg bdist_wheel upload +else + # Set the version number back (i.e., remove dev suffix). + sed -i -r "s/__version__ = '.*'/__version__ = '${VERSION}'/" google/protobuf/__init__.py +fi diff --git a/python/release/wheel/protobuf_optimized_pip.sh b/python/release/wheel/protobuf_optimized_pip.sh index 469661aa..064d1d2a 100755 --- a/python/release/wheel/protobuf_optimized_pip.sh +++ b/python/release/wheel/protobuf_optimized_pip.sh @@ -47,6 +47,9 @@ cd $DIR/protobuf-${PROTOBUF_VERSION} sed -i '/AC_PROG_OBJC/d' configure.ac sed -i 's/conformance\/Makefile//g' configure.ac +# Use the /usr/bin/autoconf and related tools to pick the correct aclocal macros +export PATH="/usr/bin:$PATH" + # Build protoc ./autogen.sh CXXFLAGS="-fPIC -g -O2" ./configure diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index bed835cb..bd1e39f1 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.3.2" + s.version = "3.4.0.2" 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 ba368fd7..1999213c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,8 +48,7 @@ nobase_dist_proto_DATA = google/protobuf/descriptor.proto \ google/protobuf/timestamp.proto \ google/protobuf/type.proto \ google/protobuf/wrappers.proto \ - google/protobuf/compiler/plugin.proto \ - google/protobuf/compiler/profile.proto + google/protobuf/compiler/plugin.proto # Not sure why these don't get cleaned automatically. clean-local: @@ -104,6 +103,7 @@ nobase_include_HEADERS = \ google/protobuf/api.pb.h \ google/protobuf/any.h \ google/protobuf/arena.h \ + google/protobuf/arena_impl.h \ google/protobuf/arenastring.h \ google/protobuf/descriptor_database.h \ google/protobuf/descriptor.h \ @@ -158,7 +158,6 @@ 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 \ @@ -184,7 +183,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 13:2:0 -export-dynamic -no-undefined +libprotobuf_lite_la_LDFLAGS = -version-info 14: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 @@ -222,6 +221,8 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/arenastring.cc \ google/protobuf/extension_set.cc \ google/protobuf/generated_message_util.cc \ + google/protobuf/generated_message_table_driven_lite.h \ + google/protobuf/generated_message_table_driven_lite.cc \ google/protobuf/message_lite.cc \ google/protobuf/repeated_field.cc \ google/protobuf/wire_format_lite.cc \ @@ -231,7 +232,7 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/io/zero_copy_stream_impl_lite.cc libprotobuf_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_la_LDFLAGS = -version-info 13:2:0 -export-dynamic -no-undefined +libprotobuf_la_LDFLAGS = -version-info 14: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 @@ -252,6 +253,7 @@ libprotobuf_la_SOURCES = \ google/protobuf/extension_set_heavy.cc \ google/protobuf/field_mask.pb.cc \ google/protobuf/generated_message_reflection.cc \ + google/protobuf/generated_message_table_driven_lite.h \ google/protobuf/generated_message_table_driven.cc \ google/protobuf/map_field.cc \ google/protobuf/message.cc \ @@ -321,7 +323,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 13:2:0 -export-dynamic -no-undefined +libprotoc_la_LDFLAGS = -version-info 14: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 @@ -331,7 +333,6 @@ 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 \ @@ -680,10 +681,10 @@ protoc_outputs = \ google/protobuf/unittest_preserve_unknown_enum.pb.h \ google/protobuf/unittest_proto3_arena.pb.cc \ google/protobuf/unittest_proto3_arena.pb.h \ - google/protobuf/unittest_proto3_arena_lite.pb.cc \ - google/protobuf/unittest_proto3_arena_lite.pb.h \ - google/protobuf/unittest_proto3_lite.pb.cc \ - google/protobuf/unittest_proto3_lite.pb.h \ + google/protobuf/unittest_proto3_arena_lite.pb.cc \ + google/protobuf/unittest_proto3_arena_lite.pb.h \ + google/protobuf/unittest_proto3_lite.pb.cc \ + google/protobuf/unittest_proto3_lite.pb.h \ google/protobuf/unittest_well_known_types.pb.cc \ google/protobuf/unittest_well_known_types.pb.h \ google/protobuf/util/internal/testdata/anys.pb.cc \ @@ -790,8 +791,8 @@ protobuf_test_SOURCES = \ google/protobuf/no_field_presence_test.cc \ google/protobuf/preserve_unknown_enum_test.cc \ google/protobuf/proto3_arena_unittest.cc \ - google/protobuf/proto3_arena_lite_unittest.cc \ - google/protobuf/proto3_lite_unittest.cc \ + google/protobuf/proto3_arena_lite_unittest.cc \ + google/protobuf/proto3_lite_unittest.cc \ google/protobuf/reflection_ops_unittest.cc \ google/protobuf/repeated_field_reflection_unittest.cc \ google/protobuf/repeated_field_unittest.cc \ @@ -809,6 +810,7 @@ protobuf_test_SOURCES = \ google/protobuf/compiler/mock_code_generator.h \ google/protobuf/compiler/parser_unittest.cc \ google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \ + google/protobuf/compiler/cpp/cpp_move_unittest.cc \ google/protobuf/compiler/cpp/cpp_unittest.h \ google/protobuf/compiler/cpp/cpp_unittest.cc \ google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \ @@ -920,15 +922,11 @@ no_warning_test.cc: echo "#include <$${FILE}>" >> no_warning_test.cc; \ fi \ done - echo "#include <gtest/gtest.h>" >> no_warning_test.cc - echo "TEST(NoWarningTest, Empty) {}" >> no_warning_test.cc + echo "int main(int, char**) { return 0; }" >> no_warning_test.cc -no_warning_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \ - ../gmock/gtest/lib/libgtest.la \ - ../gmock/gtest/lib/libgtest_main.la -no_warning_test_CPPFLAGS = -I$(srcdir)/../gmock/gtest/include +no_warning_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la no_warning_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) \ - -Wall -Wconversion -Werror -Werror=missing-declarations + -Wall -Wextra -Werror -Wno-unused-parameter nodist_no_warning_test_SOURCES = no_warning_test.cc $(protoc_outputs) TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \ diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 948530ba..7d538212 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -19,7 +19,10 @@ namespace google { namespace protobuf { -class AnyDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Any> { +class AnyDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Any> + _instance; } _Any_default_instance_; namespace protobuf_google_2fprotobuf_2fany_2eproto { @@ -32,20 +35,20 @@ namespace { } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::google::protobuf::internal::AuxillaryParseTableField(), }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const - TableStruct::schema[] = { - { NULL, NULL, 0, -1, -1, false }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, _internal_metadata_), ~0u, // no _extensions_ @@ -54,8 +57,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, type_url_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, value_), }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(Any)}, }; @@ -85,18 +87,13 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _Any_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); - _Any_default_instance_.DefaultConstruct(); -} + _Any_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Any_default_instance_);} void InitDefaults() { static GOOGLE_PROTOBUF_DECLARE_ONCE(once); @@ -105,7 +102,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\031google/protobuf/any.proto\022\017google.prot" "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002" " \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z" @@ -117,7 +114,6 @@ void AddDescriptorsImpl() { descriptor, 205); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/any.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -221,8 +217,13 @@ Any* Any::New(::google::protobuf::Arena* arena) const { void Any::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Any) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + _internal_metadata_.Clear(); } bool Any::MergePartialFromCodedStream( @@ -238,7 +239,7 @@ bool Any::MergePartialFromCodedStream( // string type_url = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_type_url())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -254,7 +255,7 @@ bool Any::MergePartialFromCodedStream( // bytes value = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( input, this->mutable_value())); } else { @@ -265,12 +266,11 @@ bool Any::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -306,6 +306,10 @@ void Any::SerializeWithCachedSizes( 2, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Any) } @@ -334,6 +338,10 @@ void Any::SerializeWithCachedSizes( 2, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Any) return target; } @@ -342,6 +350,11 @@ size_t Any::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Any) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // string type_url = 1; if (this->type_url().size() > 0) { total_size += 1 + @@ -418,9 +431,11 @@ void Any::Swap(Any* other) { InternalSwap(other); } void Any::InternalSwap(Any* other) { + using std::swap; type_url_.Swap(&other->type_url_); value_.Swap(&other->value_); - std::swap(_cached_size_, other->_cached_size_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Any::GetMetadata() const { diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index ad2073a8..5ffda741 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -49,8 +49,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -69,7 +70,6 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in CopyFrom(from); return *this; } - static const ::google::protobuf::Descriptor* descriptor(); static const Any& default_instance(); @@ -91,6 +91,9 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in } void Swap(Any* other); + friend void swap(Any& a, Any& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -176,6 +179,10 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // Any // string type_url = 1; @@ -284,6 +291,9 @@ inline void Any::set_allocated_value(::std::string* value) { // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value) } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // @@protoc_insertion_point(namespace_scope) diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto index 9bd3f50a..c7486676 100644 --- a/src/google/protobuf/any.proto +++ b/src/google/protobuf/any.proto @@ -74,6 +74,16 @@ option objc_class_prefix = "GPB"; // any.Unpack(foo) // ... // +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := ptypes.MarshalAny(foo) +// ... +// foo := &pb.Foo{} +// if err := ptypes.UnmarshalAny(any, foo); err != nil { +// ... +// } +// // The pack methods provided by protobuf library will by default use // 'type.googleapis.com/full.type.name' as the type URL and the unpack // methods only use the fully qualified type name after the last '/' diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 093bf1cb..96a5074d 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -19,11 +19,20 @@ namespace google { namespace protobuf { -class ApiDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Api> { +class ApiDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Api> + _instance; } _Api_default_instance_; -class MethodDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Method> { +class MethodDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Method> + _instance; } _Method_default_instance_; -class MixinDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Mixin> { +class MixinDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Mixin> + _instance; } _Mixin_default_instance_; namespace protobuf_google_2fprotobuf_2fapi_2eproto { @@ -36,22 +45,22 @@ namespace { } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::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 }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _internal_metadata_), ~0u, // no _extensions_ @@ -84,8 +93,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, root_), }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(Api)}, { 12, -1, sizeof(Method)}, { 24, -1, sizeof(Mixin)}, @@ -119,26 +127,19 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _Api_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; - _Method_default_instance_.Shutdown(); - delete file_level_metadata[1].reflection; - _Mixin_default_instance_.Shutdown(); - delete file_level_metadata[2].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); ::google::protobuf::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::InitDefaults(); ::google::protobuf::protobuf_google_2fprotobuf_2ftype_2eproto::InitDefaults(); - _Api_default_instance_.DefaultConstruct(); - _Method_default_instance_.DefaultConstruct(); - _Mixin_default_instance_.DefaultConstruct(); - _Api_default_instance_.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>( + _Api_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Api_default_instance_);_Method_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Method_default_instance_);_Mixin_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Mixin_default_instance_);_Api_default_instance_._instance.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>( ::google::protobuf::SourceContext::internal_default_instance()); } @@ -149,7 +150,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\031google/protobuf/api.proto\022\017google.prot" "obuf\032$google/protobuf/source_context.pro" "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014" @@ -176,7 +177,6 @@ void AddDescriptorsImpl() { "google/protobuf/api.proto", &protobuf_RegisterTypes); ::google::protobuf::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::AddDescriptors(); ::google::protobuf::protobuf_google_2fprotobuf_2ftype_2eproto::AddDescriptors(); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -256,9 +256,7 @@ Api::~Api() { void Api::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); version_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete source_context_; - } + if (this != internal_default_instance()) delete source_context_; } void Api::SetCachedSize(int size) const { @@ -286,6 +284,10 @@ Api* Api::New(::google::protobuf::Arena* arena) const { void Api::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Api) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + methods_.Clear(); options_.Clear(); mixins_.Clear(); @@ -296,6 +298,7 @@ void Api::Clear() { } source_context_ = NULL; syntax_ = 0; + _internal_metadata_.Clear(); } bool Api::MergePartialFromCodedStream( @@ -311,7 +314,7 @@ bool Api::MergePartialFromCodedStream( // string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -327,7 +330,7 @@ bool Api::MergePartialFromCodedStream( // repeated .google.protobuf.Method methods = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_methods())); } else { @@ -339,7 +342,7 @@ bool Api::MergePartialFromCodedStream( // repeated .google.protobuf.Option options = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { @@ -351,7 +354,7 @@ bool Api::MergePartialFromCodedStream( // string version = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_version())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -367,7 +370,7 @@ bool Api::MergePartialFromCodedStream( // .google.protobuf.SourceContext source_context = 5; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(42u)) { + static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_source_context())); } else { @@ -379,7 +382,7 @@ bool Api::MergePartialFromCodedStream( // repeated .google.protobuf.Mixin mixins = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(50u)) { + static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_mixins())); } else { @@ -391,7 +394,7 @@ bool Api::MergePartialFromCodedStream( // .google.protobuf.Syntax syntax = 7; case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(56u)) { + static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -405,12 +408,11 @@ bool Api::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -483,6 +485,10 @@ void Api::SerializeWithCachedSizes( 7, this->syntax(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Api) } @@ -552,6 +558,10 @@ void Api::SerializeWithCachedSizes( 7, this->syntax(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api) return target; } @@ -560,6 +570,11 @@ size_t Api::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Api) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // repeated .google.protobuf.Method methods = 2; { unsigned int count = static_cast<unsigned int>(this->methods_size()); @@ -691,14 +706,16 @@ void Api::Swap(Api* other) { InternalSwap(other); } void Api::InternalSwap(Api* other) { + using std::swap; 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_); - std::swap(syntax_, other->syntax_); - std::swap(_cached_size_, other->_cached_size_); + swap(source_context_, other->source_context_); + swap(syntax_, other->syntax_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Api::GetMetadata() const { @@ -884,9 +901,10 @@ void Api::clear_source_context() { source_context_ = NULL; } const ::google::protobuf::SourceContext& Api::source_context() const { + const ::google::protobuf::SourceContext* p = source_context_; // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context) - return source_context_ != NULL ? *source_context_ - : *::google::protobuf::SourceContext::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::SourceContext*>( + &::google::protobuf::_SourceContext_default_instance_); } ::google::protobuf::SourceContext* Api::mutable_source_context() { @@ -1050,6 +1068,10 @@ Method* Method::New(::google::protobuf::Arena* arena) const { void Method::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Method) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + options_.Clear(); name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -1057,6 +1079,7 @@ void Method::Clear() { ::memset(&request_streaming_, 0, static_cast<size_t>( reinterpret_cast<char*>(&syntax_) - reinterpret_cast<char*>(&request_streaming_)) + sizeof(syntax_)); + _internal_metadata_.Clear(); } bool Method::MergePartialFromCodedStream( @@ -1072,7 +1095,7 @@ bool Method::MergePartialFromCodedStream( // string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1088,7 +1111,7 @@ bool Method::MergePartialFromCodedStream( // string request_type_url = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_request_type_url())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1104,7 +1127,7 @@ bool Method::MergePartialFromCodedStream( // bool request_streaming = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { + static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -1118,7 +1141,7 @@ bool Method::MergePartialFromCodedStream( // string response_type_url = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_response_type_url())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1134,7 +1157,7 @@ bool Method::MergePartialFromCodedStream( // bool response_streaming = 5; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(40u)) { + static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -1148,7 +1171,7 @@ bool Method::MergePartialFromCodedStream( // repeated .google.protobuf.Option options = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(50u)) { + static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { @@ -1160,7 +1183,7 @@ bool Method::MergePartialFromCodedStream( // .google.protobuf.Syntax syntax = 7; case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(56u)) { + static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -1174,12 +1197,11 @@ bool Method::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1252,6 +1274,10 @@ void Method::SerializeWithCachedSizes( 7, this->syntax(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Method) } @@ -1319,6 +1345,10 @@ void Method::SerializeWithCachedSizes( 7, this->syntax(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method) return target; } @@ -1327,6 +1357,11 @@ size_t Method::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Method) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // repeated .google.protobuf.Option options = 6; { unsigned int count = static_cast<unsigned int>(this->options_size()); @@ -1451,14 +1486,16 @@ void Method::Swap(Method* other) { InternalSwap(other); } void Method::InternalSwap(Method* other) { + using std::swap; options_.InternalSwap(&other->options_); name_.Swap(&other->name_); request_type_url_.Swap(&other->request_type_url_); response_type_url_.Swap(&other->response_type_url_); - std::swap(request_streaming_, other->request_streaming_); - std::swap(response_streaming_, other->response_streaming_); - std::swap(syntax_, other->syntax_); - std::swap(_cached_size_, other->_cached_size_); + swap(request_streaming_, other->request_streaming_); + swap(response_streaming_, other->response_streaming_); + swap(syntax_, other->syntax_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Method::GetMetadata() const { @@ -1774,8 +1811,13 @@ Mixin* Mixin::New(::google::protobuf::Arena* arena) const { void Mixin::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Mixin) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + _internal_metadata_.Clear(); } bool Mixin::MergePartialFromCodedStream( @@ -1791,7 +1833,7 @@ bool Mixin::MergePartialFromCodedStream( // string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1807,7 +1849,7 @@ bool Mixin::MergePartialFromCodedStream( // string root = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_root())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1822,12 +1864,11 @@ bool Mixin::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1867,6 +1908,10 @@ void Mixin::SerializeWithCachedSizes( 2, this->root(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Mixin) } @@ -1899,6 +1944,10 @@ void Mixin::SerializeWithCachedSizes( 2, this->root(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Mixin) return target; } @@ -1907,6 +1956,11 @@ size_t Mixin::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Mixin) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // string name = 1; if (this->name().size() > 0) { total_size += 1 + @@ -1983,9 +2037,11 @@ void Mixin::Swap(Mixin* other) { InternalSwap(other); } void Mixin::InternalSwap(Mixin* other) { + using std::swap; name_.Swap(&other->name_); root_.Swap(&other->root_); - std::swap(_cached_size_, other->_cached_size_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Mixin::GetMetadata() const { diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index f857f220..bed136db 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -56,8 +56,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -76,7 +77,21 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in CopyFrom(from); return *this; } + #if LANG_CXX11 + Api(Api&& from) noexcept + : Api() { + *this = ::std::move(from); + } + inline Api& operator=(Api&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif static const ::google::protobuf::Descriptor* descriptor(); static const Api& default_instance(); @@ -88,6 +103,9 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in 0; void Swap(Api* other); + friend void swap(Api& a, Api& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -235,7 +253,21 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc CopyFrom(from); return *this; } + #if LANG_CXX11 + Method(Method&& from) noexcept + : Method() { + *this = ::std::move(from); + } + inline Method& operator=(Method&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif static const ::google::protobuf::Descriptor* descriptor(); static const Method& default_instance(); @@ -247,6 +279,9 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc 1; void Swap(Method* other); + friend void swap(Method& a, Method& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -387,7 +422,21 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_ CopyFrom(from); return *this; } + #if LANG_CXX11 + Mixin(Mixin&& from) noexcept + : Mixin() { + *this = ::std::move(from); + } + inline Mixin& operator=(Mixin&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif static const ::google::protobuf::Descriptor* descriptor(); static const Mixin& default_instance(); @@ -399,6 +448,9 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_ 2; void Swap(Mixin* other); + friend void swap(Mixin& a, Mixin& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -483,6 +535,10 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_ // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // Api // string name = 1; @@ -660,9 +716,10 @@ inline void Api::clear_source_context() { source_context_ = NULL; } inline const ::google::protobuf::SourceContext& Api::source_context() const { + const ::google::protobuf::SourceContext* p = source_context_; // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context) - return source_context_ != NULL ? *source_context_ - : *::google::protobuf::SourceContext::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::SourceContext*>( + &::google::protobuf::_SourceContext_default_instance_); } inline ::google::protobuf::SourceContext* Api::mutable_source_context() { @@ -1079,6 +1136,9 @@ inline void Mixin::set_allocated_root(::std::string* root) { // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root) } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // ------------------------------------------------------------------- diff --git a/src/google/protobuf/api.proto b/src/google/protobuf/api.proto index 7c30e8b7..f37ee2fa 100644 --- a/src/google/protobuf/api.proto +++ b/src/google/protobuf/api.proto @@ -42,26 +42,33 @@ option java_multiple_files = true; option objc_class_prefix = "GPB"; option go_package = "google.golang.org/genproto/protobuf/api;api"; -// Api is a light-weight descriptor for a protocol buffer service. +// Api is a light-weight descriptor for an API Interface. +// +// Interfaces are also described as "protocol buffer services" in some contexts, +// such as by the "service" keyword in a .proto file, but they are different +// from API Services, which represent a concrete implementation of an interface +// as opposed to simply a description of methods and bindings. They are also +// sometimes simply referred to as "APIs" in other contexts, such as the name of +// this message itself. See https://cloud.google.com/apis/design/glossary for +// detailed terminology. message Api { - // The fully qualified name of this api, including package name - // followed by the api's simple name. + // The fully qualified name of this interface, including package name + // followed by the interface's simple name. string name = 1; - // The methods of this api, in unspecified order. + // The methods of this interface, in unspecified order. repeated Method methods = 2; - // Any metadata attached to the API. + // Any metadata attached to the interface. repeated Option options = 3; - // A version string for this api. If specified, must have the form - // `major-version.minor-version`, as in `1.10`. If the minor version - // is omitted, it defaults to zero. If the entire version field is - // empty, the major version is derived from the package name, as - // outlined below. If the field is not empty, the version in the - // package name will be verified to be consistent with what is - // provided here. + // A version string for this interface. If specified, must have the form + // `major-version.minor-version`, as in `1.10`. If the minor version is + // omitted, it defaults to zero. If the entire version field is empty, the + // major version is derived from the package name, as outlined below. If the + // field is not empty, the version in the package name will be verified to be + // consistent with what is provided here. // // The versioning schema uses [semantic // versioning](http://semver.org) where the major version number @@ -71,10 +78,10 @@ message Api { // chosen based on the product plan. // // The major version is also reflected in the package name of the - // API, which must end in `v<major-version>`, as in + // interface, which must end in `v<major-version>`, as in // `google.feature.v1`. For major versions 0 and 1, the suffix can // be omitted. Zero major versions must only be used for - // experimental, none-GA apis. + // experimental, non-GA interfaces. // // string version = 4; @@ -83,14 +90,14 @@ message Api { // message. SourceContext source_context = 5; - // Included APIs. See [Mixin][]. + // Included interfaces. See [Mixin][]. repeated Mixin mixins = 6; // The source syntax of the service. Syntax syntax = 7; } -// Method represents a method of an api. +// Method represents a method of an API interface. message Method { // The simple name of this method. @@ -115,9 +122,9 @@ message Method { Syntax syntax = 7; } -// Declares an API to be included in this API. The including API must -// redeclare all the methods from the included API, but documentation -// and options are inherited as follows: +// Declares an API Interface to be included in this interface. The including +// interface must redeclare all the methods from the included interface, but +// documentation and options are inherited as follows: // // - If after comment and whitespace stripping, the documentation // string of the redeclared method is empty, it will be inherited @@ -129,7 +136,8 @@ message Method { // // - If an http annotation is inherited, the path pattern will be // modified as follows. Any version prefix will be replaced by the -// version of the including API plus the [root][] path if specified. +// version of the including interface plus the [root][] path if +// specified. // // Example of a simple mixin: // @@ -193,7 +201,7 @@ message Method { // ... // } message Mixin { - // The fully qualified name of the API which is included. + // The fully qualified name of the interface which is included. string name = 1; // If non-empty specifies a path under which inherited HTTP paths diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 16cf8951..fe38f5dd 100755 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -39,32 +39,35 @@ #endif // ADDRESS_SANITIZER namespace google { +static const size_t kMinCleanupListElements = 8; +static const size_t kMaxCleanupListElements = 64; // 1kB on 64-bit. + namespace protobuf { +namespace internal { -google::protobuf::internal::SequenceNumber Arena::lifecycle_id_generator_; +google::protobuf::internal::SequenceNumber ArenaImpl::lifecycle_id_generator_; #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) -Arena::ThreadCache& Arena::thread_cache() { +ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ = new internal::ThreadLocalStorage<ThreadCache>(); return *thread_cache_->Get(); } #elif defined(PROTOBUF_USE_DLLS) -Arena::ThreadCache& Arena::thread_cache() { +ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_ = { -1, NULL }; return thread_cache_; } #else -GOOGLE_THREAD_LOCAL Arena::ThreadCache Arena::thread_cache_ = { -1, NULL }; +GOOGLE_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, NULL}; #endif -void Arena::Init() { +void ArenaImpl::Init() { lifecycle_id_ = lifecycle_id_generator_.GetNext(); blocks_ = 0; hint_ = 0; space_allocated_ = 0; owns_first_block_ = true; - cleanup_list_ = 0; if (options_.initial_block != NULL && options_.initial_block_size > 0) { GOOGLE_CHECK_GE(options_.initial_block_size, sizeof(Block)) @@ -75,134 +78,154 @@ void Arena::Init() { first_block->size = options_.initial_block_size; first_block->pos = kHeaderSize; first_block->next = NULL; + first_block->cleanup = NULL; // Thread which calls Init() owns the first block. This allows the // single-threaded case to allocate on the first block without taking any // locks. first_block->owner = &thread_cache(); - SetThreadCacheBlock(first_block); AddBlockInternal(first_block); + CacheBlock(first_block); owns_first_block_ = false; } - - // Call the initialization hook - if (options_.on_arena_init != NULL) { - hooks_cookie_ = options_.on_arena_init(this); - } else { - hooks_cookie_ = NULL; - } } -Arena::~Arena() { - uint64 space_allocated = ResetInternal(); - - // Call the destruction hook - if (options_.on_arena_destruction != NULL) { - options_.on_arena_destruction(this, hooks_cookie_, space_allocated); - } -} +ArenaImpl::~ArenaImpl() { ResetInternal(); } -uint64 Arena::Reset() { +uint64 ArenaImpl::Reset() { // Invalidate any ThreadCaches pointing to any blocks we just destroyed. lifecycle_id_ = lifecycle_id_generator_.GetNext(); return ResetInternal(); } -uint64 Arena::ResetInternal() { - CleanupList(); - uint64 space_allocated = FreeBlocks(); - - // Call the reset hook - if (options_.on_arena_reset != NULL) { - options_.on_arena_reset(this, hooks_cookie_, space_allocated); - } +uint64 ArenaImpl::ResetInternal() { + Block* head = + reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_)); + CleanupList(head); + uint64 space_allocated = FreeBlocks(head); return space_allocated; } -Arena::Block* Arena::NewBlock(void* me, Block* my_last_block, size_t n, - size_t start_block_size, size_t max_block_size) { +ArenaImpl::Block* ArenaImpl::NewBlock(void* me, Block* my_last_block, + size_t min_bytes, size_t start_block_size, + size_t max_block_size) { size_t size; if (my_last_block != NULL) { // Double the current block size, up to a limit. - size = 2 * (my_last_block->size); - if (size > max_block_size) size = max_block_size; + size = std::min(2 * my_last_block->size, max_block_size); } else { size = start_block_size; } - // Verify that n + kHeaderSize won't overflow. - GOOGLE_CHECK_LE(n, std::numeric_limits<size_t>::max() - kHeaderSize); - size = std::max(size, kHeaderSize + n); + // Verify that min_bytes + kHeaderSize won't overflow. + GOOGLE_CHECK_LE(min_bytes, std::numeric_limits<size_t>::max() - kHeaderSize); + size = std::max(size, kHeaderSize + min_bytes); Block* b = reinterpret_cast<Block*>(options_.block_alloc(size)); - b->pos = kHeaderSize + n; + b->pos = kHeaderSize; b->size = size; b->owner = me; + b->cleanup = NULL; #ifdef ADDRESS_SANITIZER // Poison the rest of the block for ASAN. It was unpoisoned by the underlying // malloc but it's not yet usable until we return it as part of an allocation. ASAN_POISON_MEMORY_REGION( reinterpret_cast<char*>(b) + b->pos, b->size - b->pos); #endif // ADDRESS_SANITIZER + AddBlock(b); return b; } -void Arena::AddBlock(Block* b) { +void ArenaImpl::AddBlock(Block* b) { MutexLock l(&blocks_lock_); AddBlockInternal(b); } -void Arena::AddBlockInternal(Block* b) { +void ArenaImpl::AddBlockInternal(Block* b) { b->next = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_)); google::protobuf::internal::Release_Store(&blocks_, reinterpret_cast<google::protobuf::internal::AtomicWord>(b)); - if (b->avail() != 0) { - // Direct future allocations to this block. - google::protobuf::internal::Release_Store(&hint_, reinterpret_cast<google::protobuf::internal::AtomicWord>(b)); - } space_allocated_ += b->size; } -void Arena::AddListNode(void* elem, void (*cleanup)(void*)) { - Node* node = reinterpret_cast<Node*>(AllocateAligned(sizeof(Node))); +ArenaImpl::Block* ArenaImpl::ExpandCleanupList(Block* b) { + size_t size = b->cleanup ? b->cleanup->size * 2 : kMinCleanupListElements; + size = std::min(size, kMaxCleanupListElements); + size_t bytes = internal::AlignUpTo8(CleanupChunk::SizeOf(size)); + if (b->avail() < bytes) { + b = GetBlock(bytes); + } + CleanupChunk* list = + reinterpret_cast<CleanupChunk*>(AllocFromBlock(b, bytes)); + list->next = b->cleanup; + list->size = size; + list->len = 0; + b->cleanup = list; + return b; +} + +inline GOOGLE_ATTRIBUTE_ALWAYS_INLINE void ArenaImpl::AddCleanupInBlock( + Block* b, void* elem, void (*cleanup)(void*)) { + if (b->cleanup == NULL || b->cleanup->len == b->cleanup->size) { + b = ExpandCleanupList(b); + } + + CleanupNode* node = &b->cleanup->nodes[b->cleanup->len++]; + node->elem = elem; node->cleanup = cleanup; - node->next = reinterpret_cast<Node*>( - google::protobuf::internal::NoBarrier_AtomicExchange(&cleanup_list_, - reinterpret_cast<google::protobuf::internal::AtomicWord>(node))); } -void* Arena::AllocateAligned(const std::type_info* allocated, size_t n) { - // Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.) - n = (n + 7) & -8; +void ArenaImpl::AddCleanup(void* elem, void (*cleanup)(void*)) { + return AddCleanupInBlock(GetBlock(0), elem, cleanup); +} - // Monitor allocation if needed. - if (GOOGLE_PREDICT_FALSE(hooks_cookie_ != NULL) && - options_.on_arena_allocation != NULL) { - options_.on_arena_allocation(allocated, n, hooks_cookie_); - } +void* ArenaImpl::AllocateAligned(size_t n) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + + return AllocFromBlock(GetBlock(n), n); +} + +void* ArenaImpl::AllocateAlignedAndAddCleanup(size_t n, + void (*cleanup)(void*)) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + + Block* b = GetBlock(n); + void* mem = AllocFromBlock(b, n); + AddCleanupInBlock(b, mem, cleanup); + return mem; +} + +inline GOOGLE_ATTRIBUTE_ALWAYS_INLINE ArenaImpl::Block* ArenaImpl::GetBlock(size_t n) { + Block* my_block = NULL; // If this thread already owns a block in this arena then try to use that. // This fast path optimizes the case where multiple threads allocate from the // same arena. - if (thread_cache().last_lifecycle_id_seen == lifecycle_id_ && - thread_cache().last_block_used_ != NULL) { - if (thread_cache().last_block_used_->avail() < n) { - return SlowAlloc(n); + ThreadCache* tc = &thread_cache(); + if (tc->last_lifecycle_id_seen == lifecycle_id_) { + my_block = tc->last_block_used_; + if (my_block->avail() >= n) { + return my_block; } - return AllocFromBlock(thread_cache().last_block_used_, n); } // Check whether we own the last accessed block on this arena. // This fast path optimizes the case where a single thread uses multiple // arenas. - void* me = &thread_cache(); Block* b = reinterpret_cast<Block*>(google::protobuf::internal::Acquire_Load(&hint_)); - if (!b || b->owner != me || b->avail() < n) { - return SlowAlloc(n); + if (b != NULL && b->owner == tc) { + my_block = b; + if (my_block->avail() >= n) { + return my_block; + } } - return AllocFromBlock(b, n); + return GetBlockSlow(tc, my_block, n); } -void* Arena::AllocFromBlock(Block* b, size_t n) { +inline GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* ArenaImpl::AllocFromBlock(Block* b, + size_t n) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(b->pos), b->pos); // Must be already aligned. + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + GOOGLE_DCHECK_GE(b->avail(), n); size_t p = b->pos; b->pos = p + n; #ifdef ADDRESS_SANITIZER @@ -211,27 +234,32 @@ void* Arena::AllocFromBlock(Block* b, size_t n) { return reinterpret_cast<char*>(b) + p; } -void* Arena::SlowAlloc(size_t n) { - void* me = &thread_cache(); +ArenaImpl::Block* ArenaImpl::GetBlockSlow(void* me, Block* my_full_block, + size_t n) { Block* b = FindBlock(me); // Find block owned by me. - // See if allocation fits in my latest block. - if (b != NULL && b->avail() >= n) { - SetThreadCacheBlock(b); - google::protobuf::internal::NoBarrier_Store(&hint_, reinterpret_cast<google::protobuf::internal::AtomicWord>(b)); - return AllocFromBlock(b, n); + if (b == NULL || b->avail() < n) { + b = NewBlock(me, b, n, options_.start_block_size, options_.max_block_size); + + // Try to steal the cleanup list from my_full_block. It's too full for this + // allocation, but it might have space left in its cleanup list and there's + // no reason to waste that memory. + if (my_full_block) { + GOOGLE_DCHECK_EQ(my_full_block->owner, me); + GOOGLE_DCHECK(b->cleanup == NULL); + b->cleanup = my_full_block->cleanup; + my_full_block->cleanup = NULL; + } } - b = NewBlock(me, b, n, options_.start_block_size, options_.max_block_size); - AddBlock(b); - SetThreadCacheBlock(b); - return reinterpret_cast<char*>(b) + kHeaderSize; + CacheBlock(b); + return b; } -uint64 Arena::SpaceAllocated() const { +uint64 ArenaImpl::SpaceAllocated() const { MutexLock l(&blocks_lock_); return space_allocated_; } -uint64 Arena::SpaceUsed() const { +uint64 ArenaImpl::SpaceUsed() const { uint64 space_used = 0; Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_)); while (b != NULL) { @@ -241,14 +269,11 @@ uint64 Arena::SpaceUsed() const { return space_used; } -std::pair<uint64, uint64> Arena::SpaceAllocatedAndUsed() const { - return std::make_pair(SpaceAllocated(), SpaceUsed()); -} - -uint64 Arena::FreeBlocks() { +uint64 ArenaImpl::FreeBlocks(Block* head) { uint64 space_allocated = 0; - Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_)); Block* first_block = NULL; + Block* b = head; + while (b != NULL) { space_allocated += (b->size); Block* next = b->next; @@ -281,27 +306,35 @@ uint64 Arena::FreeBlocks() { // Make the first block that was passed in through ArenaOptions // available for reuse. first_block->pos = kHeaderSize; + first_block->cleanup = NULL; // Thread which calls Reset() owns the first block. This allows the // single-threaded case to allocate on the first block without taking any // locks. first_block->owner = &thread_cache(); - SetThreadCacheBlock(first_block); AddBlockInternal(first_block); + CacheBlock(first_block); } return space_allocated; } -void Arena::CleanupList() { - Node* head = - reinterpret_cast<Node*>(google::protobuf::internal::NoBarrier_Load(&cleanup_list_)); - while (head != NULL) { - head->cleanup(head->elem); - head = head->next; +void ArenaImpl::CleanupList(Block* head) { + // Have to do this in a first pass, because some of the destructors might + // refer to memory in other blocks. + for (Block* b = head; b; b = b->next) { + CleanupChunk* list = b->cleanup; + while (list) { + size_t n = list->len; + CleanupNode* node = &list->nodes[list->len - 1]; + for (size_t i = 0; i < n; i++, node--) { + node->cleanup(node->elem); + } + list = list->next; + } + b->cleanup = NULL; } - cleanup_list_ = 0; } -Arena::Block* Arena::FindBlock(void* me) { +ArenaImpl::Block* ArenaImpl::FindBlock(void* me) { // TODO(sanjay): We might want to keep a separate list with one // entry per thread. Block* b = reinterpret_cast<Block*>(google::protobuf::internal::Acquire_Load(&blocks_)); @@ -311,5 +344,14 @@ Arena::Block* Arena::FindBlock(void* me) { return b; } +} // namespace internal + +void Arena::OnArenaAllocation(const std::type_info* allocated_type, + size_t n) const { + if (on_arena_allocation_ != NULL) { + on_arena_allocation_(allocated_type, n, hooks_cookie_); + } +} + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 0ffc6004..f8a94705 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -37,7 +37,7 @@ #ifdef max #undef max // Visual Studio defines this macro #endif -#if __cplusplus >= 201103L +#if LANG_CXX11 #include <google/protobuf/stubs/type_traits.h> #endif #if defined(_MSC_VER) && !_HAS_EXCEPTIONS @@ -51,13 +51,7 @@ using type_info = ::type_info; #include <typeinfo> #endif -#include <google/protobuf/stubs/atomic_sequence_num.h> -#include <google/protobuf/stubs/atomicops.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/mutex.h> -#include <google/protobuf/stubs/type_traits.h> - +#include <google/protobuf/arena_impl.h> namespace google { namespace protobuf { @@ -122,7 +116,6 @@ struct ArenaOptions { // from the arena. By default, it contains a ptr to a wrapper function that // calls free. void (*block_dealloc)(void*, size_t); - // Hooks for adding external functionality such as user-specific metrics // collection, specific debugging abilities, etc. // Init hook may return a pointer to a cookie to be stored in the arena. @@ -225,21 +218,38 @@ class LIBPROTOBUF_EXPORT Arena { public: // Arena constructor taking custom options. See ArenaOptions below for // descriptions of the options available. - explicit Arena(const ArenaOptions& options) : options_(options) { - Init(); + explicit Arena(const ArenaOptions& options) : impl_(options) { + Init(options); } // Default constructor with sensible default options, tuned for average // use-cases. - Arena() { - Init(); + Arena() : impl_(ArenaOptions()) { Init(ArenaOptions()); } + + ~Arena() { + uint64 space_allocated = SpaceAllocated(); + // Call the reset hook + if (on_arena_reset_ != NULL) { + on_arena_reset_(this, hooks_cookie_, space_allocated); + } + + // Call the destruction hook + if (on_arena_destruction_ != NULL) { + on_arena_destruction_(this, hooks_cookie_, space_allocated); + } } - // Destructor deletes all owned heap allocated objects, and destructs objects - // that have non-trivial destructors, except for proto2 message objects whose - // destructors can be skipped. Also, frees all blocks except the initial block - // if it was passed in. - ~Arena(); + void Init(const ArenaOptions& options) { + on_arena_allocation_ = options.on_arena_allocation; + on_arena_reset_ = options.on_arena_reset; + on_arena_destruction_ = options.on_arena_destruction; + // Call the initialization hook + if (options.on_arena_init != NULL) { + hooks_cookie_ = options.on_arena_init(this); + } else { + hooks_cookie_ = NULL; + } + } // API to create proto2 message objects on the arena. If the arena passed in // is NULL, then a heap allocated object is returned. Type T must be a message @@ -253,10 +263,15 @@ class LIBPROTOBUF_EXPORT Arena { // allocation protocol, documented above. template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* CreateMessage(::google::protobuf::Arena* arena) { +#if LANG_CXX11 + static_assert( + InternalHelper<T>::is_arena_constructable::value, + "CreateMessage can only construct types that are ArenaConstructable"); +#endif if (arena == NULL) { return new T; } else { - return arena->CreateMessageInternal<T>(static_cast<T*>(0)); + return arena->CreateMessageInternal<T>(); } } @@ -265,11 +280,15 @@ class LIBPROTOBUF_EXPORT Arena { // take additional constructor arguments. template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* CreateMessage(::google::protobuf::Arena* arena, const Arg& arg) { +#if LANG_CXX11 + static_assert( + InternalHelper<T>::is_arena_constructable::value, + "CreateMessage can only construct types that are ArenaConstructable"); +#endif if (arena == NULL) { return new T(NULL, arg); } else { - return arena->CreateMessageInternal<T>(static_cast<T*>(0), - arg); + return arena->CreateMessageInternal<T>(arg); } } @@ -280,11 +299,15 @@ class LIBPROTOBUF_EXPORT Arena { static T* CreateMessage(::google::protobuf::Arena* arena, const Arg1& arg1, const Arg2& arg2) { +#if LANG_CXX11 + static_assert( + InternalHelper<T>::is_arena_constructable::value, + "CreateMessage can only construct types that are ArenaConstructable"); +#endif if (arena == NULL) { return new T(NULL, arg1, arg2); } else { - return arena->CreateMessageInternal<T>(static_cast<T*>(0), - arg1, arg2); + return arena->CreateMessageInternal<T>(arg1, arg2); } } @@ -463,24 +486,33 @@ class LIBPROTOBUF_EXPORT Arena { // Returns the total space allocated by the arena, which is the sum of the // sizes of the underlying blocks. This method is relatively fast; a counter // is kept as blocks are allocated. - uint64 SpaceAllocated() const; + uint64 SpaceAllocated() const { return impl_.SpaceAllocated(); } // Returns the total space used by the arena. Similar to SpaceAllocated but // does not include free space and block overhead. The total space returned // may not include space used by other threads executing concurrently with // the call to this method. - GOOGLE_ATTRIBUTE_NOINLINE uint64 SpaceUsed() const; + uint64 SpaceUsed() const { return impl_.SpaceUsed(); } // DEPRECATED. Please use SpaceAllocated() and SpaceUsed(). // // Combines SpaceAllocated and SpaceUsed. Returns a pair of // <space_allocated, space_used>. - GOOGLE_ATTRIBUTE_NOINLINE std::pair<uint64, uint64> SpaceAllocatedAndUsed() const; + std::pair<uint64, uint64> SpaceAllocatedAndUsed() const { + return std::make_pair(SpaceAllocated(), SpaceUsed()); + } // Frees all storage allocated by this arena after calling destructors // registered with OwnDestructor() and freeing objects registered with Own(). // Any objects allocated on this arena are unusable after this call. It also // returns the total space used by the arena which is the sums of the sizes // of the allocated blocks. This method is not thread-safe. - GOOGLE_ATTRIBUTE_NOINLINE uint64 Reset(); + GOOGLE_ATTRIBUTE_NOINLINE uint64 Reset() { + uint64 space_allocated = SpaceAllocated(); + // Call the reset hook + if (on_arena_reset_ != NULL) { + on_arena_reset_(this, hooks_cookie_, space_allocated); + } + return impl_.Reset(); + } // Adds |object| to a list of heap-allocated objects to be freed with |delete| // when the arena is destroyed or reset. @@ -497,7 +529,7 @@ class LIBPROTOBUF_EXPORT Arena { template <typename T> GOOGLE_ATTRIBUTE_NOINLINE void OwnDestructor(T* object) { if (object != NULL) { - AddListNode(object, &internal::arena_destruct_object<T>); + impl_.AddCleanup(object, &internal::arena_destruct_object<T>); } } @@ -507,7 +539,7 @@ class LIBPROTOBUF_EXPORT Arena { // the class destructor. GOOGLE_ATTRIBUTE_NOINLINE void OwnCustomDestructor(void* object, void (*destruct)(void*)) { - AddListNode(object, destruct); + impl_.AddCleanup(object, destruct); } // Retrieves the arena associated with |value| if |value| is an arena-capable @@ -516,19 +548,59 @@ class LIBPROTOBUF_EXPORT Arena { // resolves at compile-time. template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE static ::google::protobuf::Arena* GetArena(const T* value) { - return GetArenaInternal(value, static_cast<T*>(0)); + return GetArenaInternal(value, is_arena_constructable<T>()); } - private: - struct InternalIsArenaConstructableHelper { + template <typename T> + class InternalHelper { + template <typename U> + static char DestructorSkippable(const typename U::DestructorSkippable_*); + template <typename U> + static double DestructorSkippable(...); + + typedef google::protobuf::internal::integral_constant< + bool, sizeof(DestructorSkippable<T>(static_cast<const T*>(0))) == + sizeof(char) || + google::protobuf::internal::has_trivial_destructor<T>::value> + is_destructor_skippable; + template<typename U> static char ArenaConstructable( const typename U::InternalArenaConstructable_*); template<typename U> static double ArenaConstructable(...); + + typedef google::protobuf::internal::integral_constant<bool, sizeof(ArenaConstructable<T>( + static_cast<const T*>(0))) == + sizeof(char)> + is_arena_constructable; + +#if LANG_CXX11 + template <typename... Args> + static T* Construct(void* ptr, Args&&... args) { + return new (ptr) T(std::forward<Args>(args)...); + } +#else + template <typename Arg1> + static T* Construct(void* ptr, const Arg1& arg1) { + return new (ptr) T(arg1); + } + template <typename Arg1, typename Arg2> + static T* Construct(void* ptr, const Arg1& arg1, const Arg2& arg2) { + return new (ptr) T(arg1, arg2); + } + template <typename Arg1, typename Arg2, typename Arg3> + static T* Construct(void* ptr, const Arg1& arg1, + const Arg2& arg2, const Arg3& arg3) { + return new (ptr) T(arg1, arg2, arg3); + } +#endif // LANG_CXX11 + + static Arena* GetArena(const T* p) { return p->GetArenaNoVirtual(); } + + friend class Arena; }; - public: // Helper typetrait that indicates support for arenas in a type T at compile // time. This is public only to allow construction of higher-level templated // utilities. is_arena_constructable<T>::value is true if the message type T @@ -537,113 +609,54 @@ class LIBPROTOBUF_EXPORT Arena { // This is inside Arena because only Arena has the friend relationships // necessary to see the underlying generated code traits. template <typename T> - struct is_arena_constructable - : public google::protobuf::internal::integral_constant< - bool, sizeof(InternalIsArenaConstructableHelper::ArenaConstructable< - const T>(static_cast<const T*>(0))) == sizeof(char)> { - }; + struct is_arena_constructable : InternalHelper<T>::is_arena_constructable {}; private: - // Blocks are variable length malloc-ed objects. The following structure - // describes the common header for all blocks. - struct Block { - void* owner; // &ThreadCache of thread that owns this block, or - // &this->owner if not yet owned by a thread. - Block* next; // Next block in arena (may have different owner) - // ((char*) &block) + pos is next available byte. It is always - // aligned at a multiple of 8 bytes. - size_t pos; - size_t size; // total size of the block. - GOOGLE_ATTRIBUTE_ALWAYS_INLINE size_t avail() const { return size - pos; } - // data follows - }; - - template<typename Type> friend class ::google::protobuf::internal::GenericTypeHandler; - friend class MockArena; // For unit-testing. - friend class internal::ArenaString; // For AllocateAligned. - friend class internal::LazyField; // For CreateMaybeMessage. - - struct ThreadCache { - // The ThreadCache is considered valid as long as this matches the - // lifecycle_id of the arena being used. - int64 last_lifecycle_id_seen; - Block* last_block_used_; - }; - - static const size_t kHeaderSize = sizeof(Block); - static google::protobuf::internal::SequenceNumber lifecycle_id_generator_; -#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) - // Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread - // local storage class we implemented. - // iOS also does not support the GOOGLE_THREAD_LOCAL keyword. - static ThreadCache& thread_cache(); -#elif defined(PROTOBUF_USE_DLLS) - // Thread local variables cannot be exposed through DLL interface but we can - // wrap them in static functions. - static ThreadCache& thread_cache(); -#else - static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_; - static ThreadCache& thread_cache() { return thread_cache_; } -#endif - - // SFINAE for skipping addition to delete list for a message type when created - // with CreateMessage. This is mainly to skip proto2/proto1 message objects - // with cc_enable_arenas=true from being part of the delete list. Also, note, - // compiler will optimize out the branch in CreateInternal<T>. - template<typename T> - static inline bool SkipDeleteList(typename T::DestructorSkippable_*) { - return true; + void OnArenaAllocation(const std::type_info* allocated_type, size_t n) const; + inline void AllocHook(const std::type_info* allocated_type, size_t n) const { + if (GOOGLE_PREDICT_FALSE(hooks_cookie_ != NULL)) { + OnArenaAllocation(allocated_type, n); + } } - // For message objects that don't have the DestructorSkippable_ trait, we - // always add to the delete list. - template<typename T> - static inline bool SkipDeleteList(...) { - return google::protobuf::internal::has_trivial_destructor<T>::value; + // Allocate and also optionally call on_arena_allocation callback with the + // allocated type info when the hooks are in place in ArenaOptions and + // the cookie is not null. + template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE + void* AllocateInternal(bool skip_explicit_ownership) { + const size_t n = internal::AlignUpTo8(sizeof(T)); + AllocHook(RTTI_TYPE_ID(T), n); + // Monitor allocation if needed. + if (skip_explicit_ownership) { + return impl_.AllocateAligned(n); + } else { + return impl_.AllocateAlignedAndAddCleanup( + n, &internal::arena_destruct_object<T>); + } } - private: - struct InternalIsDestructorSkippableHelper { - template<typename U> - static char DestructorSkippable( - const typename U::DestructorSkippable_*); - template<typename U> - static double DestructorSkippable(...); - }; - - public: - // Helper typetrait that indicates whether the desctructor of type T should be - // called when arena is destroyed at compile time. This is only to allow - // construction of higher-level templated utilities. - // is_destructor_skippable<T>::value is true if the destructor of the message - // type T should not be called when arena is destroyed or false otherwise. - // This is inside Arena because only Arena has the friend relationships - // necessary to see the underlying generated code traits. - template<typename T> - struct is_destructor_skippable - : public google::protobuf::internal::integral_constant< - bool, - sizeof(InternalIsDestructorSkippableHelper::DestructorSkippable< - const T>(static_cast<const T*>(0))) == sizeof(char) || - google::protobuf::internal::has_trivial_destructor<T>::value> {}; - - private: // CreateMessage<T> requires that T supports arenas, but this private method // works whether or not T supports arenas. These are not exposed to user code // as it can cause confusing API usages, and end up having double free in // user code. These are used only internally from LazyField and Repeated // fields, since they are designed to work in all mode combinations. - template<typename Msg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE - static Msg* CreateMaybeMessage( - Arena* arena, typename Msg::InternalArenaConstructable_*) { + template <typename Msg> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static Msg* CreateMaybeMessage(Arena* arena, + google::protobuf::internal::true_type) { return CreateMessage<Msg>(arena); } - template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE - static T* CreateMaybeMessage(Arena* arena, ...) { + template <typename T> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* CreateMaybeMessage(Arena* arena, + google::protobuf::internal::false_type) { return Create<T>(arena); } + template <typename T> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* CreateMaybeMessage(Arena* arena) { + return CreateMaybeMessage<T>(arena, is_arena_constructable<T>()); + } + // Just allocate the required size for the given type assuming the // type has a trivial constructor. template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE @@ -651,47 +664,34 @@ class LIBPROTOBUF_EXPORT Arena { GOOGLE_CHECK_LE(num_elements, std::numeric_limits<size_t>::max() / sizeof(T)) << "Requested size is too large to fit into size_t."; - return static_cast<T*>( - AllocateAligned(RTTI_TYPE_ID(T), sizeof(T) * num_elements)); + const size_t n = internal::AlignUpTo8(sizeof(T) * num_elements); + // Monitor allocation if needed. + AllocHook(RTTI_TYPE_ID(T), n); + return static_cast<T*>(impl_.AllocateAligned(n)); } #if LANG_CXX11 template <typename T, typename... Args> GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership, Args&&... args) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + return new (AllocateInternal<T>(skip_explicit_ownership)) T(std::forward<Args>(args)...); - if (!skip_explicit_ownership) { - AddListNode(t, &internal::arena_destruct_object<T>); - } - return t; } -#endif +#else template <typename T> 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<T>); - } - return t; + return new (AllocateInternal<T>(skip_explicit_ownership)) T(); } template <typename T, typename Arg> 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); - if (!skip_explicit_ownership) { - AddListNode(t, &internal::arena_destruct_object<T>); - } - return t; + return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg); } - template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE - T* CreateInternal( - bool skip_explicit_ownership, const Arg1& arg1, const Arg2& arg2) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg1, arg2); - if (!skip_explicit_ownership) { - AddListNode(t, &internal::arena_destruct_object<T>); - } - return t; + template <typename T, typename Arg1, typename Arg2> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2) { + return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg1, arg2); } template <typename T, typename Arg1, typename Arg2, typename Arg3> @@ -699,12 +699,8 @@ class LIBPROTOBUF_EXPORT Arena { const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg1, arg2, arg3); - if (!skip_explicit_ownership) { - AddListNode(t, &internal::arena_destruct_object<T>); - } - return t; } template <typename T, typename Arg1, typename Arg2, typename Arg3, @@ -714,12 +710,8 @@ class LIBPROTOBUF_EXPORT Arena { const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg1, arg2, arg3, arg4); - if (!skip_explicit_ownership) { - AddListNode(t, &internal::arena_destruct_object<T>); - } - return t; } template <typename T, typename Arg1, typename Arg2, typename Arg3, @@ -730,12 +722,8 @@ class LIBPROTOBUF_EXPORT Arena { const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg1, arg2, arg3, arg4, arg5); - if (!skip_explicit_ownership) { - AddListNode(t, &internal::arena_destruct_object<T>); - } - return t; } template <typename T, typename Arg1, typename Arg2, typename Arg3, @@ -747,12 +735,8 @@ class LIBPROTOBUF_EXPORT Arena { const Arg4& arg4, const Arg5& arg5, const Arg6& arg6) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg1, arg2, arg3, arg4, arg5, arg6); - if (!skip_explicit_ownership) { - AddListNode(t, &internal::arena_destruct_object<T>); - } - return t; } template <typename T, typename Arg1, typename Arg2, typename Arg3, @@ -765,12 +749,8 @@ class LIBPROTOBUF_EXPORT Arena { const Arg5& arg5, const Arg6& arg6, const Arg7& arg7) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg1, arg2, arg3, arg4, arg5, arg6, arg7); - if (!skip_explicit_ownership) { - AddListNode(t, &internal::arena_destruct_object<T>); - } - return t; } template <typename T, typename Arg1, typename Arg2, typename Arg3, @@ -785,30 +765,30 @@ class LIBPROTOBUF_EXPORT Arena { const Arg6& arg6, const Arg7& arg7, const Arg8& arg8) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + return new (AllocateInternal<T>(skip_explicit_ownership)) T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - if (!skip_explicit_ownership) { - AddListNode(t, &internal::arena_destruct_object<T>); - } - return t; } - - template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE - T* CreateMessageInternal(typename T::InternalArenaConstructable_*) { - return CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), this); +#endif + template <typename T> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal() { + return InternalHelper<T>::Construct( + AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value), + this); } - template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE - T* CreateMessageInternal(typename T::InternalArenaConstructable_*, - const Arg& arg) { - return CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), this, arg); + template <typename T, typename Arg> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal(const Arg& arg) { + return InternalHelper<T>::Construct( + AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value), + this, arg); } - template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE - T* CreateMessageInternal(typename T::InternalArenaConstructable_*, - const Arg1& arg1, const Arg2& arg2) { - return CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), this, arg1, - arg2); + template <typename T, typename Arg1, typename Arg2> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal(const Arg1& arg1, + const Arg2& arg2) { + return InternalHelper<T>::Construct( + AllocateInternal<T>(InternalHelper<T>::is_destructor_skippable::value), + this, arg1, arg2); } // CreateInArenaStorage is used to implement map field. Without it, @@ -818,14 +798,15 @@ class LIBPROTOBUF_EXPORT Arena { static void CreateInArenaStorage(T* ptr, Arena* arena) { CreateInArenaStorageInternal(ptr, arena, typename is_arena_constructable<T>::type()); - RegisterDestructorInternal(ptr, arena, - typename is_destructor_skippable<T>::type()); + RegisterDestructorInternal( + ptr, arena, + typename InternalHelper<T>::is_destructor_skippable::type()); } template <typename T> static void CreateInArenaStorageInternal( T* ptr, Arena* arena, google::protobuf::internal::true_type) { - new (ptr) T(arena); + InternalHelper<T>::Construct(ptr, arena); } template <typename T> static void CreateInArenaStorageInternal( @@ -850,100 +831,56 @@ class LIBPROTOBUF_EXPORT Arena { template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE void OwnInternal(T* object, google::protobuf::internal::true_type) { if (object != NULL) { - AddListNode(object, &internal::arena_delete_object< ::google::protobuf::Message >); + impl_.AddCleanup(object, + &internal::arena_delete_object< ::google::protobuf::Message>); } } template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE void OwnInternal(T* object, google::protobuf::internal::false_type) { if (object != NULL) { - AddListNode(object, &internal::arena_delete_object<T>); + impl_.AddCleanup(object, &internal::arena_delete_object<T>); } } // Implementation for GetArena(). Only message objects with // InternalArenaConstructable_ tags can be associated with an arena, and such // objects must implement a GetArenaNoVirtual() method. - template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE - static ::google::protobuf::Arena* GetArenaInternal( - const T* value, typename T::InternalArenaConstructable_*) { - return value->GetArenaNoVirtual(); + template <typename T> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static ::google::protobuf::Arena* GetArenaInternal( + const T* value, google::protobuf::internal::true_type) { + return InternalHelper<T>::GetArena(value); } - template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE - static ::google::protobuf::Arena* GetArenaInternal(const T* /* value */, ...) { + template <typename T> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static ::google::protobuf::Arena* GetArenaInternal( + const T* value, google::protobuf::internal::false_type) { return NULL; } - // Allocate and also optionally call on_arena_allocation callback with the - // allocated type info when the hooks are in place in ArenaOptions and - // the cookie is not null. - void* AllocateAligned(const std::type_info* allocated, size_t n); - - // Allocate an internal allocation, avoiding optional typed monitoring. - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* AllocateAligned(size_t n) { - return AllocateAligned(NULL, n); - } - - void Init(); - - // Free all blocks and return the total space used which is the sums of sizes - // of the all the allocated blocks. - uint64 FreeBlocks(); - - // Add object pointer and cleanup function pointer to the list. - // TODO(rohananil, cfallin): We could pass in a sub-arena into this method - // to avoid polluting blocks of this arena with list nodes. This would help in - // mixed mode (where many protobufs have cc_enable_arenas=false), and is an - // alternative to a chunked linked-list, but with extra overhead of *next. - void AddListNode(void* elem, void (*cleanup)(void*)); - // Delete or Destruct all objects owned by the arena. - void CleanupList(); - uint64 ResetInternal(); - - inline void SetThreadCacheBlock(Block* block) { - thread_cache().last_block_used_ = block; - thread_cache().last_lifecycle_id_seen = lifecycle_id_; + // For friends of arena. + void* AllocateAligned(size_t n) { + AllocHook(NULL, n); + return impl_.AllocateAligned(internal::AlignUpTo8(n)); } - int64 lifecycle_id_; // Unique for each arena. Changes on Reset(). - - google::protobuf::internal::AtomicWord blocks_; // Head of linked list of all allocated blocks - google::protobuf::internal::AtomicWord hint_; // Fast thread-local block access - uint64 space_allocated_; // Sum of sizes of all allocated blocks. - - // Node contains the ptr of the object to be cleaned up and the associated - // cleanup function ptr. - struct Node { - void* elem; // Pointer to the object to be cleaned up. - void (*cleanup)(void*); // Function pointer to the destructor or deleter. - Node* next; // Next node in the list. - }; + internal::ArenaImpl impl_; - google::protobuf::internal::AtomicWord cleanup_list_; // Head of a linked list of nodes containing object - // ptrs and cleanup methods. - - bool owns_first_block_; // Indicates that arena owns the first block - mutable Mutex blocks_lock_; - - void AddBlock(Block* b); - // Access must be synchronized, either by blocks_lock_ or by being called from - // Init()/Reset(). - void AddBlockInternal(Block* b); - void* SlowAlloc(size_t n); - Block* FindBlock(void* me); - Block* NewBlock(void* me, Block* my_last_block, size_t n, - size_t start_block_size, size_t max_block_size); - static void* AllocFromBlock(Block* b, size_t n); - template <typename Key, typename T> - friend class Map; + void* (*on_arena_init_)(Arena* arena); + void (*on_arena_allocation_)(const std::type_info* allocated_type, + uint64 alloc_size, void* cookie); + void (*on_arena_reset_)(Arena* arena, void* cookie, uint64 space_used); + void (*on_arena_destruction_)(Arena* arena, void* cookie, uint64 space_used); // The arena may save a cookie it receives from the external on_init hook // and then use it when calling the on_reset and on_destruction hooks. void* hooks_cookie_; - ArenaOptions options_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Arena); + template <typename Type> + friend class ::google::protobuf::internal::GenericTypeHandler; + friend class internal::ArenaString; // For AllocateAligned. + friend class internal::LazyField; // For CreateMaybeMessage. + template <typename Key, typename T> + friend class Map; }; // Defined above for supporting environments without RTTI. diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h new file mode 100644 index 00000000..b7f0c7b6 --- /dev/null +++ b/src/google/protobuf/arena_impl.h @@ -0,0 +1,214 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This file defines an Arena allocator for better allocation performance. + +#ifndef GOOGLE_PROTOBUF_ARENA_IMPL_H__ +#define GOOGLE_PROTOBUF_ARENA_IMPL_H__ + +#include <limits> + +#include <google/protobuf/stubs/atomic_sequence_num.h> +#include <google/protobuf/stubs/atomicops.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/mutex.h> +#include <google/protobuf/stubs/type_traits.h> + +namespace google { + +namespace protobuf { +namespace internal { + +inline size_t AlignUpTo8(size_t n) { + // Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.) + return (n + 7) & -8; +} + +// This class provides the core Arena memory allocation library. Different +// implementations only need to implement the public interface below. +// Arena is not a template type as that would only be useful if all protos +// in turn would be templates, which will/cannot happen. However separating +// the memory allocation part from the cruft of the API users expect we can +// use #ifdef the select the best implementation based on hardware / OS. +class LIBPROTOBUF_EXPORT ArenaImpl { + public: + struct Options { + size_t start_block_size; + size_t max_block_size; + char* initial_block; + size_t initial_block_size; + void* (*block_alloc)(size_t); + void (*block_dealloc)(void*, size_t); + + template <typename O> + explicit Options(const O& options) + : start_block_size(options.start_block_size), + max_block_size(options.max_block_size), + initial_block(options.initial_block), + initial_block_size(options.initial_block_size), + block_alloc(options.block_alloc), + block_dealloc(options.block_dealloc) {} + }; + + template <typename O> + explicit ArenaImpl(const O& options) : options_(options) { + Init(); + } + + // Destructor deletes all owned heap allocated objects, and destructs objects + // that have non-trivial destructors, except for proto2 message objects whose + // destructors can be skipped. Also, frees all blocks except the initial block + // if it was passed in. + ~ArenaImpl(); + + uint64 Reset(); + + uint64 SpaceAllocated() const; + uint64 SpaceUsed() const; + + void* AllocateAligned(size_t n); + + void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*)); + + // Add object pointer and cleanup function pointer to the list. + void AddCleanup(void* elem, void (*cleanup)(void*)); + + private: + // Node contains the ptr of the object to be cleaned up and the associated + // cleanup function ptr. + struct CleanupNode { + void* elem; // Pointer to the object to be cleaned up. + void (*cleanup)(void*); // Function pointer to the destructor or deleter. + }; + + // Cleanup uses a chunked linked list, to reduce pointer chasing. + struct CleanupChunk { + static size_t SizeOf(size_t i) { + return sizeof(CleanupChunk) + (sizeof(CleanupNode) * (i - 1)); + } + size_t len; // Number of elements currently present. + size_t size; // Total elements in the list. + CleanupChunk* next; // Next node in the list. + CleanupNode nodes[1]; // True length is |size|. + }; + + // Blocks are variable length malloc-ed objects. The following structure + // describes the common header for all blocks. + struct Block { + void* owner; // &ThreadCache of thread that owns this block. + Block* next; // Next block in arena (may have different owner) + CleanupChunk* cleanup; // Head of cleanup list (may point to another block, + // but it must have the same owner). + // ((char*) &block) + pos is next available byte. It is always + // aligned at a multiple of 8 bytes. + size_t pos; + size_t size; // total size of the block. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE size_t avail() const { return size - pos; } + // data follows + }; + + struct ThreadCache { + // The ThreadCache is considered valid as long as this matches the + // lifecycle_id of the arena being used. + int64 last_lifecycle_id_seen; + Block* last_block_used_; + }; + + // kHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8 to + // protect the invariant that pos is always at a multiple of 8. + static const size_t kHeaderSize = (sizeof(Block) + 7) & -8; +#if LANG_CXX11 + static_assert(kHeaderSize % 8 == 0, "kHeaderSize must be a multiple of 8."); +#endif + static google::protobuf::internal::SequenceNumber lifecycle_id_generator_; +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) + // Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread + // local storage class we implemented. + // iOS also does not support the GOOGLE_THREAD_LOCAL keyword. + static ThreadCache& thread_cache(); +#elif defined(PROTOBUF_USE_DLLS) + // Thread local variables cannot be exposed through DLL interface but we can + // wrap them in static functions. + static ThreadCache& thread_cache(); +#else + static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_; + static ThreadCache& thread_cache() { return thread_cache_; } +#endif + + void Init(); + + // Free all blocks and return the total space used which is the sums of sizes + // of the all the allocated blocks. + uint64 FreeBlocks(Block* head); + + void AddCleanupInBlock(Block* b, void* elem, void (*cleanup)(void*)); + Block* ExpandCleanupList(Block* b); + // Delete or Destruct all objects owned by the arena. + void CleanupList(Block* head); + uint64 ResetInternal(); + + inline void CacheBlock(Block* block) { + thread_cache().last_block_used_ = block; + thread_cache().last_lifecycle_id_seen = lifecycle_id_; + google::protobuf::internal::Release_Store(&hint_, reinterpret_cast<google::protobuf::internal::AtomicWord>(block)); + } + + google::protobuf::internal::AtomicWord blocks_; // Head of linked list of all allocated blocks + google::protobuf::internal::AtomicWord hint_; // Fast thread-local block access + uint64 space_allocated_; // Sum of sizes of all allocated blocks. + + bool owns_first_block_; // Indicates that arena owns the first block + mutable Mutex blocks_lock_; + + void AddBlock(Block* b); + // Access must be synchronized, either by blocks_lock_ or by being called from + // Init()/Reset(). + void AddBlockInternal(Block* b); + // Returns a block owned by this thread. + Block* GetBlock(size_t n); + Block* GetBlockSlow(void* me, Block* my_full_block, size_t n); + Block* FindBlock(void* me); + Block* NewBlock(void* me, Block* my_last_block, size_t min_bytes, + size_t start_block_size, size_t max_block_size); + static void* AllocFromBlock(Block* b, size_t n); + + int64 lifecycle_id_; // Unique for each arena. Changes on Reset(). + + Options options_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArenaImpl); +}; + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_ARENA_IMPL_H__ diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc index e5afe42d..c330b903 100644 --- a/src/google/protobuf/arenastring_unittest.cc +++ b/src/google/protobuf/arenastring_unittest.cc @@ -32,16 +32,21 @@ #include <google/protobuf/arenastring.h> -#include <string> +#include <algorithm> +#include <cstdlib> #include <memory> #ifndef _SHARED_PTR_H #include <google/protobuf/stubs/shared_ptr.h> #endif -#include <cstdlib> +#include <string> +#include <vector> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> #include <gtest/gtest.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> + namespace google { using google::protobuf::internal::ArenaString; @@ -87,7 +92,8 @@ TEST(ArenaStringPtrTest, ArenaStringPtrOnArena) { EXPECT_EQ(string("default"), field.Get()); field.Set(&default_value, WrapString("Test short"), &arena); EXPECT_EQ(string("Test short"), field.Get()); - field.Set(&default_value, WrapString("Test long long long long value"), &arena); + field.Set(&default_value, WrapString("Test long long long long value"), + &arena); EXPECT_EQ(string("Test long long long long value"), field.Get()); field.Set(&default_value, string(""), &arena); field.Destroy(&default_value, &arena); @@ -104,5 +110,6 @@ TEST(ArenaStringPtrTest, ArenaStringPtrOnArena) { field2.Destroy(&default_value, &arena); } + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index 6ea5f18d..dd6a59d8 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -50,6 +50,7 @@ namespace io { class ZeroCopyOutputStream; } class FileDescriptor; namespace compiler { +class AccessInfoMap; class Version; // Defined in this file. @@ -112,7 +113,8 @@ class LIBPROTOC_EXPORT CodeGenerator { // runs. class LIBPROTOC_EXPORT GeneratorContext { public: - inline GeneratorContext() {} + inline GeneratorContext() { + } virtual ~GeneratorContext(); // Opens the given file, truncating it if it exists, and returns a @@ -148,6 +150,7 @@ class LIBPROTOC_EXPORT GeneratorContext { // this GeneratorContext. virtual void GetCompilerVersion(Version* version) const; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext); }; diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 4d894c82..5f864041 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -33,6 +33,8 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include <google/protobuf/compiler/command_line_interface.h> + + #include <google/protobuf/stubs/platform_macros.h> #include <stdio.h> @@ -65,13 +67,21 @@ #endif #include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/stringprintf.h> #include <google/protobuf/compiler/importer.h> #include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/plugin.pb.h> #include <google/protobuf/compiler/subprocess.h> #include <google/protobuf/compiler/zip_writer.h> +#include <google/protobuf/compiler/plugin.pb.h> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/importer.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> #include <google/protobuf/text_format.h> #include <google/protobuf/dynamic_message.h> #include <google/protobuf/io/coded_stream.h> @@ -98,8 +108,7 @@ namespace compiler { #endif namespace { -#if defined(_WIN32) && !defined(__CYGWIN__) -static const char* kPathSeparator = ";"; +#if defined(_MSC_VER) // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. using google::protobuf::internal::win32::access; @@ -108,8 +117,6 @@ using google::protobuf::internal::win32::mkdir; using google::protobuf::internal::win32::open; using google::protobuf::internal::win32::setmode; using google::protobuf::internal::win32::write; -#else -static const char* kPathSeparator = ":"; #endif static const char* kDefaultDirectDependenciesViolationMsg = @@ -268,11 +275,14 @@ string PluginName(const string& plugin_prefix, const string& directive) { // strip the "--" and "_out/_opt" and add the plugin prefix. return plugin_prefix + "gen-" + directive.substr(2, directive.size() - 6); } + } // namespace // A MultiFileErrorCollector that prints errors to stderr. -class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, - public io::ErrorCollector { +class CommandLineInterface::ErrorPrinter + : public MultiFileErrorCollector, + public io::ErrorCollector, + public DescriptorPool::ErrorCollector { public: ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL) : format_(format), tree_(tree), found_errors_(false) {} @@ -299,6 +309,25 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, AddErrorOrWarning("input", line, column, message, "warning", std::clog); } + // implements DescriptorPool::ErrorCollector------------------------- + void AddError( + const string& filename, + const string& element_name, + const Message* descriptor, + ErrorLocation location, + const string& message) { + AddErrorOrWarning(filename, -1, -1, message, "error", std::cerr); + } + + void AddWarning( + const string& filename, + const string& element_name, + const Message* descriptor, + ErrorLocation location, + const string& message) { + AddErrorOrWarning(filename, -1, -1, message, "warning", std::clog); + } + bool FoundErrors() const { return found_errors_; } private: @@ -400,6 +429,13 @@ class CommandLineInterface::MemoryOutputStream virtual int64 ByteCount() const { return inner_->ByteCount(); } private: + // Checks to see if "filename_.meta" exists in directory_; if so, fixes the + // offsets in that GeneratedCodeInfo record to reflect bytes inserted in + // filename_ at original offset insertion_offset with length insertion_length. + // We assume that insertions will not occur within any given annotated span + // of text. + void UpdateMetadata(size_t insertion_offset, size_t insertion_length); + // Where to insert the string when it's done. GeneratorContextImpl* directory_; string filename_; @@ -420,8 +456,7 @@ class CommandLineInterface::MemoryOutputStream CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl( const std::vector<const FileDescriptor*>& parsed_files) : parsed_files_(parsed_files), - had_error_(false) { -} + had_error_(false) {} CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() { STLDeleteValues(&files_); @@ -597,6 +632,44 @@ CommandLineInterface::MemoryOutputStream::MemoryOutputStream( inner_(new io::StringOutputStream(&data_)) { } +void CommandLineInterface::MemoryOutputStream::UpdateMetadata( + size_t insertion_offset, size_t insertion_length) { + std::map<string, string*>::iterator meta_file = + directory_->files_.find(filename_ + ".meta"); + if (meta_file == directory_->files_.end() || !meta_file->second) { + // No metadata was recorded for this file. + return; + } + string* encoded_data = meta_file->second; + GeneratedCodeInfo metadata; + bool is_text_format = false; + if (!metadata.ParseFromString(*encoded_data)) { + if (!TextFormat::ParseFromString(*encoded_data, &metadata)) { + // The metadata is invalid. + std::cerr << filename_ + << ".meta: Could not parse metadata as wire or text format." + << std::endl; + return; + } + // Generators that use the public plugin interface emit text-format + // metadata (because in the public plugin protocol, file content must be + // UTF8-encoded strings). + is_text_format = true; + } + for (int i = 0; i < metadata.annotation_size(); ++i) { + GeneratedCodeInfo::Annotation* annotation = metadata.mutable_annotation(i); + if (annotation->begin() >= insertion_offset) { + annotation->set_begin(annotation->begin() + insertion_length); + annotation->set_end(annotation->end() + insertion_length); + } + } + if (is_text_format) { + TextFormat::PrintToString(metadata, encoded_data); + } else { + metadata.SerializeToString(encoded_data); + } +} + CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { // Make sure all data has been written. inner_.reset(); @@ -674,6 +747,7 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { if (indent_.empty()) { // No indent. This makes things easier. target->insert(pos, data_); + UpdateMetadata(pos, data_.size()); } else { // Calculate how much space we need. int indent_size = 0; @@ -683,6 +757,7 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { // Make a hole for it. target->insert(pos, data_.size() + indent_size, '\0'); + UpdateMetadata(pos, data_.size() + indent_size); // Now copy in the data. string::size_type data_pos = 0; @@ -710,6 +785,12 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { // =================================================================== +#if defined(_WIN32) && !defined(__CYGWIN__) +const char* const CommandLineInterface::kPathSeparator = ";"; +#else +const char* const CommandLineInterface::kPathSeparator = ":"; +#endif + CommandLineInterface::CommandLineInterface() : mode_(MODE_COMPILE), print_mode_(PRINT_NONE), @@ -719,9 +800,7 @@ CommandLineInterface::CommandLineInterface() kDefaultDirectDependenciesViolationMsg), imports_in_descriptor_set_(false), source_info_in_descriptor_set_(false), - disallow_services_(false), - inputs_are_proto_path_relative_(false) { -} + disallow_services_(false) {} CommandLineInterface::~CommandLineInterface() {} void CommandLineInterface::RegisterGenerator(const string& flag_name, @@ -762,61 +841,39 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { break; } - AddDefaultProtoPaths(&proto_path_); - - // Set up the source tree. - DiskSourceTree source_tree; - for (int i = 0; i < proto_path_.size(); i++) { - source_tree.MapPath(proto_path_[i].first, proto_path_[i].second); - } - - // Map input files to virtual paths if necessary. - if (!inputs_are_proto_path_relative_) { - if (!MakeInputsBeProtoPathRelative(&source_tree)) { + std::vector<const FileDescriptor*> parsed_files; + // null unless descriptor_set_in_names_.empty() + google::protobuf::scoped_ptr<DiskSourceTree> disk_source_tree; + google::protobuf::scoped_ptr<ErrorPrinter> error_collector; + google::protobuf::scoped_ptr<DescriptorPool> descriptor_pool; + google::protobuf::scoped_ptr<DescriptorDatabase> descriptor_database; + if (descriptor_set_in_names_.empty()) { + disk_source_tree.reset(new DiskSourceTree()); + if (!InitializeDiskSourceTree(disk_source_tree.get())) { return 1; } - } + error_collector.reset( + new ErrorPrinter(error_format_, disk_source_tree.get())); - // Allocate the Importer. - ErrorPrinter error_collector(error_format_, &source_tree); - Importer importer(&source_tree, &error_collector); - - std::vector<const FileDescriptor*> parsed_files; - - // Parse each file. - for (int i = 0; i < input_files_.size(); i++) { - // Import the file. - importer.AddUnusedImportTrackFile(input_files_[i]); - const FileDescriptor* parsed_file = importer.Import(input_files_[i]); - importer.ClearUnusedImportTrackFiles(); - if (parsed_file == NULL) return 1; - parsed_files.push_back(parsed_file); + SourceTreeDescriptorDatabase* database = + new SourceTreeDescriptorDatabase(disk_source_tree.get()); + database->RecordErrorsTo(error_collector.get()); + descriptor_database.reset(database); + descriptor_pool.reset(new DescriptorPool( + descriptor_database.get(), database->GetValidationErrorCollector())); + } else { + error_collector.reset(new ErrorPrinter(error_format_)); - // Enforce --disallow_services. - if (disallow_services_ && parsed_file->service_count() > 0) { - std::cerr << parsed_file->name() << ": This file contains services, but " - "--disallow_services was used." << std::endl; + SimpleDescriptorDatabase* database = new SimpleDescriptorDatabase(); + descriptor_database.reset(database); + if (!PopulateSimpleDescriptorDatabase(database)) { return 1; } - - // Enforce --direct_dependencies - if (direct_dependencies_explicitly_set_) { - bool indirect_imports = false; - for (int i = 0; i < parsed_file->dependency_count(); i++) { - if (direct_dependencies_.find(parsed_file->dependency(i)->name()) == - direct_dependencies_.end()) { - indirect_imports = true; - std::cerr << parsed_file->name() << ": " - << StringReplace(direct_dependencies_violation_msg_, "%s", - parsed_file->dependency(i)->name(), - true /* replace_all */) - << std::endl; - } - } - if (indirect_imports) { - return 1; - } - } + descriptor_pool.reset(new DescriptorPool(database, error_collector.get())); + } + descriptor_pool->EnforceWeakDependencies(true); + if (!ParseInputFiles(descriptor_pool.get(), &parsed_files)) { + return 1; } // We construct a separate GeneratorContext for each output location. Note @@ -869,15 +926,16 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { } if (!dependency_out_name_.empty()) { + GOOGLE_DCHECK(disk_source_tree.get()); if (!GenerateDependencyManifestFile(parsed_files, output_directories, - &source_tree)) { + disk_source_tree.get())) { return 1; } } STLDeleteValues(&output_directories); - if (!descriptor_set_name_.empty()) { + if (!descriptor_set_out_name_.empty()) { if (!WriteDescriptorSet(parsed_files)) { return 1; } @@ -896,13 +954,13 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { return 1; } } else { - if (!EncodeOrDecode(importer.pool())) { + if (!EncodeOrDecode(descriptor_pool.get())) { return 1; } } } - if (error_collector.FoundErrors()) { + if (error_collector->FoundErrors()) { return 1; } @@ -918,7 +976,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { break; case PRINT_NONE: GOOGLE_LOG(ERROR) << "If the code reaches here, it usually means a bug of " - "flag parsing in the CommonadLineInterface."; + "flag parsing in the CommandLineInterface."; return 1; // Do not add a default case. @@ -928,6 +986,112 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { return 0; } +bool CommandLineInterface::InitializeDiskSourceTree( + DiskSourceTree* source_tree) { + AddDefaultProtoPaths(&proto_path_); + + // Set up the source tree. + for (int i = 0; i < proto_path_.size(); i++) { + source_tree->MapPath(proto_path_[i].first, proto_path_[i].second); + } + + // Map input files to virtual paths if possible. + if (!MakeInputsBeProtoPathRelative(source_tree)) { + return false; + } + return true; +} + +bool CommandLineInterface::PopulateSimpleDescriptorDatabase( + SimpleDescriptorDatabase* database) { + for (int i = 0; i < descriptor_set_in_names_.size(); i++) { + int fd; + do { + fd = open(descriptor_set_in_names_[i].c_str(), O_RDONLY | O_BINARY); + } while (fd < 0 && errno == EINTR); + if (fd < 0) { + std::cerr << descriptor_set_in_names_[i] << ": " + << strerror(ENOENT) << std::endl; + return false; + } + + FileDescriptorSet file_descriptor_set; + bool parsed = file_descriptor_set.ParseFromFileDescriptor(fd); + if (close(fd) != 0) { + std::cerr << descriptor_set_in_names_[i] << ": close: " + << strerror(errno); + return false; + } + + if (!parsed) { + std::cerr << descriptor_set_in_names_[i] << ": Unable to parse." + << std::endl; + return false; + } + + for (int j = 0; j < file_descriptor_set.file_size(); j++) { + FileDescriptorProto previously_added_file_descriptor_proto; + if (database->FindFileByName(file_descriptor_set.file(j).name(), + &previously_added_file_descriptor_proto)) { + // already present - skip + continue; + } + if (!database->Add(file_descriptor_set.file(j))) { + return false; + } + } + } + return true; +} + +bool CommandLineInterface::ParseInputFiles( + DescriptorPool* descriptor_pool, + std::vector<const FileDescriptor*>* parsed_files) { + + // Parse each file. + for (int i = 0; i < input_files_.size(); i++) { + // Import the file. + descriptor_pool->AddUnusedImportTrackFile(input_files_[i]); + const FileDescriptor* parsed_file = + descriptor_pool->FindFileByName(input_files_[i]); + descriptor_pool->ClearUnusedImportTrackFiles(); + if (parsed_file == NULL) { + if (!descriptor_set_in_names_.empty()) { + std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl; + } + return false; + } + parsed_files->push_back(parsed_file); + + // Enforce --disallow_services. + if (disallow_services_ && parsed_file->service_count() > 0) { + std::cerr << parsed_file->name() << ": This file contains services, but " + "--disallow_services was used." << std::endl; + return false; + } + + // Enforce --direct_dependencies + if (direct_dependencies_explicitly_set_) { + bool indirect_imports = false; + for (int i = 0; i < parsed_file->dependency_count(); i++) { + if (direct_dependencies_.find(parsed_file->dependency(i)->name()) == + direct_dependencies_.end()) { + indirect_imports = true; + std::cerr << parsed_file->name() << ": " + << StringReplace(direct_dependencies_violation_msg_, "%s", + parsed_file->dependency(i)->name(), + true /* replace_all */) + << std::endl; + } + } + if (indirect_imports) { + return false; + } + } + } + return true; +} + void CommandLineInterface::Clear() { // Clear all members that are set by Run(). Note that we must not clear // members which are set by other methods before Run() is called. @@ -938,7 +1102,8 @@ void CommandLineInterface::Clear() { direct_dependencies_violation_msg_ = kDefaultDirectDependenciesViolationMsg; output_directives_.clear(); codec_type_.clear(); - descriptor_set_name_.clear(); + descriptor_set_in_names_.clear(); + descriptor_set_out_name_.clear(); dependency_out_name_.clear(); mode_ = MODE_COMPILE; @@ -952,6 +1117,17 @@ void CommandLineInterface::Clear() { bool CommandLineInterface::MakeInputsBeProtoPathRelative( DiskSourceTree* source_tree) { for (int i = 0; i < input_files_.size(); i++) { + // If the input file path is not a physical file path, it must be a virtual + // path. + if (access(input_files_[i].c_str(), F_OK) < 0) { + string disk_file; + if (source_tree->VirtualFileToDiskFile(input_files_[i], &disk_file)) { + return true; + } else { + std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl; + return false; + } + } string virtual_file, shadowing_disk_file; switch (source_tree->DiskFileToVirtualFile( input_files_[i], &virtual_file, &shadowing_disk_file)) { @@ -969,12 +1145,14 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative( case DiskSourceTree::CANNOT_OPEN: std::cerr << input_files_[i] << ": " << strerror(errno) << std::endl; return false; - case DiskSourceTree::NO_MAPPING: - // First check if the file exists at all. - if (access(input_files_[i].c_str(), F_OK) < 0) { - // File does not even exist. - std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl; + case DiskSourceTree::NO_MAPPING: { + // Try to interpret the path as a virtual path. + string disk_file; + if (source_tree->VirtualFileToDiskFile(input_files_[i], &disk_file)) { + return true; } else { + // The input file path can't be mapped to any --proto_path and it also + // can't be interpreted as a virtual path. std::cerr << input_files_[i] << ": File does not reside within any path " @@ -983,9 +1161,11 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative( "proto_path must be an exact prefix of the .proto file " "names -- protoc is too dumb to figure out when two paths " "(e.g. absolute and relative) are equivalent (it's harder " - "than you think)." << std::endl; + "than you think)." + << std::endl; + return false; } - return false; + } } } @@ -1081,7 +1261,7 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { return PARSE_ARGUMENT_FAIL; } if (mode_ == MODE_COMPILE && output_directives_.empty() && - descriptor_set_name_.empty()) { + descriptor_set_out_name_.empty()) { std::cerr << "Missing output directives." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -1096,11 +1276,11 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { << std::endl; return PARSE_ARGUMENT_FAIL; } - if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) { + if (imports_in_descriptor_set_ && descriptor_set_out_name_.empty()) { std::cerr << "--include_imports only makes sense when combined with " "--descriptor_set_out." << std::endl; } - if (source_info_in_descriptor_set_ && descriptor_set_name_.empty()) { + if (source_info_in_descriptor_set_ && descriptor_set_out_name_.empty()) { std::cerr << "--include_source_info only makes sense when combined with " "--descriptor_set_out." << std::endl; } @@ -1187,11 +1367,20 @@ CommandLineInterface::InterpretArgument(const string& name, input_files_.push_back(value); } else if (name == "-I" || name == "--proto_path") { + if (!descriptor_set_in_names_.empty()) { + std::cerr << "Only one of " << name + << " and --descriptor_set_in can be specified." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + // Java's -classpath (and some other languages) delimits path components // with colons. Let's accept that syntax too just to make things more // intuitive. std::vector<string> parts = Split( - value, kPathSeparator, true); + value, + CommandLineInterface::kPathSeparator, + true); for (int i = 0; i < parts.size(); i++) { string virtual_path; @@ -1249,8 +1438,38 @@ CommandLineInterface::InterpretArgument(const string& name, } else if (name == "--direct_dependencies_violation_msg") { direct_dependencies_violation_msg_ = value; + } else if (name == "--descriptor_set_in") { + if (!descriptor_set_in_names_.empty()) { + std::cerr << name << " may only be passed once. To specify multiple " + "descriptor sets, pass them all as a single " + "parameter separated by '" + << CommandLineInterface::kPathSeparator << "'." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + if (value.empty()) { + std::cerr << name << " requires a non-empty value." << std::endl; + return PARSE_ARGUMENT_FAIL; + } + if (!proto_path_.empty()) { + std::cerr << "Only one of " << name + << " and --proto_path can be specified." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + if (!dependency_out_name_.empty()) { + std::cerr << name << " cannot be used with --dependency_out." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + + descriptor_set_in_names_ = Split( + value, + CommandLineInterface::kPathSeparator, + true); + } else if (name == "-o" || name == "--descriptor_set_out") { - if (!descriptor_set_name_.empty()) { + if (!descriptor_set_out_name_.empty()) { std::cerr << name << " may only be passed once." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -1264,7 +1483,7 @@ CommandLineInterface::InterpretArgument(const string& name, "same time." << std::endl; return PARSE_ARGUMENT_FAIL; } - descriptor_set_name_ = value; + descriptor_set_out_name_ = value; } else if (name == "--dependency_out") { if (!dependency_out_name_.empty()) { @@ -1275,6 +1494,11 @@ CommandLineInterface::InterpretArgument(const string& name, std::cerr << name << " requires a non-empty value." << std::endl; return PARSE_ARGUMENT_FAIL; } + if (!descriptor_set_in_names_.empty()) { + std::cerr << name << " cannot be used with --descriptor_set_in." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } dependency_out_name_ = value; } else if (name == "--include_imports") { @@ -1314,7 +1538,7 @@ CommandLineInterface::InterpretArgument(const string& name, << std::endl; return PARSE_ARGUMENT_FAIL; } - if (!output_directives_.empty() || !descriptor_set_name_.empty()) { + if (!output_directives_.empty() || !descriptor_set_out_name_.empty()) { std::cerr << "Cannot use " << name << " and generate code or descriptors at the same time." << std::endl; @@ -1380,7 +1604,7 @@ CommandLineInterface::InterpretArgument(const string& name, << "other info at the same time." << std::endl; return PARSE_ARGUMENT_FAIL; } - if (!output_directives_.empty() || !descriptor_set_name_.empty()) { + if (!output_directives_.empty() || !descriptor_set_out_name_.empty()) { std::cerr << "Cannot use " << name << " and generate code or descriptors at the same time." << std::endl; @@ -1472,6 +1696,14 @@ void CommandLineInterface::PrintHelpText() { " pairs in text format to standard output. No\n" " PROTO_FILES should be given when using this\n" " flag.\n" +" --descriptor_set_in=FILES Specifies a delimited list of FILES\n" +" each containing a FileDescriptorSet (a\n" +" protocol buffer defined in descriptor.proto).\n" +" The FileDescriptor for each of the PROTO_FILES\n" +" provided will be loaded from these\n" +" FileDescriptorSets. If a FileDescriptor\n" +" appears multiple times, the first occurrence\n" +" will be used.\n" " -oFILE, Writes a FileDescriptorSet (a protocol buffer,\n" " --descriptor_set_out=FILE defined in descriptor.proto) containing all of\n" " the input files to FILE.\n" @@ -1651,6 +1883,7 @@ bool CommandLineInterface::GeneratePluginOutput( request.set_parameter(parameter); } + std::set<const FileDescriptor*> already_seen; for (int i = 0; i < parsed_files.size(); i++) { request.add_file_to_generate(parsed_files[i]->name()); @@ -1819,24 +2052,24 @@ bool CommandLineInterface::WriteDescriptorSet( int fd; do { - fd = open(descriptor_set_name_.c_str(), + fd = open(descriptor_set_out_name_.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); } while (fd < 0 && errno == EINTR); if (fd < 0) { - perror(descriptor_set_name_.c_str()); + perror(descriptor_set_out_name_.c_str()); return false; } io::FileOutputStream out(fd); if (!file_set.SerializeToZeroCopyStream(&out)) { - std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) + std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno()) << std::endl; out.Close(); return false; } if (!out.Close()) { - std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) + std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno()) << std::endl; return false; } diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index 997c1748..e6596575 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -52,17 +52,16 @@ namespace protobuf { class Descriptor; // descriptor.h class DescriptorPool; // descriptor.h class FileDescriptor; // descriptor.h +class FileDescriptorSet; // descriptor.h class FileDescriptorProto; // descriptor.pb.h template<typename T> class RepeatedPtrField; // repeated_field.h +class SimpleDescriptorDatabase; // descriptor_database.h -} // namespace protobuf - -namespace protobuf { namespace compiler { -class CodeGenerator; // code_generator.h -class GeneratorContext; // code_generator.h -class DiskSourceTree; // importer.h +class CodeGenerator; // code_generator.h +class GeneratorContext; // code_generator.h +class DiskSourceTree; // importer.h // This class implements the command-line interface to the protocol compiler. // It is designed to make it very easy to create a custom protocol compiler @@ -91,9 +90,21 @@ class DiskSourceTree; // importer.h // The compiler is invoked with syntax like: // protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto // +// The .proto file to compile can be specified on the command line using either +// its physical file path, or a virtual path relative to a diretory specified +// in --proto_path. For example, for src/foo.proto, the following two protoc +// invocations work the same way: +// 1. protoc --proto_path=src src/foo.proto (physical file path) +// 2. protoc --proto_path=src foo.proto (virtual path relative to src) +// +// If a file path can be interpreted both as a physical file path and as a +// relative virtual path, the physical file path takes precendence. +// // For a full description of the command-line syntax, invoke it with --help. class LIBPROTOC_EXPORT CommandLineInterface { public: + static const char* const kPathSeparator; + CommandLineInterface(); ~CommandLineInterface(); @@ -175,17 +186,11 @@ class LIBPROTOC_EXPORT CommandLineInterface { // it calls strerror(). I'm not sure why you'd want to do this anyway. int Run(int argc, const char* const argv[]); - // Call SetInputsAreCwdRelative(true) if the input files given on the command - // line should be interpreted relative to the proto import path specified - // using --proto_path or -I flags. Otherwise, input file names will be - // interpreted relative to the current working directory (or as absolute - // paths if they start with '/'), though they must still reside inside - // a directory given by --proto_path or the compiler will fail. The latter - // mode is generally more intuitive and easier to use, especially e.g. when - // defining implicit rules in Makefiles. - void SetInputsAreProtoPathRelative(bool enable) { - inputs_are_proto_path_relative_ = enable; - } + // DEPRECATED. Calling this method has no effect. Protocol compiler now + // always try to find the .proto file relative to the current directory + // first and if the file is not found, it will then treat the input path + // as a virutal path. + void SetInputsAreProtoPathRelative(bool /* enable */) {} // Provides some text which will be printed when the --version flag is // used. The version of libprotoc will also be printed on the next line @@ -243,6 +248,16 @@ class LIBPROTOC_EXPORT CommandLineInterface { // Print the --help text to stderr. void PrintHelpText(); + // Loads proto_path_ into the provided source_tree. + bool InitializeDiskSourceTree(DiskSourceTree* source_tree); + + // Loads descriptor_set_in into the provided database + bool PopulateSimpleDescriptorDatabase(SimpleDescriptorDatabase* database); + + // Parses input_files_ into parsed_files + bool ParseInputFiles(DescriptorPool* descriptor_pool, + std::vector<const FileDescriptor*>* parsed_files); + // Generate the given output file from the given input. struct OutputDirective; // see below bool GenerateOutput(const std::vector<const FileDescriptor*>& parsed_files, @@ -383,9 +398,13 @@ class LIBPROTOC_EXPORT CommandLineInterface { // decoding. (Empty string indicates --decode_raw.) string codec_type_; + // If --descriptor_set_in was given, these are filenames containing + // parsed FileDescriptorSets to be used for loading protos. Otherwise, empty. + std::vector<string> descriptor_set_in_names_; + // If --descriptor_set_out was given, this is the filename to which the // FileDescriptorSet should be written. Otherwise, empty. - string descriptor_set_name_; + string descriptor_set_out_name_; // If --dependency_out was given, this is the path to the file where the // dependency file will be written. Otherwise, empty. @@ -408,9 +427,6 @@ class LIBPROTOC_EXPORT CommandLineInterface { // Was the --disallow_services flag used? bool disallow_services_; - // See SetInputsAreProtoPathRelative(). - bool inputs_are_proto_path_relative_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface); }; diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 5fbb37a4..73d3e4c9 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -69,7 +69,7 @@ namespace google { namespace protobuf { namespace compiler { -#if defined(_WIN32) +#if defined(_MSC_VER) // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. using google::protobuf::internal::win32::access; @@ -127,10 +127,6 @@ class CommandLineInterfaceTest : public testing::Test { // google3. #endif // !PROTOBUF_OPENSOURCE - void SetInputsAreProtoPathRelative(bool enable) { - cli_.SetInputsAreProtoPathRelative(enable); - } - // ----------------------------------------------------------------- // Methods to check the test results (called after Run()). @@ -190,12 +186,17 @@ class CommandLineInterfaceTest : public testing::Test { const string& insertions, const string& proto_name, const string& message_name); + void CheckGeneratedAnnotations(const string& name, const string& file); void ExpectNullCodeGeneratorCalled(const string& parameter); + void ReadDescriptorSet(const string& filename, FileDescriptorSet* descriptor_set); + void WriteDescriptorSet(const string& filename, + const FileDescriptorSet* descriptor_set); + void ExpectFileContent(const string& filename, const string& content); @@ -249,11 +250,6 @@ class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { // =================================================================== void CommandLineInterfaceTest::SetUp() { - // Most of these tests were written before this option was added, so we - // run with the option on (which used to be the only way) except in certain - // tests where we turn it off. - cli_.SetInputsAreProtoPathRelative(true); - temp_directory_ = TestTempDir() + "/proto2_cli_test_temp"; // If the temp directory already exists, it must be left over from a @@ -279,6 +275,7 @@ void CommandLineInterfaceTest::SetUp() { mock_generators_to_delete_.push_back(generator); cli_.RegisterGenerator("--null_out", generator, "Null output."); + disallow_plugins_ = false; } @@ -469,12 +466,18 @@ void CommandLineInterfaceTest::ExpectGeneratedWithInsertions( proto_name, temp_directory_); } +void CommandLineInterfaceTest::CheckGeneratedAnnotations(const string& name, + const string& file) { + MockCodeGenerator::CheckGeneratedAnnotations(name, file, temp_directory_); +} + void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled( const string& parameter) { EXPECT_TRUE(null_generator_->called_); EXPECT_EQ(parameter, null_generator_->parameter_); } + void CommandLineInterfaceTest::ReadDescriptorSet( const string& filename, FileDescriptorSet* descriptor_set) { string path = temp_directory_ + "/" + filename; @@ -486,6 +489,13 @@ void CommandLineInterfaceTest::ReadDescriptorSet( } } +void CommandLineInterfaceTest::WriteDescriptorSet( + const string& filename, const FileDescriptorSet* descriptor_set) { + string binary_proto; + GOOGLE_CHECK(descriptor_set->SerializeToString(&binary_proto)); + CreateTempFile(filename, binary_proto); +} + void CommandLineInterfaceTest::ExpectCapturedStdout( const string& expected_text) { EXPECT_EQ(expected_text, captured_stdout_); @@ -494,7 +504,8 @@ void CommandLineInterfaceTest::ExpectCapturedStdout( void CommandLineInterfaceTest::ExpectCapturedStdoutSubstringWithZeroReturnCode( const string& expected_substring) { EXPECT_EQ(0, return_code_); - EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, captured_stdout_); + EXPECT_PRED_FORMAT2( + testing::IsSubstring, expected_substring, captured_stdout_); } void CommandLineInterfaceTest::ExpectFileContent( @@ -523,6 +534,22 @@ TEST_F(CommandLineInterfaceTest, BasicOutput) { ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } +TEST_F(CommandLineInterfaceTest, BasicOutput_DescriptorSetIn) { + // Test that the common case works. + FileDescriptorSet file_descriptor_set; + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + WriteDescriptorSet("foo.bin", &file_descriptor_set); + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + TEST_F(CommandLineInterfaceTest, BasicPlugin) { // Test that basic plugins work. @@ -537,6 +564,23 @@ TEST_F(CommandLineInterfaceTest, BasicPlugin) { ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); } +TEST_F(CommandLineInterfaceTest, BasicPlugin_DescriptorSetIn) { + // Test that basic plugins work. + + FileDescriptorSet file_descriptor_set; + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + WriteDescriptorSet("foo.bin", &file_descriptor_set); + + Run("protocol_compiler --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); +} + TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) { // Invoke a generator and a plugin at the same time. @@ -552,6 +596,24 @@ TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) { ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); } +TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin_DescriptorSetIn) { + // Invoke a generator and a plugin at the same time. + + FileDescriptorSet file_descriptor_set; + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + WriteDescriptorSet("foo.bin", &file_descriptor_set); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); + ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); +} + TEST_F(CommandLineInterfaceTest, MultipleInputs) { // Test parsing multiple input files. @@ -576,6 +638,34 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs) { "bar.proto", "Bar"); } +TEST_F(CommandLineInterfaceTest, MultipleInputs_DescriptorSetIn) { + // Test parsing multiple input files. + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_message_type()->set_name("Bar"); + + WriteDescriptorSet("foo.bin", &file_descriptor_set); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto bar.proto"); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "bar.proto", "Bar"); +} + TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) { // Test parsing multiple input files with an import of a separate file. @@ -606,6 +696,165 @@ TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) { "bar.proto", "Bar"); } +TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport_DescriptorSetIn) { + // Test parsing multiple input files with an import of a separate file. + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_dependency("baz.proto"); + DescriptorProto* message = file_descriptor_proto->add_message_type(); + message->set_name("Bar"); + FieldDescriptorProto* field = message->add_field(); + field->set_type_name("Baz"); + field->set_name("a"); + field->set_number(1); + + WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set); + + file_descriptor_set.clear_file(); + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("baz.proto"); + file_descriptor_proto->add_message_type()->set_name("Baz"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bat.proto"); + file_descriptor_proto->add_dependency("baz.proto"); + message = file_descriptor_proto->add_message_type(); + message->set_name("Bat"); + field = message->add_field(); + field->set_type_name("Baz"); + field->set_name("a"); + field->set_number(1); + + WriteDescriptorSet("baz_and_bat.bin", &file_descriptor_set); + Run(strings::Substitute( + "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir " + "--descriptor_set_in=$0 foo.proto bar.proto", + string("$tmpdir/foo_and_bar.bin") + + CommandLineInterface::kPathSeparator + + "$tmpdir/baz_and_bat.bin")); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "bar.proto", "Bar"); + + Run(strings::Substitute( + "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir " + "--descriptor_set_in=$0 baz.proto bat.proto", + string("$tmpdir/foo_and_bar.bin") + + CommandLineInterface::kPathSeparator + + "$tmpdir/baz_and_bat.bin")); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "baz.proto,bat.proto", + "baz.proto", "Baz"); + ExpectGeneratedWithMultipleInputs("test_generator", "baz.proto,bat.proto", + "bat.proto", "Bat"); + ExpectGeneratedWithMultipleInputs("test_plugin", "baz.proto,bat.proto", + "baz.proto", "Baz"); + ExpectGeneratedWithMultipleInputs("test_plugin", "baz.proto,bat.proto", + "bat.proto", "Bat"); +} + +TEST_F(CommandLineInterfaceTest, + MultipleInputsWithImport_DescriptorSetIn_DuplicateFileDescriptor) { + // Test parsing multiple input files with an import of a separate file. + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto foo_file_descriptor_proto; + foo_file_descriptor_proto.set_name("foo.proto"); + foo_file_descriptor_proto.add_message_type()->set_name("Foo"); + + file_descriptor_set.add_file()->CopyFrom(foo_file_descriptor_proto); + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_dependency("baz.proto"); + file_descriptor_proto->add_dependency("foo.proto"); + DescriptorProto* message = file_descriptor_proto->add_message_type(); + message->set_name("Bar"); + FieldDescriptorProto* field = message->add_field(); + field->set_type_name("Baz"); + field->set_name("a"); + field->set_number(1); + field = message->add_field(); + field->set_type_name("Foo"); + field->set_name("f"); + field->set_number(2); + WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set); + + file_descriptor_set.clear_file(); + file_descriptor_set.add_file()->CopyFrom(foo_file_descriptor_proto); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("baz.proto"); + file_descriptor_proto->add_dependency("foo.proto"); + message = file_descriptor_proto->add_message_type(); + message->set_name("Baz"); + field = message->add_field(); + field->set_type_name("Foo"); + field->set_name("f"); + field->set_number(1); + WriteDescriptorSet("foo_and_baz.bin", &file_descriptor_set); + + Run(strings::Substitute( + "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir " + "--descriptor_set_in=$0 bar.proto", + string("$tmpdir/foo_and_bar.bin") + + CommandLineInterface::kPathSeparator + + "$tmpdir/foo_and_baz.bin")); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "bar.proto", "Bar"); + ExpectGenerated("test_plugin", "", "bar.proto", "Bar"); +} + +TEST_F(CommandLineInterfaceTest, + MultipleInputsWithImport_DescriptorSetIn_MissingImport) { + // Test parsing multiple input files with an import of a separate file. + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_dependency("baz.proto"); + DescriptorProto* message = file_descriptor_proto->add_message_type(); + message->set_name("Bar"); + FieldDescriptorProto* field = message->add_field(); + field->set_type_name("Baz"); + field->set_name("a"); + field->set_number(1); + + WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set); + + file_descriptor_set.clear_file(); + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("baz.proto"); + file_descriptor_proto->add_message_type()->set_name("Baz"); + + WriteDescriptorSet("baz.bin", &file_descriptor_set); + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo_and_bar.bin " + "foo.proto bar.proto"); + ExpectErrorSubstring( + "bar.proto: Import \"baz.proto\" was not found or had errors."); + ExpectErrorSubstring("bar.proto: \"Baz\" is not defined."); +} + TEST_F(CommandLineInterfaceTest, CreateDirectory) { // Test that when we output to a sub-directory, it is created. @@ -752,6 +1001,25 @@ TEST_F(CommandLineInterfaceTest, Insert) { "foo.proto", "Foo"); } +TEST_F(CommandLineInterfaceTest, InsertWithAnnotationFixup) { + // Check that annotation spans are updated after insertions. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message MockCodeGenerator_Annotate {}\n"); + + Run("protocol_compiler " + "--test_out=TestParameter:$tmpdir " + "--plug_out=TestPluginParameter:$tmpdir " + "--test_out=insert=test_generator,test_plugin:$tmpdir " + "--plug_out=insert=test_generator,test_plugin:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + CheckGeneratedAnnotations("test_generator", "foo.proto"); + CheckGeneratedAnnotations("test_plugin", "foo.proto"); +} + #if defined(_WIN32) TEST_F(CommandLineInterfaceTest, WindowsOutputPath) { @@ -837,17 +1105,11 @@ TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) { "}\n"); CreateTempFile("b/foo.proto", "this should not be parsed\n"); -#undef PATH_SEPARATOR -#if defined(_WIN32) -#define PATH_SEPARATOR ";" -#else -#define PATH_SEPARATOR ":" -#endif - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir/a" PATH_SEPARATOR "$tmpdir/b foo.proto"); - -#undef PATH_SEPARATOR + Run(strings::Substitute( + "protocol_compiler --test_out=$$tmpdir --proto_path=$0 foo.proto", + string("$tmpdir/a") + + CommandLineInterface::kPathSeparator + + "$tmpdir/b")); ExpectNoErrors(); ExpectGenerated("test_generator", "", "foo.proto", "Foo"); @@ -1057,8 +1319,6 @@ TEST_F(CommandLineInterfaceTest, DirectDependencies_CustomErrorMessage) { TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { // Test that we can accept working-directory-relative input files. - SetInputsAreProtoPathRelative(false); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1316,6 +1576,17 @@ TEST_F(CommandLineInterfaceTest, ParseErrors) { "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n"); } +TEST_F(CommandLineInterfaceTest, ParseErrors_DescriptorSetIn) { + // Test that parse errors are reported. + CreateTempFile("foo.bin", "not a FileDescriptorSet"); + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + + ExpectErrorText( + "$tmpdir/foo.bin: Unable to parse.\n"); +} + TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) { // Test that parse errors are reported from multiple files. @@ -1362,16 +1633,23 @@ TEST_F(CommandLineInterfaceTest, InputNotFoundError) { Run("protocol_compiler --test_out=$tmpdir " "--proto_path=$tmpdir foo.proto"); + ExpectErrorText("foo.proto: No such file or directory\n"); +} + +TEST_F(CommandLineInterfaceTest, InputNotFoundError_DescriptorSetIn) { + // Test what happens if the input file is not found. + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + ExpectErrorText( - "foo.proto: File not found.\n"); + "$tmpdir/foo.bin: No such file or directory\n"); } TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) { // Test what happens when a working-directory-relative input file is not // found. - SetInputsAreProtoPathRelative(false); - Run("protocol_compiler --test_out=$tmpdir " "--proto_path=$tmpdir $tmpdir/foo.proto"); @@ -1383,8 +1661,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) { // Test what happens when a working-directory-relative input file is not // mapped to a virtual path. - SetInputsAreProtoPathRelative(false); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1409,8 +1685,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) { // Check what happens if the input file is not found *and* is not mapped // in the proto_path. - SetInputsAreProtoPathRelative(false); - // Create a directory called "bar" so that we can point --proto_path at it. CreateTempFile("bar/dummy", ""); @@ -1425,8 +1699,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) { // Test what happens when a working-directory-relative input file is shadowed // by another file in the virtual path. - SetInputsAreProtoPathRelative(false); - CreateTempFile("foo/foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1452,8 +1724,34 @@ TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) { "--proto_path=$tmpdir/foo foo.proto"); ExpectErrorText( - "$tmpdir/foo: warning: directory does not exist.\n" - "foo.proto: File not found.\n"); + "$tmpdir/foo: warning: directory does not exist.\n" + "foo.proto: No such file or directory\n"); +} + +TEST_F(CommandLineInterfaceTest, ProtoPathAndDescriptorSetIn) { + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir --descriptor_set_in=$tmpdir/foo.bin foo.proto"); + ExpectErrorText( + "Only one of --descriptor_set_in and --proto_path can be specified.\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin --proto_path=$tmpdir foo.proto"); + ExpectErrorText( + "Only one of --proto_path and --descriptor_set_in can be specified.\n"); +} + +TEST_F(CommandLineInterfaceTest, ProtoPathAndDependencyOut) { + Run("protocol_compiler --test_out=$tmpdir " + "--dependency_out=$tmpdir/manifest " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + ExpectErrorText( + "--descriptor_set_in cannot be used with --dependency_out.\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin " + "--dependency_out=$tmpdir/manifest foo.proto"); + ExpectErrorText( + "--dependency_out cannot be used with --descriptor_set_in.\n"); } TEST_F(CommandLineInterfaceTest, MissingInputError) { @@ -1903,9 +2201,16 @@ TEST_F(CommandLineInterfaceTest, PrintFreeFieldNumbers) { // test as a shell script, but we'd like to be able to run the test on // platforms that don't have a Bourne-compatible shell available (especially // Windows/MSVC). -class EncodeDecodeTest : public testing::Test { + +enum EncodeDecodeTestMode { + PROTO_PATH, + DESCRIPTOR_SET_IN +}; + +class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> { protected: virtual void SetUp() { + WriteUnittestProtoDescriptorSet(); duped_stdin_ = dup(STDIN_FILENO); } @@ -1948,7 +2253,18 @@ class EncodeDecodeTest : public testing::Test { std::vector<string> args; args.push_back("protoc"); SplitStringUsing(command, " ", &args); - args.push_back("--proto_path=" + TestSourceDir()); + switch (GetParam()) { + case PROTO_PATH: + args.push_back("--proto_path=" + TestSourceDir()); + break; + case DESCRIPTOR_SET_IN: + args.push_back(StrCat( + "--descriptor_set_in=", + unittest_proto_descriptor_set_filename_)); + break; + default: + ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam(); + } google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]); for (int i = 0; i < args.size(); i++) { @@ -1956,7 +2272,6 @@ class EncodeDecodeTest : public testing::Test { } CommandLineInterface cli; - cli.SetInputsAreProtoPathRelative(true); CaptureTestStdout(); CaptureTestStderr(); @@ -1994,12 +2309,37 @@ class EncodeDecodeTest : public testing::Test { } private: + void WriteUnittestProtoDescriptorSet() { + unittest_proto_descriptor_set_filename_ = + TestTempDir() + "/unittest_proto_descriptor_set.bin"; + FileDescriptorSet file_descriptor_set; + protobuf_unittest::TestAllTypes test_all_types; + test_all_types.descriptor()->file()->CopyTo(file_descriptor_set.add_file()); + + protobuf_unittest_import::ImportMessage import_message; + import_message.descriptor()->file()->CopyTo(file_descriptor_set.add_file()); + + + protobuf_unittest_import::PublicImportMessage public_import_message; + public_import_message.descriptor()->file()->CopyTo( + file_descriptor_set.add_file()); + GOOGLE_DCHECK(file_descriptor_set.IsInitialized()); + + string binary_proto; + GOOGLE_CHECK(file_descriptor_set.SerializeToString(&binary_proto)); + GOOGLE_CHECK_OK(File::SetContents( + unittest_proto_descriptor_set_filename_, + binary_proto, + true)); + } + int duped_stdin_; string captured_stdout_; string captured_stderr_; + string unittest_proto_descriptor_set_filename_; }; -TEST_F(EncodeDecodeTest, Encode) { +TEST_P(EncodeDecodeTest, Encode) { RedirectStdinFromFile(TestSourceDir() + "/google/protobuf/" "testdata/text_format_unittest_data_oneof_implemented.txt"); EXPECT_TRUE(Run("google/protobuf/unittest.proto " @@ -2009,7 +2349,7 @@ TEST_F(EncodeDecodeTest, Encode) { ExpectStderrMatchesText(""); } -TEST_F(EncodeDecodeTest, Decode) { +TEST_P(EncodeDecodeTest, Decode) { RedirectStdinFromFile(TestSourceDir() + "/google/protobuf/testdata/golden_message_oneof_implemented"); EXPECT_TRUE(Run("google/protobuf/unittest.proto " @@ -2020,7 +2360,7 @@ TEST_F(EncodeDecodeTest, Decode) { ExpectStderrMatchesText(""); } -TEST_F(EncodeDecodeTest, Partial) { +TEST_P(EncodeDecodeTest, Partial) { RedirectStdinFromText(""); EXPECT_TRUE(Run("google/protobuf/unittest.proto " "--encode=protobuf_unittest.TestRequired")); @@ -2029,7 +2369,7 @@ TEST_F(EncodeDecodeTest, Partial) { "warning: Input message is missing required fields: a, b, c\n"); } -TEST_F(EncodeDecodeTest, DecodeRaw) { +TEST_P(EncodeDecodeTest, DecodeRaw) { protobuf_unittest::TestAllTypes message; message.set_optional_int32(123); message.set_optional_string("foo"); @@ -2043,21 +2383,24 @@ TEST_F(EncodeDecodeTest, DecodeRaw) { ExpectStderrMatchesText(""); } -TEST_F(EncodeDecodeTest, UnknownType) { +TEST_P(EncodeDecodeTest, UnknownType) { EXPECT_FALSE(Run("google/protobuf/unittest.proto " "--encode=NoSuchType")); ExpectStdoutMatchesText(""); ExpectStderrMatchesText("Type not defined: NoSuchType\n"); } -TEST_F(EncodeDecodeTest, ProtoParseError) { +TEST_P(EncodeDecodeTest, ProtoParseError) { EXPECT_FALSE(Run("google/protobuf/no_such_file.proto " "--encode=NoSuchType")); ExpectStdoutMatchesText(""); ExpectStderrMatchesText( - "google/protobuf/no_such_file.proto: File not found.\n"); + "google/protobuf/no_such_file.proto: No such file or directory\n"); } +INSTANTIATE_TEST_CASE_P(FileDescriptorSetSource, + EncodeDecodeTest, + testing::Values(PROTO_PATH, DESCRIPTOR_SET_IN)); } // anonymous namespace #endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index fce58c02..f99159f5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -125,12 +125,9 @@ 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; @@ -141,8 +138,6 @@ 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"); @@ -152,10 +147,6 @@ 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.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc index 6a8a83d1..3b4b97e6 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -81,10 +81,16 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { std::map<string, string> vars; vars["classname"] = classname_; vars["short_name"] = descriptor_->name(); - vars["enumbase"] = classname_ + (options_.proto_h ? " : int" : ""); - - printer->Print(vars, "enum $enumbase$ {\n"); - printer->Annotate("enumbase", descriptor_); + vars["enumbase"] = options_.proto_h ? " : int" : ""; + // These variables are placeholders to pick out the beginning and ends of + // identifiers for annotations (when doing so with existing variables would + // be ambiguous or impossible). They should never be set to anything but the + // empty string. + vars["{"] = ""; + vars["}"] = ""; + + printer->Print(vars, "enum $classname$$enumbase$ {\n"); + printer->Annotate("classname", descriptor_); printer->Indent(); const EnumValueDescriptor* min_value = descriptor_->value(0); @@ -102,7 +108,8 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { " PROTOBUF_DEPRECATED" : ""; if (i > 0) printer->Print(",\n"); - printer->Print(vars, "$prefix$$name$$deprecation$ = $number$"); + printer->Print(vars, "${$$prefix$$name$$}$$deprecation$ = $number$"); + printer->Annotate("{", "}", descriptor_->value(i)); if (descriptor_->value(i)->number() < min_value->number()) { min_value = descriptor_->value(i); @@ -134,14 +141,20 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { } printer->Print(vars, - "$dllexport$bool $classname$_IsValid(int value);\n" - "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n" - "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"); + "$dllexport$bool $classname$_IsValid(int value);\n" + "const $classname$ ${$$prefix$$short_name$_MIN$}$ = " + "$prefix$$min_name$;\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(vars, + "const $classname$ ${$$prefix$$short_name$_MAX$}$ = " + "$prefix$$max_name$;\n"); + printer->Annotate("{", "}", descriptor_); if (generate_array_size_) { printer->Print(vars, - "const int $prefix$$short_name$_ARRAYSIZE = " - "$prefix$$short_name$_MAX + 1;\n\n"); + "const int ${$$prefix$$short_name$_ARRAYSIZE$}$ = " + "$prefix$$short_name$_MAX + 1;\n\n"); + printer->Annotate("{", "}", descriptor_); } if (HasDescriptorMethods(descriptor_->file(), options_)) { diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 960730ca..08a635fa 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -74,9 +74,11 @@ GeneratePrivateMembers(io::Printer* printer) const { void EnumFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, "$deprecated_attr$$type$ $name$() const;\n"); + printer->Annotate("name", descriptor_); printer->Print(variables_, - "$deprecated_attr$$type$ $name$() const;\n" - "$deprecated_attr$void set_$name$($type$ value);\n"); + "$deprecated_attr$void ${$set_$name$$}$($type$ value);\n"); + printer->Annotate("{", "}", descriptor_); } void EnumFieldGenerator:: @@ -113,7 +115,7 @@ GenerateMergingCode(io::Printer* printer) const { void EnumFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); + printer->Print(variables_, "swap($name$_, other->$name$_);\n"); } void EnumFieldGenerator:: @@ -259,12 +261,23 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "$deprecated_attr$$type$ $name$(int index) const;\n" - "$deprecated_attr$void set_$name$(int index, $type$ value);\n" - "$deprecated_attr$void add_$name$($type$ value);\n"); + "$deprecated_attr$$type$ $name$(int index) const;\n"); + printer->Annotate("name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_$name$$}$(int index, $type$ value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$add_$name$$}$($type$ value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$const ::google::protobuf::RepeatedField<int>& $name$() const;\n"); + printer->Annotate("name", descriptor_); printer->Print(variables_, - "$deprecated_attr$const ::google::protobuf::RepeatedField<int>& $name$() const;\n" - "$deprecated_attr$::google::protobuf::RepeatedField<int>* mutable_$name$();\n"); + "$deprecated_attr$::google::protobuf::RepeatedField<int>* " + "${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedEnumFieldGenerator:: @@ -294,8 +307,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, printer->Print(variables, " $name$_.Add(value);\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" - "}\n"); - printer->Print(variables, + "}\n" "$inline$const ::google::protobuf::RepeatedField<int>&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc index e4fce461..6b1673b2 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc @@ -35,9 +35,10 @@ #include <google/protobuf/compiler/cpp/cpp_extension.h> #include <map> #include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> + namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index 4480a9d2..dce9617c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -95,6 +95,13 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, // By default, empty string, so that generic code used for both oneofs and // singular fields can be written. (*variables)["oneof_prefix"] = ""; + + // These variables are placeholders to pick out the beginning and ends of + // identifiers for annotations (when doing so with existing variables would + // be ambiguous or impossible). They should never be set to anything but the + // empty string. + (*variables)["{"] = ""; + (*variables)["}"] = ""; } void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor, @@ -194,7 +201,6 @@ const FieldGenerator& FieldGeneratorMap::get( return *field_generators_[field->index()]; } - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index 00dc25d4..d9dd3850 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -180,10 +180,6 @@ class FieldGenerator { virtual void GenerateDefaultInstanceAllocator(io::Printer* /*printer*/) const {} - // Generate code that should be run when ShutdownProtobufLibrary() is called, - // to delete all dynamically-allocated objects. - virtual void GenerateShutdownCode(io::Printer* /*printer*/) const {} - // Generate lines to decode this field, which will be placed inside the // message's MergeFromCodedStream() method. virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0; @@ -233,7 +229,6 @@ class FieldGeneratorMap { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); }; - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index feb8ba65..a066a6a7 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -126,12 +126,20 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) new EnumGenerator(file->enum_type(i), options)); enum_generators_.push_back(enum_generators_owner_[i].get()); } + for (int i = 0; i < enum_generators_.size(); i++) { + enum_generators_[i]->index_in_metadata_ = i; + } for (int i = 0; i < file->service_count(); i++) { service_generators_owner_[i].reset( new ServiceGenerator(file->service(i), options)); service_generators_.push_back(service_generators_owner_[i].get()); } + if (HasGenericServices(file_, options_)) { + for (int i = 0; i < service_generators_.size(); i++) { + service_generators_[i]->index_in_metadata_ = i; + } + } for (int i = 0; i < file->extension_count(); i++) { extension_generators_owner_[i].reset( @@ -343,9 +351,10 @@ void FileGenerator::GenerateSource(io::Printer* printer) { "::"; } printer->Print( - "class $classname$DefaultTypeInternal : " - "public ::google::protobuf::internal::ExplicitlyConstructed<$parent$$classname$> " - "{\n", + "class $classname$DefaultTypeInternal {\n" + "public:\n" + " ::google::protobuf::internal::ExplicitlyConstructed<$parent$$classname$>\n" + " _instance;\n", "parent", parent, "classname", message_generators_[i]->classname_); printer->Indent(); message_generators_[i]->GenerateExtraDefaultFields(printer); @@ -545,7 +554,8 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // table-driven parsing. printer->Print("PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField\n" - " const TableStruct::entries[] = {\n"); + " const TableStruct::entries[] " + "GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); printer->Indent(); std::vector<size_t> entries; @@ -566,7 +576,8 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { "};\n" "\n" "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField\n" - " const TableStruct::aux[] = {\n"); + " const TableStruct::aux[] " + "GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); printer->Indent(); std::vector<size_t> aux_entries; @@ -585,7 +596,8 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { printer->Print( "};\n" "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const\n" - " TableStruct::schema[] = {\n"); + " TableStruct::schema[] " + "GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); printer->Indent(); size_t offset = 0; @@ -597,7 +609,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { } if (message_generators_.empty()) { - printer->Print("{ NULL, NULL, 0, -1, -1, false },\n"); + printer->Print("{ NULL, NULL, 0, -1, -1, -1, -1, NULL, false },\n"); } printer->Outdent(); @@ -605,9 +617,47 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { "};\n" "\n"); + if (!message_generators_.empty() && options_.table_driven_serialization) { + printer->Print( + "const ::google::protobuf::internal::FieldMetadata TableStruct::field_metadata[] " + "= {\n"); + printer->Indent(); + std::vector<int> field_metadata_offsets; + int idx = 0; + for (int i = 0; i < message_generators_.size(); i++) { + field_metadata_offsets.push_back(idx); + idx += message_generators_[i]->GenerateFieldMetadata(printer); + } + field_metadata_offsets.push_back(idx); + printer->Outdent(); + printer->Print( + "};\n" + "const ::google::protobuf::internal::SerializationTable " + "TableStruct::serialization_table[] = {\n"); + printer->Indent(); + // We rely on the order we layout the tables to match the order we + // calculate them with FlattenMessagesInFile, so we check here that + // these match exactly. + std::vector<const Descriptor*> calculated_order = + FlattenMessagesInFile(file_); + GOOGLE_CHECK_EQ(calculated_order.size(), message_generators_.size()); + for (int i = 0; i < message_generators_.size(); i++) { + GOOGLE_CHECK_EQ(calculated_order[i], message_generators_[i]->descriptor_); + printer->Print( + "{$num_fields$, TableStruct::field_metadata + $index$},\n", + "classname", message_generators_[i]->classname_, "num_fields", + SimpleItoa(field_metadata_offsets[i + 1] - field_metadata_offsets[i]), + "index", SimpleItoa(field_metadata_offsets[i])); + } + printer->Outdent(); + printer->Print( + "};\n" + "\n"); + } if (HasDescriptorMethods(file_, options_)) { if (!message_generators_.empty()) { - printer->Print("const ::google::protobuf::uint32 TableStruct::offsets[] = {\n"); + printer->Print("const ::google::protobuf::uint32 TableStruct::offsets[] " + "GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); printer->Indent(); std::vector<std::pair<size_t, size_t> > pairs; for (int i = 0; i < message_generators_.size(); i++) { @@ -616,8 +666,8 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { printer->Outdent(); printer->Print( "};\n" - "\n" - "static const ::google::protobuf::internal::MigrationSchema schemas[] = {\n"); + "static const ::google::protobuf::internal::MigrationSchema schemas[] " + "GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); printer->Indent(); { int offset = 0; @@ -648,7 +698,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // we still need these symbols to exist printer->Print( // MSVC doesn't like empty arrays, so we add a dummy. - "const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u };\n" + "const ::google::protobuf::uint32 TableStruct::offsets[1] = {};\n" "static const ::google::protobuf::internal::MigrationSchema* schemas = NULL;\n" "static const ::google::protobuf::Message* const* " "file_default_instances = NULL;\n"); @@ -691,7 +741,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { printer->Print( "file_level_metadata[$index$].reflection = " "$parent$::$classname$::CreateReflection(file_level_metadata[$index$]" - ".descriptor, _$classname$_default_instance_.get_mutable());\n", + ".descriptor, _$classname$_default_instance_._instance.get_mutable());\n", "index", SimpleItoa(i), "parent", ClassName(message_generators_[i]->descriptor_->containing_type(), false), @@ -738,33 +788,6 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { "} // namespace\n"); } - // ----------------------------------------------------------------- - - // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown. - printer->Print( - "\n" - "void TableStruct::Shutdown() {\n"); - printer->Indent(); - - for (int i = 0; i < message_generators_.size(); i++) { - 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"); - - // ----------------------------------------------------------------- - // Now generate the InitDefaultsImpl() function. printer->Print( "void TableStruct::InitDefaultsImpl() {\n" @@ -826,7 +849,8 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { string file_data; file_proto.SerializeToString(&file_data); - printer->Print("static const char descriptor[] = {\n"); + printer->Print("static const char descriptor[] " + "GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); printer->Indent(); if (file_data.size() > 66535) { @@ -877,9 +901,6 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { file_namespace); } - printer->Print( - "::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown);\n"); - printer->Outdent(); printer->Print( "}\n" @@ -1022,11 +1043,11 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { "#include <google/protobuf/map.h>" " // IWYU pragma: export\n"); if (HasDescriptorMethods(file_, options_)) { - printer->Print( - "#include <google/protobuf/map_field_inl.h>\n"); + printer->Print("#include <google/protobuf/map_entry.h>\n"); + printer->Print("#include <google/protobuf/map_field_inl.h>\n"); } else { - printer->Print( - "#include <google/protobuf/map_field_lite.h>\n"); + printer->Print("#include <google/protobuf/map_entry_lite.h>\n"); + printer->Print("#include <google/protobuf/map_field_lite.h>\n"); } } @@ -1093,7 +1114,7 @@ void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) { void FileGenerator::GenerateGlobalStateFunctionDeclarations( io::Printer* printer) { - // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile + // Forward-declare the AddDescriptors, AssignDescriptors // functions, so that we can declare them to be friends of each class. printer->Print( "\n" @@ -1104,12 +1125,14 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations( " static const ::google::protobuf::internal::AuxillaryParseTableField aux[];\n" " static const ::google::protobuf::internal::ParseTable schema[];\n" " static const ::google::protobuf::uint32 offsets[];\n" + " static const ::google::protobuf::internal::FieldMetadata field_metadata[];\n" + " static const ::google::protobuf::internal::SerializationTable " + "serialization_table[];\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. // This is the internal implementation of InitDefaults. It should only // be called by InitDefaults which makes sure it will be called only once. " static void InitDefaultsImpl();\n" - " static void Shutdown();\n" "};\n" "void $dllexport_decl$AddDescriptors();\n" "void $dllexport_decl$InitDefaults();\n" @@ -1199,6 +1222,13 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) { // dependent. printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); + // TODO(gerbens) remove pragmas when gcc is no longer used. Current version + // of gcc fires a bogus error when compiled with strict-aliasing. + printer->Print( + "#ifdef __GNUC__\n" + " #pragma GCC diagnostic push\n" + " #pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n" + "#endif // __GNUC__\n"); // Generate class inline methods. for (int i = 0; i < message_generators_.size(); i++) { if (i > 0) { @@ -1208,6 +1238,10 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) { message_generators_[i]->GenerateInlineMethods(printer, /* is_inline = */ true); } + printer->Print( + "#ifdef __GNUC__\n" + " #pragma GCC diagnostic pop\n" + "#endif // __GNUC__\n"); printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); for (int i = 0; i < message_generators_.size(); i++) { @@ -1224,13 +1258,8 @@ void FileGenerator::GenerateProto2NamespaceEnumSpecializations( io::Printer* printer) { // Emit GetEnumDescriptor specializations into google::protobuf namespace: if (HasEnumDefinitions(file_)) { - // The SWIG conditional is to avoid a null-pointer dereference - // (bug 1984964) in swig-1.3.21 resulting from the following syntax: - // namespace X { void Y<Z::W>(); } - // which appears in GetEnumDescriptor() specializations. printer->Print( "\n" - "#ifndef SWIG\n" "namespace google {\nnamespace protobuf {\n" "\n"); for (int i = 0; i < enum_generators_.size(); i++) { @@ -1238,8 +1267,7 @@ void FileGenerator::GenerateProto2NamespaceEnumSpecializations( } printer->Print( "\n" - "} // namespace protobuf\n} // namespace google\n" - "#endif // SWIG\n"); + "} // namespace protobuf\n} // namespace google\n"); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index cee31224..68abd0ef 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -100,6 +100,8 @@ bool CppGenerator::Generate(const FileDescriptor* file, file_options.enforce_lite = true; } else if (options[i].first == "table_driven_parsing") { file_options.table_driven_parsing = true; + } else if (options[i].first == "table_driven_serialization") { + file_options.table_driven_serialization = 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 9cddba5c..00959796 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -37,14 +37,16 @@ #include <vector> #include <google/protobuf/stubs/hash.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/cpp/cpp_helpers.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> + + namespace google { namespace protobuf { namespace compiler { @@ -167,6 +169,11 @@ string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) { } } +string DefaultInstanceName(const Descriptor* descriptor) { + string prefix = descriptor->file()->package().empty() ? "" : "::"; + return prefix + DotsToColons(descriptor->file()->package()) + "::_" + + ClassName(descriptor, false) + "_default_instance_"; +} string DependentBaseClassTemplateName(const Descriptor* descriptor) { return ClassName(descriptor, false) + "_InternalBase"; @@ -654,6 +661,26 @@ void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field, "VerifyUtf8Cord", "VerifyUTF8CordNamedField", printer); } +namespace { + +void Flatten(const Descriptor* descriptor, + std::vector<const Descriptor*>* flatten) { + for (int i = 0; i < descriptor->nested_type_count(); i++) + Flatten(descriptor->nested_type(i), flatten); + flatten->push_back(descriptor); +} + +} // namespace + +std::vector<const Descriptor*> FlattenMessagesInFile( + const FileDescriptor* file) { + std::vector<const Descriptor*> result; + for (int i = 0; i < file->message_type_count(); i++) { + Flatten(file->message_type(i), &result); + } + return result; +} + bool HasWeakFields(const Descriptor* descriptor) { return false; } diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index a744a865..6ae68591 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -67,6 +67,9 @@ extern const char kThinSeparator[]; string ClassName(const Descriptor* descriptor, bool qualified); string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); +// Fully qualified name of the default_instance of this message. +string DefaultInstanceName(const Descriptor* descriptor); + // Name of the CRTP class template (for use with proto_h). // This is a class name, like "ProtoName_InternalBase". string DependentBaseClassTemplateName(const Descriptor* descriptor); @@ -159,8 +162,18 @@ string SafeFunctionName(const Descriptor* descriptor, const FieldDescriptor* field, const string& prefix); -// Returns true if unknown fields are preseved after parsing. -inline bool PreserveUnknownFields(const Descriptor* message) { +// Returns true if unknown fields are always preserved after parsing. +inline bool AlwaysPreserveUnknownFields(const FileDescriptor* file) { + return file->syntax() != FileDescriptor::SYNTAX_PROTO3; +} + +// Returns true if unknown fields are preserved after parsing. +inline bool AlwaysPreserveUnknownFields(const Descriptor* message) { + return AlwaysPreserveUnknownFields(message->file()); +} + +// Returns true if generated messages have public unknown fields accessors +inline bool PublicUnknownFieldsAccessors(const Descriptor* message) { return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3; } @@ -168,10 +181,8 @@ inline bool PreserveUnknownFields(const Descriptor* message) { ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor( const FileDescriptor* file, const Options& options); -// If PreserveUnknownFields() is true, determines whether unknown -// fields will be stored in an UnknownFieldSet or a string. -// If PreserveUnknownFields() is false, this method will not be -// used. +// Determines whether unknown fields will be stored in an UnknownFieldSet or +// a string. inline bool UseUnknownFieldSet(const FileDescriptor* file, const Options& options) { return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME; @@ -277,6 +288,10 @@ inline ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor( : file->options().optimize_for(); } +// This orders the messages in a .pb.cc as it's outputted by file.cc +std::vector<const Descriptor*> FlattenMessagesInFile( + const FileDescriptor* file); + bool HasWeakFields(const Descriptor* desc); bool HasWeakFields(const FileDescriptor* desc); diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc index d76db169..da33d29b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -150,6 +150,7 @@ GeneratePrivateMembers(io::Printer* printer) const { " $map_classname$;\n"); } printer->Print(variables_, + "private:\n" "::google::protobuf::internal::MapField$lite$<\n" " $map_classname$,\n" " $key_cpp$, $val_cpp$,\n" @@ -161,11 +162,15 @@ GeneratePrivateMembers(io::Printer* printer) const { void MapFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, + printer->Print( + variables_, "$deprecated_attr$const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" - " $name$() const;\n" - "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" - " mutable_$name$();\n"); + " $name$() const;\n"); + printer->Annotate("name", descriptor_); + printer->Print(variables_, + "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" + " ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); } void MapFieldGenerator:: diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 33231ae3..63ebb3c5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -52,6 +52,8 @@ #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/map_entry_lite.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> @@ -280,7 +282,7 @@ void OptimizePadding(std::vector<const FieldDescriptor*>* fields, enum Family { REPEATED = 0, STRING = 1, - MESSAGE = 2, + MESSAGE = 3, ZERO_INITIALIZABLE = 4, OTHER = 5, kMaxFamily @@ -452,22 +454,13 @@ bool HasPrivateHasMethod(const FieldDescriptor* field) { } -bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) { +bool TableDrivenParsingEnabled( + 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())) { @@ -482,16 +475,6 @@ bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) { 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; @@ -503,8 +486,10 @@ bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) { return false; } - // - Field numbers are relatively dense within the actual number of fields - if (max_field_number * table_sparseness >= descriptor->field_count()) { + // - Field numbers are relatively dense within the actual number of fields. + // We check for strictly greater than in the case where there are no fields + // (only extensions) so max_field_number == descriptor->field_count() == 0. + if (max_field_number * table_sparseness > descriptor->field_count()) { return false; } @@ -516,6 +501,31 @@ bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) { return true; } +void SetUnknkownFieldsVariable(const Descriptor* descriptor, + const Options& options, + std::map<string, string>* variables) { + if (UseUnknownFieldSet(descriptor->file(), options)) { + (*variables)["unknown_fields_type"] = "::google::protobuf::UnknownFieldSet"; + } else { + (*variables)["unknown_fields_type"] = "::std::string"; + } + if (AlwaysPreserveUnknownFields(descriptor)) { + (*variables)["have_unknown_fields"] = + "_internal_metadata_.have_unknown_fields()"; + (*variables)["unknown_fields"] = "_internal_metadata_.unknown_fields()"; + } else { + (*variables)["have_unknown_fields"] = + "(_internal_metadata_.have_unknown_fields() && " + " ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())"; + (*variables)["unknown_fields"] = + "(::google::protobuf::internal::GetProto3PreserveUnknownsDefault()" + " ? _internal_metadata_.unknown_fields()" + " : _internal_metadata_.default_instance())"; + } + (*variables)["mutable_unknown_fields"] = + "_internal_metadata_.mutable_unknown_fields()"; +} + } // anonymous namespace // =================================================================== @@ -592,7 +602,7 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, use_dependent_base_ = true; } - table_driven_ = TableDrivenEnabled(descriptor_, options_); + table_driven_ = TableDrivenParsingEnabled(descriptor_, options_); } MessageGenerator::~MessageGenerator() {} @@ -703,24 +713,29 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { } if (field->is_repeated()) { - printer->Print(vars, "$deprecated_attr$int $name$_size() const;\n"); + printer->Print(vars, "$deprecated_attr$int ${$$name$_size$}$() const;\n"); + printer->Annotate("{", "}", field); } else if (HasHasMethod(field)) { - printer->Print(vars, "$deprecated_attr$bool has_$name$() const;\n"); + printer->Print(vars, "$deprecated_attr$bool ${$has_$name$$}$() const;\n"); + printer->Annotate("{", "}", field); } else if (HasPrivateHasMethod(field)) { printer->Print(vars, - "private:\n" - "bool has_$name$() const;\n" - "public:\n"); + "private:\n" + "bool ${$has_$name$$}$() const;\n" + "public:\n"); + printer->Annotate("{", "}", field); } if (!dependent_field) { // If this field is dependent, then its clear_() method is in the // depenent base class. (See also GenerateDependentAccessorDeclarations.) - printer->Print(vars, "$deprecated_attr$void clear_$name$();\n"); + printer->Print(vars, "$deprecated_attr$void ${$clear_$name$$}$();\n"); + printer->Annotate("{", "}", field); } printer->Print(vars, "$deprecated_attr$static const int $constant_name$ = " "$number$;\n"); + printer->Annotate("constant_name", field); // Generate type-specific accessor declarations. field_generators_.get(field).GenerateAccessorDeclarations(printer); @@ -1074,32 +1089,39 @@ GenerateClassDefinition(io::Printer* printer) { printer->Print(" public:\n"); printer->Indent(); - printer->Print(vars, - "$classname$();\n" - "virtual ~$classname$();\n" - "\n" - "$classname$(const $classname$& from);\n" - "\n" - "inline $classname$& operator=(const $classname$& from) {\n" - " CopyFrom(from);\n" - " return *this;\n" - "}\n" - "\n"); + printer->Print( + vars, + "$classname$();\n" + "virtual ~$classname$();\n" + "\n" + "$classname$(const $classname$& from);\n" + "\n" + "inline $classname$& operator=(const $classname$& from) {\n" + " CopyFrom(from);\n" + " return *this;\n" + "}\n"); + + if (options_.table_driven_serialization) { + printer->Print( + "private:\n" + "const void* InternalGetTable() const;\n" + "public:\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$($classname$&& from) noexcept\n" " : $classname$() {\n" " *this = ::std::move(from);\n" "}\n" "\n" - "inline $classname$& operator=($classname$&& from) {\n" + "inline $classname$& operator=($classname$&& from) noexcept {\n" " if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {\n" - " InternalSwap(&from);\n" + " if (this != &from) InternalSwap(&from);\n" " } else {\n" " CopyFrom(from);\n" " }\n" @@ -1107,22 +1129,17 @@ GenerateClassDefinition(io::Printer* printer) { "}\n" "#endif\n"); } - #endif - if (PreserveUnknownFields(descriptor_)) { - string type = UseUnknownFieldSet(descriptor_->file(), options_) - ? "::google::protobuf::UnknownFieldSet" - : "::std::string"; - printer->Print( - "inline const $type$& unknown_fields() const {\n" - " return _internal_metadata_.unknown_fields();\n" - "}\n" - "\n" - "inline $type$* mutable_unknown_fields() {\n" - " return _internal_metadata_.mutable_unknown_fields();\n" - "}\n" - "\n", - "type", type ); + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + if (PublicUnknownFieldsAccessors(descriptor_)) { + printer->Print(vars, + "inline const $unknown_fields_type$& unknown_fields() const {\n" + " return $unknown_fields$;\n" + "}\n" + "inline $unknown_fields_type$* mutable_unknown_fields() {\n" + " return $mutable_unknown_fields$;\n" + "}\n" + "\n"); } // N.B.: We exclude GetArena() when arena support is disabled, falling back on @@ -1190,7 +1207,6 @@ GenerateClassDefinition(io::Printer* printer) { " $message_index$;\n" "\n"); - if (SupportsArenas(descriptor_)) { printer->Print(vars, "void UnsafeArenaSwap($classname$* other);\n"); @@ -1214,6 +1230,9 @@ GenerateClassDefinition(io::Printer* printer) { printer->Print(vars, "void Swap($classname$* other);\n" + "friend void swap($classname$& a, $classname$& b) {\n" + " a.Swap(&b);\n" + "}\n" "\n" "// implements Message ----------------------------------------------\n" "\n" @@ -1250,9 +1269,14 @@ GenerateClassDefinition(io::Printer* printer) { "\n" "size_t ByteSizeLong() const PROTOBUF_FINAL;\n" "bool MergePartialFromCodedStream(\n" - " ::google::protobuf::io::CodedInputStream* input)$merge_partial_final$;\n" - "void SerializeWithCachedSizes(\n" - " ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;\n"); + " ::google::protobuf::io::CodedInputStream* input)$merge_partial_final$;\n"); + if (!options_.table_driven_serialization || + descriptor_->options().message_set_wire_format()) { + printer->Print( + "void SerializeWithCachedSizes(\n" + " ::google::protobuf::io::CodedOutputStream* output) const " + "PROTOBUF_FINAL;\n"); + } // DiscardUnknownFields() is implemented in message.cc using reflections. We // need to implement this function in generated code for messages. if (!UseUnknownFieldSet(descriptor_->file(), options_)) { @@ -1278,6 +1302,9 @@ GenerateClassDefinition(io::Printer* printer) { "final", use_final); if (SupportsArenas(descriptor_)) { printer->Print( + // TODO(gerbens) Make this private! Currently people are deriving from + // protos to give access to this constructor, breaking the invariants + // we rely on. "protected:\n" "explicit $classname$(::google::protobuf::Arena* arena);\n" "private:\n" @@ -1443,7 +1470,7 @@ GenerateClassDefinition(io::Printer* printer) { if (SupportsArenas(descriptor_)) { printer->Print( - "friend class ::google::protobuf::Arena;\n" + "template <typename T> friend class ::google::protobuf::Arena::InternalHelper;\n" "typedef void InternalArenaConstructable_;\n" "typedef void DestructorSkippable_;\n"); } @@ -1577,7 +1604,6 @@ GenerateExtraDefaultFields(io::Printer* printer) { // 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++) { const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); @@ -1602,7 +1628,7 @@ GenerateExtraDefaultFields(io::Printer* printer) { 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"); + printer->Print("{ NULL, NULL, 0, -1, -1, -1, -1, NULL, false },\n"); return false; } @@ -1639,9 +1665,44 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, " $classname$, _has_bits_),\n"); } + if (descriptor_->oneof_decl_count() > 0) { + printer->Print(vars, + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" + " $classname$, _oneof_case_),\n"); + } else { + printer->Print("-1, // no _oneof_case_\n"); + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print(vars, + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " + "_extensions_),\n"); + } else { + printer->Print("-1, // no _extensions_\n"); + } + + // TODO(ckennelly): Consolidate this with the calculation for + // AuxillaryParseTableField. + std::vector<string> package_parts; + + const Descriptor* outer = descriptor_; + 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["ns"] = Join(package_parts, "::"); + printer->Print(vars, "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" - " $classname$, _internal_metadata_),\n"); + " $classname$, _internal_metadata_),\n" + "&::$ns$_$classname$_default_instance_,\n"); if (UseUnknownFieldSet(descriptor_->file(), options_)) { printer->Print(vars, "true,\n"); @@ -1670,6 +1731,239 @@ void MessageGenerator::GenerateSchema(io::Printer* printer, int offset, "{ $offset$, $has_bits_offsets$, sizeof($classname$)},\n"); } +namespace { + +// TODO(gerbens) remove this after the next sync with GitHub code base. +// Then the opensource testing has gained the functionality to compile +// the CalcFieldNum given the symbols defined in generated-message-util. +#ifdef OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP +// We need a clean version of CalcFieldNum that doesn't use new functionality +// in the runtime, because this functionality is not yet in the opensource +// runtime + +uint32 CalculateType(uint32 type, uint32 type_class) { + return (type - 1) + type_class * 20; +} + +uint32 CalcFieldNum(const FieldDescriptor* field, const Options& options) { + bool is_a_map = IsMapEntryMessage(field->containing_type()); + int type = field->type(); + if (field->containing_oneof()) { + return CalculateType(type, 4); + } + if (field->is_packed()) { + return CalculateType(type, 3); + } else if (field->is_repeated()) { + return CalculateType(type, 2); + } else if (!HasFieldPresence(field->file()) && + field->containing_oneof() == NULL && !is_a_map) { + return CalculateType(type, 1); + } else { + return CalculateType(type, 0); + } +} + +#else +// We need to calculate for each field what function the table driven code +// should use to serialize it. This returns the index in a lookup table. +uint32 CalcFieldNum(const FieldDescriptor* field, const Options& options) { + bool is_a_map = IsMapEntryMessage(field->containing_type()); + int type = field->type(); + if (field->containing_oneof()) { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kOneOf); + } + if (field->is_packed()) { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kPacked); + } else if (field->is_repeated()) { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kRepeated); + } else if (!HasFieldPresence(field->file()) && + field->containing_oneof() == NULL && !is_a_map) { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kNoPresence); + } else { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kPresence); + } +} +#endif + +int FindMessageIndexInFile(const Descriptor* descriptor) { + std::vector<const Descriptor*> flatten = + FlattenMessagesInFile(descriptor->file()); + return std::find(flatten.begin(), flatten.end(), descriptor) - + flatten.begin(); +} + +} // namespace + +int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { + if (!options_.table_driven_serialization) { + return 0; + } + + std::vector<const FieldDescriptor*> sorted = SortFieldsByNumber(descriptor_); + if (IsMapEntryMessage(descriptor_)) { + for (int i = 0; i < 2; i++) { + const FieldDescriptor* field = sorted[i]; + uint32 tag = internal::WireFormatLite::MakeTag( + field->number(), WireFormat::WireTypeForFieldType(field->type())); + + std::map<string, string> vars; + vars["classname"] = classname_; + vars["parent_classname"] = + ClassName(descriptor_->containing_type(), false); + vars["field_name"] = FieldName(field); + vars["tag"] = SimpleItoa(tag); + vars["hasbit"] = SimpleItoa(i); + vars["type"] = SimpleItoa(CalcFieldNum(field, options_)); + vars["ptr"] = "NULL"; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + GOOGLE_CHECK(!IsMapEntryMessage(field->message_type())); + { + vars["ptr"] = + QualifiedFileLevelSymbol( + field->message_type()->file()->package(), + FileLevelNamespace(field->message_type()->file()->name())) + + "::TableStruct::serialization_table + " + + SimpleItoa(FindMessageIndexInFile(field->message_type())); + } + } + vars["extra"] = HasDescriptorMethods(descriptor_->file(), options_) + ? "::SuperType" + : ""; + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" + "::google::protobuf::internal::MapEntryHelper<$parent_classname$::$" + "classname$$extra$>, $field_name$_), $tag$," + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" + "::google::protobuf::internal::MapEntryHelper<$parent_classname$::$" + "classname$$extra$>, _has_bits_) * 8 + $hasbit$, $type$, " + "$ptr$},\n"); + } + return 2; + } + printer->Print( + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " + "_cached_size_), 0, 0, 0, NULL},\n", + "classname", classname_); + std::vector<const Descriptor::ExtensionRange*> sorted_extensions; + for (int i = 0; i < descriptor_->extension_range_count(); ++i) { + sorted_extensions.push_back(descriptor_->extension_range(i)); + } + std::sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeSorter()); + for (int i = 0, extension_idx = 0; /* no range */; i++) { + for (; extension_idx < sorted_extensions.size() && + (i == sorted.size() || + sorted_extensions[extension_idx]->start < sorted[i]->number()); + extension_idx++) { + const Descriptor::ExtensionRange* range = + sorted_extensions[extension_idx]; + printer->Print( + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " + "_extensions_), $start$, $end$, " + "::google::protobuf::internal::FieldMetadata::kSpecial, " + "reinterpret_cast<const " + "void*>(::google::protobuf::internal::ExtensionSerializer)},\n", + "classname", classname_, "start", SimpleItoa(range->start), "end", + SimpleItoa(range->end)); + } + if (i == sorted.size()) break; + const FieldDescriptor* field = sorted[i]; + + uint32 tag = internal::WireFormatLite::MakeTag( + field->number(), WireFormat::WireTypeForFieldType(field->type())); + if (field->is_packed()) { + tag = internal::WireFormatLite::MakeTag( + field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + } + + string classfieldname = FieldName(field); + if (field->containing_oneof()) { + classfieldname = field->containing_oneof()->name(); + } + std::map<string, string> vars; + vars["classname"] = classname_; + vars["field_name"] = classfieldname; + vars["tag"] = SimpleItoa(tag); + vars["ptr"] = "NULL"; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (IsMapEntryMessage(field->message_type())) { + vars["idx"] = SimpleItoa(FindMessageIndexInFile(field->message_type())); + vars["fieldclassname"] = ClassName(field->message_type(), false); + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, $field_name$_), $tag$, $idx$, " + "::google::protobuf::internal::FieldMetadata::kSpecial, " + "reinterpret_cast<const void*>(static_cast< " + "::google::protobuf::internal::SpecialSerializer>(" + "::google::protobuf::internal::MapFieldSerializer< " + "::google::protobuf::internal::MapEntryToMapField<$classname$::$" + "fieldclassname$>::MapFieldType, " + "TableStruct::serialization_table>))},\n"); + continue; + } else { + vars["ptr"] = + QualifiedFileLevelSymbol( + field->message_type()->file()->package(), + FileLevelNamespace(field->message_type()->file()->name())) + + "::TableStruct::serialization_table + " + + SimpleItoa(FindMessageIndexInFile(field->message_type())); + } + } + vars["type"] = SimpleItoa(CalcFieldNum(field, options_)); + + + if (field->options().weak()) { + // TODO(gerbens) merge weak fields into ranges + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, _weak_field_map_), $tag$, $tag$, " + "::google::protobuf::internal::FieldMetadata::kSpecial, " + "reinterpret_cast<const " + "void*>(::google::protobuf::internal::WeakFieldSerializer)},\n"); + } else if (field->containing_oneof()) { + vars["oneofoffset"] = + SimpleItoa(sizeof(uint32) * field->containing_oneof()->index()); + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, $field_name$_), $tag$, " + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, _oneof_case_) + $oneofoffset$, " + "$type$, $ptr$},\n"); + } else if (HasFieldPresence(descriptor_->file()) && + has_bit_indices_[field->index()] != -1) { + vars["hasbitsoffset"] = SimpleItoa(has_bit_indices_[field->index()]); + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, $field_name$_), $tag$, " + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, _has_bits_) * 8 + $hasbitsoffset$, $type$, " + "$ptr$},\n"); + } else { + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, $field_name$_), $tag$, ~0u, $type$, " + "$ptr$},\n"); + } + } + int num_field_metadata = 1 + sorted.size() + sorted_extensions.size(); + num_field_metadata++; + string serializer = UseUnknownFieldSet(descriptor_->file(), options_) + ? "::google::protobuf::internal::UnknownFieldSetSerializer" + : "::google::protobuf::internal::UnknownFieldSerializerLite"; + printer->Print( + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " + "_internal_metadata_), 0, ~0u, " + "::google::protobuf::internal::FieldMetadata::kSpecial, reinterpret_cast<const " + "void*>($serializer$)},\n", + "classname", classname_, "serializer", serializer); + return num_field_metadata; +} + void MessageGenerator:: GenerateDefaultInstanceAllocator(io::Printer* printer) { // Construct the default instances of all fields, as they will be used @@ -1682,7 +1976,9 @@ GenerateDefaultInstanceAllocator(io::Printer* printer) { // Construct the default instance. We can't call InitAsDefaultInstance() yet // because we need to make sure all default instances that this one might // depend on are constructed first. - printer->Print("_$classname$_default_instance_.DefaultConstruct();\n", + printer->Print("_$classname$_default_instance_._instance.DefaultConstruct();\n" + "::google::protobuf::internal::OnShutdownDestroyMessage(\n" + " &_$classname$_default_instance_);", "classname", classname_); } @@ -1690,9 +1986,9 @@ void MessageGenerator:: GenerateDefaultInstanceInitializer(io::Printer* printer) { 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();" + "_$classname$_default_instance_._instance.get_mutable()->set_default_instance(_$" + "classname$_default_instance_._instance.get_mutable());\n" + "_$classname$_default_instance_._instance.get_mutable()->InitAsDefaultInstance();" "\n", "classname", classname_); return; @@ -1715,7 +2011,8 @@ GenerateDefaultInstanceInitializer(io::Printer* printer) { if (field->containing_oneof() || field->options().weak()) { name = "_" + classname_ + "_default_instance_."; } else { - name = "_" + classname_ + "_default_instance_.get_mutable()->"; + name = + "_" + classname_ + "_default_instance_._instance.get_mutable()->"; } name += FieldName(field); printer->Print( @@ -1732,25 +2029,6 @@ GenerateDefaultInstanceInitializer(io::Printer* printer) { } void MessageGenerator:: -GenerateShutdownCode(io::Printer* printer) { - if (IsMapEntryMessage(descriptor_)) return; - - printer->Print("_$classname$_default_instance_.Shutdown();\n", "classname", - classname_); - - if (HasDescriptorMethods(descriptor_->file(), options_)) { - printer->Print("delete file_level_metadata[$index$].reflection;\n", "index", - SimpleItoa(index_in_file_messages_)); - } - - // Handle default instances of fields. - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GenerateShutdownCode(printer); - } -} - -void MessageGenerator:: GenerateClassMethods(io::Printer* printer) { if (IsMapEntryMessage(descriptor_)) { if (HasDescriptorMethods(descriptor_->file(), options_)) { @@ -1854,6 +2132,15 @@ GenerateClassMethods(io::Printer* printer) { GenerateSwap(printer); printer->Print("\n"); + if (options_.table_driven_serialization) { + printer->Print( + "const void* $classname$::InternalGetTable() const {\n" + " return $file_namespace$::TableStruct::serialization_table + $index$;\n" + "}\n" + "\n", + "classname", classname_, "index", SimpleItoa(index_in_file_messages_), + "file_namespace", FileLevelNamespace(descriptor_->file()->name())); + } if (HasDescriptorMethods(descriptor_->file(), options_)) { printer->Print( "::google::protobuf::Metadata $classname$::GetMetadata() const {\n" @@ -1926,13 +2213,25 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { processing_type |= static_cast<unsigned>( field->is_repeated() ? internal::kRepeatedMask : 0); + processing_type |= static_cast<unsigned>( + field->containing_oneof() ? internal::kOneofMask : 0); + + if (field->is_map()) { + processing_type = internal::TYPE_MAP; + } + const unsigned char tag_size = WireFormat::TagSize(field->number(), field->type()); std::map<string, string> vars; vars["classname"] = classname_; - vars["name"] = FieldName(field); - vars["has"] = SimpleItoa(has_bit_indices_[field->index()]); + if (field->containing_oneof() != NULL) { + vars["name"] = field->containing_oneof()->name(); + vars["presence"] = SimpleItoa(field->containing_oneof()->index()); + } else { + vars["name"] = FieldName(field); + vars["presence"] = SimpleItoa(has_bit_indices_[field->index()]); + } vars["nwtype"] = SimpleItoa(normal_wiretype); vars["pwtype"] = SimpleItoa(packed_wiretype); vars["ptype"] = SimpleItoa(processing_type); @@ -1942,7 +2241,7 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { "{\n" " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" " $classname$, $name$_),\n" - " static_cast< ::google::protobuf::uint32>($has$),\n" + " static_cast< ::google::protobuf::uint32>($presence$),\n" " $nwtype$, $pwtype$, $ptype$, $tag_size$\n" "},\n"); } @@ -1977,7 +2276,7 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { printer->Print( vars, "{::google::protobuf::internal::AuxillaryParseTableField::enum_aux{" - "$type$_IsValid, \"$type$\" }},\n"); + "$type$_IsValid}},\n"); last_field_number++; break; case FieldDescriptor::CPPTYPE_MESSAGE: { @@ -1995,7 +2294,17 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { GOOGLE_DCHECK_NE(package_parts.size(), 0); package_parts.back().clear(); - vars["classname"] = ClassName(field->message_type(), false); + if (field->is_map()) { + vars["classname"] = ClassName(field->containing_type(), false) + + "::" + ClassName(field->message_type(), false); + printer->Print(vars, + "{::google::protobuf::internal::AuxillaryParseTableField::map_" + "aux{&::google::protobuf::internal::ParseMap<$classname$>}},\n"); + last_field_number++; + break; + } else { + vars["classname"] = ClassName(field->message_type(), false); + } vars["ns"] = Join(package_parts, "::"); vars["type"] = FieldMessageTypeName(field); vars["file_namespace"] = FileLevelNamespace(outer->file()->name()); @@ -2005,7 +2314,7 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { " &::$ns$_$classname$_default_instance_,\n"); bool dont_emit_table = - !TableDrivenEnabled(field->message_type(), options_); + !TableDrivenParsingEnabled(field->message_type(), options_); if (dont_emit_table) { printer->Print(" NULL,\n"); @@ -2034,16 +2343,10 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { 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" + " \"$full_name$\"\n" "}},\n"); last_field_number++; break; @@ -2103,8 +2406,7 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( const FieldDescriptor* field = descriptor_->field(i); if (field->containing_oneof() || field->options().weak()) { printer->Print( - "GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(" - "(&_$classname$_default_instance_), $name$_),\n", + "offsetof($classname$DefaultTypeInternal, $name$_),\n", "classname", classname_, "name", FieldName(field)); } else { printer->Print( @@ -2178,6 +2480,7 @@ GenerateSharedDestructorCode(io::Printer* printer) { // Do nothing when the message is allocated in an arena. printer->Print( "::google::protobuf::Arena* arena = GetArenaNoVirtual();\n" + "GOOGLE_DCHECK(arena == NULL);\n" "if (arena != NULL) {\n" " return;\n" "}\n" @@ -2385,8 +2688,7 @@ GenerateStructors(io::Printer* printer) { initializer_with_arena += ", _weak_field_map_(arena)"; } - string initializer_null; - initializer_null = ", _internal_metadata_(NULL)"; + string initializer_null = superclass + "(), _internal_metadata_(NULL)"; if (IsAnyMessage(descriptor_)) { initializer_null += ", _any_metadata_(&type_url_, &value_)"; } @@ -2396,16 +2698,16 @@ GenerateStructors(io::Printer* printer) { printer->Print( "$classname$::$classname$()\n" - " : $superclass$()$initializer$ {\n" + " : $initializer$ {\n" " if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {\n" " $file_namespace$::InitDefaults();\n" " }\n" " SharedCtor();\n" " // @@protoc_insertion_point(constructor:$full_name$)\n" "}\n", - "classname", classname_, "superclass", superclass, "full_name", - descriptor_->full_name(), "initializer", initializer_null, - "file_namespace", FileLevelNamespace(descriptor_->file()->name())); + "classname", classname_, "full_name", descriptor_->full_name(), + "initializer", initializer_null, "file_namespace", + FileLevelNamespace(descriptor_->file()->name())); if (SupportsArenas(descriptor_)) { printer->Print( @@ -2598,7 +2900,6 @@ GenerateStructors(io::Printer* printer) { "}\n", "classname", classname_); } - } // Return the number of bits set in n, a non-negative integer. @@ -2611,6 +2912,22 @@ static int popcnt(uint32 n) { return result; } +bool MessageGenerator::MaybeGenerateOptionalFieldCondition( + io::Printer* printer, const FieldDescriptor* field, + int expected_has_bits_index) { + int has_bit_index = has_bit_indices_[field->index()]; + if (!field->options().weak() && + expected_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); + return true; + } + return false; +} + void MessageGenerator:: GenerateClear(io::Printer* printer) { printer->Print( @@ -2619,6 +2936,15 @@ GenerateClear(io::Printer* printer) { "classname", classname_, "full_name", descriptor_->full_name()); printer->Indent(); + printer->Print( + // TODO(jwb): It would be better to avoid emitting this if it is not used, + // rather than emitting a workaround for the resulting warning. + "::google::protobuf::uint32 cached_has_bits = 0;\n" + "// Prevent compiler warnings about cached_has_bits being unused\n" + "(void) cached_has_bits;\n\n"); + + int cached_has_bit_index = -1; + // Step 1: Extensions if (descriptor_->extension_range_count() > 0) { printer->Print("_extensions_.Clear();\n"); @@ -2727,9 +3053,14 @@ GenerateClear(io::Printer* printer) { GOOGLE_DCHECK_LE(2, count); GOOGLE_DCHECK_GE(8, count); + if (cached_has_bit_index != last_chunk / 4) { + cached_has_bit_index = last_chunk / 4; + printer->Print( + "cached_has_bits = _has_bits_[$idx$];\n", + "idx", SimpleItoa(cached_has_bit_index)); + } printer->Print( - "if (_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(); } @@ -2776,7 +3107,12 @@ GenerateClear(io::Printer* printer) { if (should_check_bit && // If no field presence, then always clear strings/messages as well. HasFieldPresence(descriptor_->file())) { - printer->Print("if (has_$name$()) {\n", "name", fieldname); + if (!MaybeGenerateOptionalFieldCondition(printer, field, + cached_has_bit_index)) { + printer->Print( + "if (has_$name$()) {\n", + "name", fieldname); + } printer->Indent(); have_enclosing_if = true; } @@ -2812,9 +3148,7 @@ GenerateClear(io::Printer* printer) { printer->Print("_has_bits_.Clear();\n"); } - if (PreserveUnknownFields(descriptor_)) { - printer->Print("_internal_metadata_.Clear();\n"); - } + printer->Print("_internal_metadata_.Clear();\n"); printer->Outdent(); printer->Print("}\n"); @@ -2918,6 +3252,7 @@ GenerateSwap(io::Printer* printer) { printer->Print("void $classname$::InternalSwap($classname$* other) {\n", "classname", classname_); printer->Indent(); + printer->Print("using std::swap;\n"); if (HasGeneratedMethods(descriptor_->file(), options_)) { for (int i = 0; i < optimized_order_.size(); i++) { @@ -2929,24 +3264,22 @@ GenerateSwap(io::Printer* printer) { for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { printer->Print( - "std::swap($oneof_name$_, other->$oneof_name$_);\n" - "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n", + "swap($oneof_name$_, other->$oneof_name$_);\n" + "swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n", "oneof_name", descriptor_->oneof_decl(i)->name(), "i", SimpleItoa(i)); } if (HasFieldPresence(descriptor_->file())) { for (int i = 0; i < HasBitsSize() / 4; ++i) { - printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n", + printer->Print("swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n", "i", SimpleItoa(i)); } } - if (PreserveUnknownFields(descriptor_)) { - printer->Print("_internal_metadata_.Swap(&other->_internal_metadata_);\n"); - } + printer->Print("_internal_metadata_.Swap(&other->_internal_metadata_);\n"); - printer->Print("std::swap(_cached_size_, other->_cached_size_);\n"); + printer->Print("swap(_cached_size_, other->_cached_size_);\n"); if (descriptor_->extension_range_count() > 0) { printer->Print("_extensions_.Swap(&other->_extensions_);\n"); } @@ -3249,21 +3582,16 @@ GenerateCopyFrom(io::Printer* printer) { void MessageGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) { + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); if (descriptor_->options().message_set_wire_format()) { // Special-case MessageSet. - printer->Print( + vars["classname"] = classname_; + printer->Print(vars, "bool $classname$::MergePartialFromCodedStream(\n" - " ::google::protobuf::io::CodedInputStream* input) {\n", - "classname", classname_); - - printer->Print( - " return _extensions_.ParseMessageSet(input, " - "internal_default_instance(),\n" - " mutable_unknown_fields());\n", - // Vars. - "classname", classname_); - - printer->Print( + " ::google::protobuf::io::CodedInputStream* input) {\n" + " return _extensions_.ParseMessageSet(input,\n" + " internal_default_instance(), $mutable_unknown_fields$);\n" "}\n"); return; } @@ -3279,14 +3607,18 @@ GenerateMergeFromCodedStream(io::Printer* printer) { if (table_driven_) { printer->Indent(); + const string lite = UseUnknownFieldSet(descriptor_->file(), options_) ? + "" : "Lite"; + printer->Print( - "return ::google::protobuf::internal::MergePartialFromCodedStream(\n" + "return ::google::protobuf::internal::MergePartialFromCodedStream$lite$(\n" " this,\n" " $file_namespace$::TableStruct::schema[\n" " $classname$::kIndexInFileMessages],\n" " input);\n", "classname", classname_, - "file_namespace", FileLevelNamespace(descriptor_->file()->name())); + "file_namespace", FileLevelNamespace(descriptor_->file()->name()), + "lite", lite); printer->Outdent(); @@ -3298,8 +3630,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) { "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n" " ::google::protobuf::uint32 tag;\n"); - if (PreserveUnknownFields(descriptor_) && - !UseUnknownFieldSet(descriptor_->file(), options_)) { + if (!UseUnknownFieldSet(descriptor_->file(), options_)) { // Use LazyStringOutputString to avoid initializing unknown fields string // unless it is actually needed. For the same reason, disable eager refresh // on the CodedOutputStream. @@ -3352,13 +3683,12 @@ GenerateMergeFromCodedStream(io::Printer* printer) { } printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = " - "input->ReadTagWithCutoff$lasttag$($max$u);\n" + "input->ReadTagWithCutoffNoLastTag($max$u);\n" "tag = p.first;\n" "if (!p.second) goto handle_unusual;\n", "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 : (maxtag <= kCutoff1 ? kCutoff1 : - maxtag)), - "lasttag", !capture_last_tag ? "NoLastTag" : ""); + maxtag))); if (descriptor_->field_count() > 0) { // We don't even want to print the switch() if we have no fields because @@ -3393,9 +3723,11 @@ GenerateMergeFromCodedStream(io::Printer* printer) { const FieldGenerator& field_generator = field_generators_.get(field); // 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))); + printer->Print( + "if (static_cast< ::google::protobuf::uint8>(tag) ==\n" + " static_cast< ::google::protobuf::uint8>($truncated$u /* $full$ & 0xFF */)) {\n", + "truncated", SimpleItoa(WireFormat::MakeTag(field) & 0xFF), + "full", SimpleItoa(WireFormat::MakeTag(field))); printer->Indent(); if (field->is_packed()) { @@ -3409,22 +3741,30 @@ GenerateMergeFromCodedStream(io::Printer* printer) { if (field->is_packed()) { internal::WireFormatLite::WireType wiretype = WireFormat::WireTypeForFieldType(field->type()); - printer->Print("} else if (static_cast< ::google::protobuf::uint8>(tag) ==\n" - " static_cast< ::google::protobuf::uint8>($uncommontag$u)) {\n", - "uncommontag", SimpleItoa( - internal::WireFormatLite::MakeTag( - field->number(), wiretype))); + const uint32 tag = internal::WireFormatLite::MakeTag( + field->number(), wiretype); + printer->Print( + "} else if (\n" + " static_cast< ::google::protobuf::uint8>(tag) ==\n" + " static_cast< ::google::protobuf::uint8>($truncated$u /* $full$ & 0xFF */)) {\n", + "truncated", SimpleItoa(tag & 0xFF), + "full", SimpleItoa(tag)); + printer->Indent(); field_generator.GenerateMergeFromCodedStream(printer); printer->Outdent(); } else if (field->is_packable() && !field->is_packed()) { internal::WireFormatLite::WireType wiretype = internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED; - printer->Print("} else if (static_cast< ::google::protobuf::uint8>(tag) ==\n" - " static_cast< ::google::protobuf::uint8>($uncommontag$u)) {\n", - "uncommontag", SimpleItoa( - internal::WireFormatLite::MakeTag( - field->number(), wiretype))); + const uint32 tag = internal::WireFormatLite::MakeTag( + field->number(), wiretype); + + printer->Print( + "} else if (\n" + " static_cast< ::google::protobuf::uint8>(tag) ==\n" + " static_cast< ::google::protobuf::uint8>($truncated$u /* $full$ & 0xFF */)) {\n", + "truncated", SimpleItoa(tag & 0xFF), + "full", SimpleItoa(tag)); printer->Indent(); field_generator.GenerateMergeFromCodedStreamWithPacking(printer); printer->Outdent(); @@ -3450,12 +3790,20 @@ GenerateMergeFromCodedStream(io::Printer* printer) { printer->Print("handle_unusual:\n"); printer->Indent(); // If tag is 0 or an end-group tag then this must be the end of the message. - printer->Print( - "if (tag == 0 ||\n" - " ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" - " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" - " goto success;\n" - "}\n"); + if (capture_last_tag) { + printer->Print( + "if (tag == 0 ||\n" + " ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" + " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" + " input->SetLastTag(tag);\n" + " goto success;\n" + "}\n"); + } else { + printer->Print( + "if (tag == 0) {\n" + " goto success;\n" + "}\n"); + } // Handle extension ranges. if (descriptor_->extension_range_count() > 0) { @@ -3483,23 +3831,16 @@ GenerateMergeFromCodedStream(io::Printer* printer) { } } printer->Print(") {\n"); - if (PreserveUnknownFields(descriptor_)) { - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - printer->Print( - " DO_(_extensions_.ParseField(tag, input, " - "internal_default_instance(),\n" - " mutable_unknown_fields()));\n"); - } else { - printer->Print( - " DO_(_extensions_.ParseField(tag, input, " - "internal_default_instance(),\n" - " &unknown_fields_stream));\n"); - } + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + printer->Print(vars, + " DO_(_extensions_.ParseField(tag, input,\n" + " internal_default_instance(),\n" + " $mutable_unknown_fields$));\n"); } else { printer->Print( - // With static initializers. - " DO_(_extensions_.ParseField(tag, input, " - "internal_default_instance());\n"); + " DO_(_extensions_.ParseField(tag, input,\n" + " internal_default_instance(),\n" + " &unknown_fields_stream));\n"); } printer->Print( " continue;\n" @@ -3507,19 +3848,14 @@ GenerateMergeFromCodedStream(io::Printer* printer) { } // We really don't recognize this tag. Skip it. - if (PreserveUnknownFields(descriptor_)) { - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - printer->Print( + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + printer->Print(vars, "DO_(::google::protobuf::internal::WireFormat::SkipField(\n" - " input, tag, mutable_unknown_fields()));\n"); - } else { - printer->Print( - "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n" - " input, tag, &unknown_fields_stream));\n"); - } + " input, tag, $mutable_unknown_fields$));\n"); } else { printer->Print( - "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n"); + "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n" + " input, tag, &unknown_fields_stream));\n"); } if (descriptor_->field_count() > 0) { @@ -3656,13 +3992,16 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) { " _extensions_.SerializeMessageSetWithCachedSizes(output);\n", "classname", classname_); GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_)); - printer->Print( + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + printer->Print(vars, " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n" - " unknown_fields(), output);\n"); + " $unknown_fields$, output);\n"); printer->Print( "}\n"); return; } + if (options_.table_driven_serialization) return; printer->Print( "void $classname$::SerializeWithCachedSizes(\n" @@ -3697,10 +4036,12 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { " deterministic, target);\n", "classname", classname_); GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_)); - printer->Print( + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + printer->Print(vars, " target = ::google::protobuf::internal::WireFormat::\n" " SerializeUnknownMessageSetItemsToArray(\n" - " unknown_fields(), target);\n"); + " $unknown_fields$, target);\n"); printer->Print( " return target;\n" "}\n"); @@ -3865,29 +4206,29 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { } } - if (PreserveUnknownFields(descriptor_)) { - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - printer->Print("if (_internal_metadata_.have_unknown_fields()) {\n"); - printer->Indent(); - if (to_array) { - printer->Print( - "target = " - "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n" - " unknown_fields(), target);\n"); - } else { - printer->Print( - "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" - " unknown_fields(), output);\n"); - } - printer->Outdent(); - - printer->Print( - "}\n"); + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + printer->Print(vars, + "if ($have_unknown_fields$) {\n"); + printer->Indent(); + if (to_array) { + printer->Print(vars, + "target = " + "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n" + " $unknown_fields$, target);\n"); } else { - printer->Print( - "output->WriteRaw(unknown_fields().data(),\n" - " static_cast<int>(unknown_fields().size()));\n"); + printer->Print(vars, + "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" + " $unknown_fields$, output);\n"); } + printer->Outdent(); + + printer->Print("}\n"); + } else { + printer->Print(vars, + "output->WriteRaw($unknown_fields$.data(),\n" + " static_cast<int>($unknown_fields$.size()));\n"); } } @@ -3931,18 +4272,19 @@ void MessageGenerator:: GenerateByteSize(io::Printer* printer) { if (descriptor_->options().message_set_wire_format()) { // Special-case MessageSet. - printer->Print( - "size_t $classname$::ByteSizeLong() const {\n" - "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" - " size_t total_size = _extensions_.MessageSetByteSize();\n", - "classname", classname_, "full_name", descriptor_->full_name()); GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_)); - printer->Print( - "if (_internal_metadata_.have_unknown_fields()) {\n" - " total_size += ::google::protobuf::internal::WireFormat::\n" - " ComputeUnknownMessageSetItemsSize(unknown_fields());\n" - "}\n"); - printer->Print( + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + vars["classname"] = classname_; + vars["full_name"] = descriptor_->full_name(); + printer->Print(vars, + "size_t $classname$::ByteSizeLong() const {\n" + "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" + " size_t total_size = _extensions_.MessageSetByteSize();\n" + " if ($have_unknown_fields$) {\n" + " total_size += ::google::protobuf::internal::WireFormat::\n" + " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n" + " }\n" " int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);\n" " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" " _cached_size_ = cached_size;\n" @@ -3996,19 +4338,19 @@ GenerateByteSize(io::Printer* printer) { "\n"); } - if (PreserveUnknownFields(descriptor_)) { - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - printer->Print( - "if (_internal_metadata_.have_unknown_fields()) {\n" - " total_size +=\n" - " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n" - " unknown_fields());\n" - "}\n"); - } else { - printer->Print( - "total_size += unknown_fields().size();\n" - "\n"); - } + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + printer->Print(vars, + "if ($have_unknown_fields$) {\n" + " total_size +=\n" + " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n" + " $unknown_fields$);\n" + "}\n"); + } else { + printer->Print(vars, + "total_size += $unknown_fields$.size();\n" + "\n"); } // Handle required fields (if any). We expect all of them to be @@ -4357,7 +4699,6 @@ GenerateIsInitialized(io::Printer* printer) { "}\n"); } - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index 23aaeeb0..352069eb 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -104,10 +104,6 @@ class MessageGenerator { // allocated before any can be initialized. void GenerateDefaultInstanceInitializer(io::Printer* printer); - // Generates code that should be run when ShutdownProtobufLibrary() is called, - // to delete all dynamically-allocated objects. - void GenerateShutdownCode(io::Printer* printer); - // Generate all non-inline methods for this class. void GenerateClassMethods(io::Printer* printer); @@ -132,6 +128,9 @@ class MessageGenerator { // of entries generated and the index of the first has_bit entry. std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer); void GenerateSchema(io::Printer* printer, int offset, int has_offset); + // For each field generates a table entry describing the field for the + // table driven serializer. + int GenerateFieldMetadata(io::Printer* printer); // Generate constructors and destructor. void GenerateStructors(io::Printer* printer); @@ -147,6 +146,13 @@ class MessageGenerator { // Generate the arena-specific destructor code. void GenerateArenaDestructorCode(io::Printer* printer); + // Helper for GenerateClear and others. Optionally emits a condition that + // assumes the existence of the cached_has_bits variable, and returns true if + // the condition was printed. + bool MaybeGenerateOptionalFieldCondition(io::Printer* printer, + const FieldDescriptor* field, + int expected_has_bits_index); + // Generate standard Message methods. void GenerateClear(io::Printer* printer); void GenerateOneofClear(io::Printer* printer); @@ -179,7 +185,6 @@ class MessageGenerator { io::Printer* printer, const Descriptor::ExtensionRange* range, bool unbounded); - // Generates has_foo() functions and variables for singular field has-bits. void GenerateSingularFieldHasBits(const FieldDescriptor* field, std::map<string, string> vars, diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index ed1719cc..da4c3950 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -50,6 +50,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, const Options& options) { SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = FieldMessageTypeName(descriptor); + (*variables)["type_default_instance"] = + DefaultInstanceName(descriptor->message_type()); if (descriptor->options().weak() || !descriptor->containing_oneof()) { (*variables)["non_null_ptr_to_name"] = StrCat("this->", (*variables)["name"], "_"); @@ -98,6 +100,7 @@ void MessageFieldGenerator:: GenerateGetterDeclaration(io::Printer* printer) const { printer->Print(variables_, "$deprecated_attr$const $type$& $name$() const;\n"); + printer->Annotate("name", descriptor_); } void MessageFieldGenerator:: @@ -107,9 +110,14 @@ GenerateDependentAccessorDeclarations(io::Printer* printer) const { } // Arena manipulation code is out-of-line in the derived message class. printer->Print(variables_, - "$deprecated_attr$$type$* mutable_$name$();\n" - "$deprecated_attr$$type$* $release_name$();\n" - "$deprecated_attr$void set_allocated_$name$($type$* $name$);\n"); + "$deprecated_attr$$type$* ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, "$deprecated_attr$$type$* $release_name$();\n"); + printer->Annotate("release_name", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$set_allocated_$name$$}$" + "($type$* $name$);\n"); + printer->Annotate("{", "}", descriptor_); } void MessageFieldGenerator:: @@ -130,15 +138,25 @@ GenerateAccessorDeclarations(io::Printer* printer) const { GenerateGetterDeclaration(printer); if (!dependent_field_) { printer->Print(variables_, - "$deprecated_attr$$type$* mutable_$name$();\n" - "$deprecated_attr$$type$* $release_name$();\n" - "$deprecated_attr$void set_allocated_$name$($type$* $name$);\n"); + "$deprecated_attr$$type$* ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, "$deprecated_attr$$type$* $release_name$();\n"); + printer->Annotate("release_name", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$set_allocated_$name$$}$" + "($type$* $name$);\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportsArenas(descriptor_)) { + printer->Print( + variables_, + "$deprecated_attr$$type$* ${$unsafe_arena_release_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); printer->Print(variables_, - "$deprecated_attr$$type$* unsafe_arena_release_$name$();\n" - "$deprecated_attr$void unsafe_arena_set_allocated_$name$(\n" - " $type$* $name$);\n"); + "$deprecated_attr$void " + "${$unsafe_arena_set_allocated_$name$$}$(\n" + " $type$* $name$);\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -346,30 +364,18 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { void MessageFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { - if (dependent_field_) { - // for dependent fields we cannot access its internal_default_instance, - // because the type is incomplete. - // TODO(gerbens) deprecate dependent base class. - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; - printer->Print(variables, - "$inline$const $type$& $classname$::$name$() const {\n" - " // @@protoc_insertion_point(field_get:$full_name$)\n" - " return $name$_ != NULL ? *$name$_\n" - " : *internal_default_instance()->$name$_;\n" - "}\n"); - return; - } - std::map<string, string> variables(variables_); variables["inline"] = is_inline ? "inline " : ""; printer->Print(variables, "$inline$const $type$& $classname$::$name$() const {\n" + " const $type$* p = $name$_;\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" - " return $name$_ != NULL ? *$name$_\n" - " : *$type$::internal_default_instance();\n" + " return p != NULL ? *p : *reinterpret_cast<const $type$*>(\n" + " &$type_default_instance$);\n" "}\n"); + if (dependent_field_) return; + if (SupportsArenas(descriptor_)) { printer->Print(variables, "$inline$" @@ -511,18 +517,18 @@ GenerateMergingCode(io::Printer* printer) const { void MessageFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); + printer->Print(variables_, "swap($name$_, other->$name$_);\n"); } void MessageFieldGenerator:: GenerateDestructorCode(io::Printer* printer) const { + // TODO(gerbens) Remove this when we don't need to destruct default instances. // In google3 a default instance will never get deleted so we don't need to // worry about that but in opensource protobuf default instances are deleted // in shutdown process and we need to take special care when handling them. printer->Print(variables_, - "if (this != internal_default_instance()) {\n" - " delete $name$_;\n" - "}\n"); + "if (this != internal_default_instance()) "); + printer->Print(variables_, "delete $name$_;\n"); } void MessageFieldGenerator:: @@ -899,16 +905,20 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedMessageFieldGenerator:: InternalGenerateTypeDependentAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "$deprecated_attr$$type$* mutable_$name$(int index);\n" - "$deprecated_attr$$type$* add_$name$();\n"); + "$deprecated_attr$$type$* ${$mutable_$name$$}$(int index);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, "$deprecated_attr$$type$* ${$add_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); if (dependent_getter_) { printer->Print(variables_, "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< $type$ >&\n" " $name$() const;\n"); + printer->Annotate("name", descriptor_); } printer->Print(variables_, - "$deprecated_attr$::google::protobuf::RepeatedPtrField< $type$ >*\n" - " mutable_$name$();\n"); + "$deprecated_attr$::google::protobuf::RepeatedPtrField< $type$ >*\n" + " ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedMessageFieldGenerator:: @@ -916,6 +926,7 @@ GenerateDependentAccessorDeclarations(io::Printer* printer) const { if (dependent_getter_) { printer->Print(variables_, "$deprecated_attr$const $type$& $name$(int index) const;\n"); + printer->Annotate("name", descriptor_); } if (dependent_field_) { InternalGenerateTypeDependentAccessorDeclarations(printer); @@ -927,6 +938,7 @@ GenerateAccessorDeclarations(io::Printer* printer) const { if (!dependent_getter_) { printer->Print(variables_, "$deprecated_attr$const $type$& $name$(int index) const;\n"); + printer->Annotate("name", descriptor_); } if (!dependent_field_) { InternalGenerateTypeDependentAccessorDeclarations(printer); @@ -935,6 +947,7 @@ GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< $type$ >&\n" " $name$() const;\n"); + printer->Annotate("name", descriptor_); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc new file mode 100644 index 00000000..f72a7d60 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc @@ -0,0 +1,169 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/test_util.h> +#include <google/protobuf/unittest.pb.h> +#include <gtest/gtest.h> + +#if LANG_CXX11 +#include <google/protobuf/stubs/type_traits.h> +#endif + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. +namespace cpp_unittest { + +// Moves are enabled only when compiling with a C++11 compiler or newer. +#if LANG_CXX11 + +TEST(MovableMessageTest, MoveConstructor) { + protobuf_unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + const auto* nested = &message1.optional_nested_message(); + + protobuf_unittest::TestAllTypes message2(std::move(message1)); + TestUtil::ExpectAllFieldsSet(message2); + + // Check if the optional_nested_message was actually moved (and not just + // copied). + EXPECT_EQ(nested, &message2.optional_nested_message()); + EXPECT_NE(nested, &message1.optional_nested_message()); +} + +TEST(MovableMessageTest, MoveAssignmentOperator) { + protobuf_unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + const auto* nested = &message1.optional_nested_message(); + + protobuf_unittest::TestAllTypes message2; + message2 = std::move(message1); + TestUtil::ExpectAllFieldsSet(message2); + + // Check if the optional_nested_message was actually moved (and not just + // copied). + EXPECT_EQ(nested, &message2.optional_nested_message()); + EXPECT_NE(nested, &message1.optional_nested_message()); +} + +TEST(MovableMessageTest, SelfMoveAssignment) { + // The `self` reference is necessary to defeat -Wself-move. + protobuf_unittest::TestAllTypes message, &self = message; + TestUtil::SetAllFields(&message); + message = std::move(self); + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(MovableMessageTest, MoveSameArena) { + Arena arena; + + auto* message1_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena); + TestUtil::SetAllFields(message1_on_arena); + const auto* nested = &message1_on_arena->optional_nested_message(); + + auto* message2_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena); + + // Moving messages on the same arena should lead to swapped pointers. + *message2_on_arena = std::move(*message1_on_arena); + EXPECT_EQ(nested, &message2_on_arena->optional_nested_message()); +} + +TEST(MovableMessageTest, MoveDifferentArenas) { + Arena arena1, arena2; + + auto* message1_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena1); + TestUtil::SetAllFields(message1_on_arena); + const auto* nested = &message1_on_arena->optional_nested_message(); + + auto* message2_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena2); + + // Moving messages on two different arenas should lead to a copy. + *message2_on_arena = std::move(*message1_on_arena); + EXPECT_NE(nested, &message2_on_arena->optional_nested_message()); + TestUtil::ExpectAllFieldsSet(*message1_on_arena); + TestUtil::ExpectAllFieldsSet(*message2_on_arena); +} + +TEST(MovableMessageTest, MoveFromArena) { + Arena arena; + + auto* message1_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena); + TestUtil::SetAllFields(message1_on_arena); + const auto* nested = &message1_on_arena->optional_nested_message(); + + protobuf_unittest::TestAllTypes message2; + + // Moving from a message on the arena should lead to a copy. + message2 = std::move(*message1_on_arena); + EXPECT_NE(nested, &message2.optional_nested_message()); + TestUtil::ExpectAllFieldsSet(*message1_on_arena); + TestUtil::ExpectAllFieldsSet(message2); +} + +TEST(MovableMessageTest, MoveToArena) { + Arena arena; + + protobuf_unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + const auto* nested = &message1.optional_nested_message(); + + auto* message2_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena); + + // Moving to a message on the arena should lead to a copy. + *message2_on_arena = std::move(message1); + EXPECT_NE(nested, &message2_on_arena->optional_nested_message()); + TestUtil::ExpectAllFieldsSet(message1); + TestUtil::ExpectAllFieldsSet(*message2_on_arena); +} + +TEST(MovableMessageTest, Noexcept) { + EXPECT_TRUE( + std::is_nothrow_move_constructible<protobuf_unittest::TestAllTypes>()); + EXPECT_TRUE(std::is_nothrow_move_assignable<protobuf_unittest::TestAllTypes>()); +} + +#endif // LANG_CXX11 + +} // namespace cpp_unittest + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index bdaa12a5..04338083 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -49,7 +49,8 @@ struct Options { transitive_pb_h(true), annotate_headers(false), enforce_lite(false), - table_driven_parsing(false) {} + table_driven_parsing(false), + table_driven_serialization(false) {} string dllexport_decl; bool safe_boundary_check; @@ -58,6 +59,7 @@ struct Options { bool annotate_headers; bool enforce_lite; bool table_driven_parsing; + bool table_driven_serialization; 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 e45f35b3..b05fcc4e 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -115,9 +115,11 @@ GeneratePrivateMembers(io::Printer* printer) const { void PrimitiveFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, "$deprecated_attr$$type$ $name$() const;\n"); + printer->Annotate("name", descriptor_); printer->Print(variables_, - "$deprecated_attr$$type$ $name$() const;\n" - "$deprecated_attr$void set_$name$($type$ value);\n"); + "$deprecated_attr$void ${$set_$name$$}$($type$ value);\n"); + printer->Annotate("{", "}", descriptor_); } void PrimitiveFieldGenerator:: @@ -148,7 +150,7 @@ GenerateMergingCode(io::Printer* printer) const { void PrimitiveFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); + printer->Print(variables_, "swap($name$_, other->$name$_);\n"); } void PrimitiveFieldGenerator:: @@ -290,14 +292,23 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "$deprecated_attr$$type$ $name$(int index) const;\n" - "$deprecated_attr$void set_$name$(int index, $type$ value);\n" - "$deprecated_attr$void add_$name$($type$ value);\n"); + "$deprecated_attr$$type$ $name$(int index) const;\n"); + printer->Annotate("name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_$name$$}$(int index, $type$ value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$add_$name$$}$($type$ value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$const ::google::protobuf::RepeatedField< $type$ >&\n" + " $name$() const;\n"); + printer->Annotate("name", descriptor_); printer->Print(variables_, - "$deprecated_attr$const ::google::protobuf::RepeatedField< $type$ >&\n" - " $name$() const;\n" - "$deprecated_attr$::google::protobuf::RepeatedField< $type$ >*\n" - " mutable_$name$();\n"); + "$deprecated_attr$::google::protobuf::RepeatedField< $type$ >*\n" + " ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedPrimitiveFieldGenerator:: @@ -316,8 +327,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { "$inline$void $classname$::add_$name$($type$ value) {\n" " $name$_.Add(value);\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" - "}\n"); - printer->Print(variables, + "}\n" "$inline$const ::google::protobuf::RepeatedField< $type$ >&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 6a710888..fec13b6d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -142,28 +142,47 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } printer->Print(variables_, - "$deprecated_attr$const ::std::string& $name$() const;\n" - "$deprecated_attr$void set_$name$(const ::std::string& value);\n"); + "$deprecated_attr$const ::std::string& $name$() const;\n"); + printer->Annotate("name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_$name$$}$(const ::std::string& value);\n"); + printer->Annotate("{", "}", descriptor_); - if (!SupportsArenas(descriptor_)) { - printer->Print(variables_, - "#if LANG_CXX11\n" - "$deprecated_attr$void set_$name$(::std::string&& value);\n" - "#endif\n"); - } + printer->Print(variables_, + "#if LANG_CXX11\n" + "$deprecated_attr$void ${$set_$name$$}$(::std::string&& value);\n" + "#endif\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_$name$$}$(const char* value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$set_$name$$}$(const $pointer_type$* " + "value, size_t size)" + ";\n"); + printer->Annotate("{", "}", descriptor_); printer->Print(variables_, - "$deprecated_attr$void set_$name$(const char* value);\n" - "$deprecated_attr$void set_$name$(const $pointer_type$* value, size_t size)" - ";\n" - "$deprecated_attr$::std::string* mutable_$name$();\n" - "$deprecated_attr$::std::string* $release_name$();\n" - "$deprecated_attr$void set_allocated_$name$(::std::string* $name$);\n"); + "$deprecated_attr$::std::string* ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, "$deprecated_attr$::std::string* $release_name$();\n"); + printer->Annotate("release_name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_allocated_$name$$}$(::std::string* $name$);\n"); + printer->Annotate("{", "}", descriptor_); if (SupportsArenas(descriptor_)) { - printer->Print(variables_, - "$deprecated_attr$::std::string* unsafe_arena_release_$name$();\n" - "$deprecated_attr$void unsafe_arena_set_allocated_$name$(\n" - " ::std::string* $name$);\n"); + printer->Print( + variables_, + "$deprecated_attr$::std::string* ${$unsafe_arena_release_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$unsafe_arena_set_allocated_$name$$}$(\n" + " ::std::string* $name$);\n"); + printer->Annotate("{", "}", descriptor_); } @@ -191,6 +210,14 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, " $name$_.Set($default_variable$, value, GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" + "#if LANG_CXX11\n" + "$inline$void $classname$::set_$name$(::std::string&& value) {\n" + " $set_hasbit$\n" + " $name$_.Set(\n" + " $default_variable$, ::std::move(value), GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "#endif\n" "$inline$void $classname$::set_$name$(const char* value) {\n" " $null_check$" " $set_hasbit$\n" @@ -456,15 +483,10 @@ GenerateDefaultInstanceAllocator(io::Printer* printer) const { printer->Print(variables_, "$classname$::$default_variable_name$.DefaultConstruct();\n" "*$classname$::$default_variable_name$.get_mutable() = " - "::std::string($default$, $default_length$);\n"); - } -} - -void StringFieldGenerator:: -GenerateShutdownCode(io::Printer* printer) const { - if (!descriptor_->default_value_string().empty()) { - printer->Print(variables_, - "$classname$::$default_variable_name$.Shutdown();\n"); + "::std::string($default$, $default_length$);\n" + "::google::protobuf::internal::OnShutdownDestroyString(\n" + " $classname$::$default_variable_name$.get_mutable());\n" + ); } } @@ -554,6 +576,19 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" + "#if LANG_CXX11\n" + "$inline$void $classname$::set_$name$(::std::string&& value) {\n" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $oneof_prefix$$name$_.Set(\n" + " $default_variable$, ::std::move(value), GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "#endif\n" "$inline$void $classname$::set_$name$(const char* value) {\n" " $null_check$" " if (!has_$name$()) {\n" @@ -837,28 +872,62 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } printer->Print(variables_, - "$deprecated_attr$const ::std::string& $name$(int index) const;\n" - "$deprecated_attr$::std::string* mutable_$name$(int index);\n" - "$deprecated_attr$void set_$name$(int index, const ::std::string& value);\n" - "#if LANG_CXX11\n" - "$deprecated_attr$void set_$name$(int index, ::std::string&& value);\n" - "#endif\n" - "$deprecated_attr$void set_$name$(int index, const char* value);\n" - "" - "$deprecated_attr$void set_$name$(" - "int index, const $pointer_type$* value, size_t size);\n" - "$deprecated_attr$::std::string* add_$name$();\n" - "$deprecated_attr$void add_$name$(const ::std::string& value);\n" - "#if LANG_CXX11\n" - "$deprecated_attr$void add_$name$(::std::string&& value);\n" - "#endif\n" - "$deprecated_attr$void add_$name$(const char* value);\n" - "$deprecated_attr$void add_$name$(const $pointer_type$* value, size_t size)" - ";\n" - "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() " - "const;\n" - "$deprecated_attr$::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()" + "$deprecated_attr$const ::std::string& $name$(int index) const;\n"); + printer->Annotate("name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$::std::string* ${$mutable_$name$$}$(int index);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$set_$name$$}$(int index, const " + "::std::string& value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "#if LANG_CXX11\n" + "$deprecated_attr$void ${$set_$name$$}$(int index, ::std::string&& value);\n" + "#endif\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$set_$name$$}$(int index, const " + "char* value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "" + "$deprecated_attr$void ${$set_$name$$}$(" + "int index, const $pointer_type$* value, size_t size);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$::std::string* ${$add_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$add_$name$$}$(const ::std::string& value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "#if LANG_CXX11\n" + "$deprecated_attr$void ${$add_$name$$}$(::std::string&& value);\n" + "#endif\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$add_$name$$}$(const char* value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$add_$name$$}$(const $pointer_type$* " + "value, size_t size)" + ";\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() " + "const;\n"); + printer->Annotate("name", descriptor_); + printer->Print(variables_, + "$deprecated_attr$::google::protobuf::RepeatedPtrField< ::std::string>* " + "${$mutable_$name$$}$()" ";\n"); + printer->Annotate("{", "}", descriptor_); if (unknown_ctype) { printer->Outdent(); diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h index af263c1a..531252b0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h @@ -65,7 +65,6 @@ class StringFieldGenerator : public FieldGenerator { void GenerateCopyConstructorCode(io::Printer* printer) const; void GenerateDestructorCode(io::Printer* printer) const; void GenerateDefaultInstanceAllocator(io::Printer* printer) const; - void GenerateShutdownCode(io::Printer* printer) const; void GenerateMergeFromCodedStream(io::Printer* printer) const; void GenerateSerializeWithCachedSizes(io::Printer* printer) const; void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index e56964c7..fdde771b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -576,12 +576,73 @@ TEST(GeneratedMessageTest, SwapWithOther) { EXPECT_EQ(unittest::TestAllTypes::BAR, message2.repeated_nested_enum(1)); } -TEST(GeneratedMessageTest, CopyConstructor) { - unittest::TestAllTypes message1; +TEST(GeneratedMessageTest, ADLSwap) { + unittest::TestAllTypes message1, message2; TestUtil::SetAllFields(&message1); - unittest::TestAllTypes message2(message1); + // Note the address of one of the repeated fields, to verify it was swapped + // rather than copied. + const int32* addr = &message1.repeated_int32().Get(0); + + using std::swap; + swap(message1, message2); + TestUtil::ExpectAllFieldsSet(message2); + TestUtil::ExpectClear(message1); + + EXPECT_EQ(addr, &message2.repeated_int32().Get(0)); +} + +TEST(GeneratedMessageTest, CopyConstructor) { + // All set. + { + unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + + unittest::TestAllTypes message2(message1); + TestUtil::ExpectAllFieldsSet(message2); + } + + // None set. + { + unittest::TestAllTypes message1; + unittest::TestAllTypes message2(message1); + + EXPECT_FALSE(message1.has_optional_string()); + EXPECT_FALSE(message2.has_optional_string()); + EXPECT_EQ(&message1.optional_string(), + &message2.optional_string()); + + EXPECT_FALSE(message1.has_optional_bytes()); + EXPECT_FALSE(message2.has_optional_bytes()); + EXPECT_EQ(&message1.optional_bytes(), + &message2.optional_bytes()); + + EXPECT_FALSE(message1.has_optional_nested_message()); + EXPECT_FALSE(message2.has_optional_nested_message()); + EXPECT_EQ(&message1.optional_nested_message(), + &message2.optional_nested_message()); + + EXPECT_FALSE(message1.has_optional_foreign_message()); + EXPECT_FALSE(message2.has_optional_foreign_message()); + EXPECT_EQ(&message1.optional_foreign_message(), + &message2.optional_foreign_message()); + + EXPECT_FALSE(message1.has_optional_import_message()); + EXPECT_FALSE(message2.has_optional_import_message()); + EXPECT_EQ(&message1.optional_import_message(), + &message2.optional_import_message()); + + EXPECT_FALSE(message1.has_optional_public_import_message()); + EXPECT_FALSE(message2.has_optional_public_import_message()); + EXPECT_EQ(&message1.optional_public_import_message(), + &message2.optional_public_import_message()); + + EXPECT_FALSE(message1.has_optional_lazy_message()); + EXPECT_FALSE(message2.has_optional_lazy_message()); + EXPECT_EQ(&message1.optional_lazy_message(), + &message2.optional_lazy_message()); + } } TEST(GeneratedMessageTest, CopyConstructorWithArenas) { @@ -1340,7 +1401,7 @@ class GeneratedServiceTest : public testing::Test { foo_(descriptor_->FindMethodByName("Foo")), bar_(descriptor_->FindMethodByName("Bar")), stub_(&mock_channel_), - done_(NewPermanentCallback(&DoNothing)) {} + done_(::google::protobuf::NewPermanentCallback(&DoNothing)) {} virtual void SetUp() { ASSERT_TRUE(foo_ != NULL); diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index 71e3c6de..4c357aa0 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -32,6 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. + #ifdef _MSC_VER #include <direct.h> #else @@ -58,6 +59,9 @@ #ifdef _WIN32 #include <ctype.h> +#endif + +#ifdef _MSC_VER // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. using google::protobuf::internal::win32::access; @@ -297,10 +301,8 @@ static string CanonicalizePath(string path) { } static inline bool ContainsParentReference(const string& path) { - return path == ".." || - HasPrefixString(path, "../") || - HasSuffixString(path, "/..") || - path.find("/../") != string::npos; + return path == ".." || HasPrefixString(path, "../") || + HasSuffixString(path, "/..") || path.find("/../") != string::npos; } // Maps a file from an old location to a new one. Typically, old_prefix is @@ -330,8 +332,7 @@ static bool ApplyMapping(const string& filename, // We do not allow the file name to use "..". return false; } - if (HasPrefixString(filename, "/") || - IsWindowsAbsolutePath(filename)) { + if (HasPrefixString(filename, "/") || IsWindowsAbsolutePath(filename)) { // This is an absolute path, so it isn't matched by the empty string. return false; } diff --git a/src/google/protobuf/compiler/java/java_context.cc b/src/google/protobuf/compiler/java/java_context.cc index b82fb3dd..0771d5e1 100644 --- a/src/google/protobuf/compiler/java/java_context.cc +++ b/src/google/protobuf/compiler/java/java_context.cc @@ -50,7 +50,7 @@ Context::Context(const FileDescriptor* file, const Options& options) Context::~Context() { } -ClassNameResolver* Context::GetNameResolver() { +ClassNameResolver* Context::GetNameResolver() const { return name_resolver_.get(); } @@ -154,7 +154,7 @@ void Context::InitializeFieldGeneratorInfoForFields( for (int i = 0; i < fields.size(); ++i) { const FieldDescriptor* field = fields[i]; FieldGeneratorInfo info; - info.name = UnderscoresToCamelCase(field); + info.name = CamelCaseFieldName(field); info.capitalized_name = UnderscoresToCapitalizedCamelCase(field); // For fields conflicting with some other fields, we append the field // number to their field names in generated code to avoid conflicts. diff --git a/src/google/protobuf/compiler/java/java_context.h b/src/google/protobuf/compiler/java/java_context.h index b22e7e3a..9a74c430 100644 --- a/src/google/protobuf/compiler/java/java_context.h +++ b/src/google/protobuf/compiler/java/java_context.h @@ -70,7 +70,7 @@ class Context { // Get the name resolver associated with this context. The resolver // can be used to map descriptors to Java class names. - ClassNameResolver* GetNameResolver(); + ClassNameResolver* GetNameResolver() const; // Get the FieldGeneratorInfo for a given field. const FieldGeneratorInfo* GetFieldGeneratorInfo( diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc index b9ee00ff..d125ebe5 100644 --- a/src/google/protobuf/compiler/java/java_enum.cc +++ b/src/google/protobuf/compiler/java/java_enum.cc @@ -109,14 +109,16 @@ void EnumGenerator::Generate(io::Printer* printer) { printer->Print(vars, "$name$($index$, $number$),\n"); } + printer->Annotate("name", canonical_values_[i]); } if (SupportUnknownEnumValue(descriptor_->file())) { if (ordinal_is_index) { - printer->Print("UNRECOGNIZED(-1),\n"); + printer->Print("${$UNRECOGNIZED$}$(-1),\n", "{", "", "}", ""); } else { - printer->Print("UNRECOGNIZED(-1, -1),\n"); + printer->Print("${$UNRECOGNIZED$}$(-1, -1),\n", "{", "", "}", ""); } + printer->Annotate("{", "}", descriptor_); } printer->Print( @@ -133,15 +135,19 @@ void EnumGenerator::Generate(io::Printer* printer) { WriteEnumValueDocComment(printer, aliases_[i].value); printer->Print(vars, "public static final $classname$ $name$ = $canonical_name$;\n"); + printer->Annotate("name", aliases_[i].value); } for (int i = 0; i < descriptor_->value_count(); i++) { std::map<string, string> vars; vars["name"] = descriptor_->value(i)->name(); vars["number"] = SimpleItoa(descriptor_->value(i)->number()); + vars["{"] = ""; + vars["}"] = ""; WriteEnumValueDocComment(printer, descriptor_->value(i)); printer->Print(vars, - "public static final int $name$_VALUE = $number$;\n"); + "public static final int ${$$name$_VALUE$}$ = $number$;\n"); + printer->Annotate("{", "}", descriptor_->value(i)); } printer->Print("\n"); diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index 279b9da4..9f7bb349 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -183,23 +183,26 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " $type$ result = $type$.$for_number$($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumFieldGenerator:: @@ -209,33 +212,38 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_builder$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" " $name$_ = value;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " $type$ result = $type$.$for_number$($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" @@ -244,14 +252,16 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $clear_has_field_bit_builder$\n" " $name$_ = $default_number$;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumFieldGenerator:: @@ -311,12 +321,8 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "int rawValue = input.readEnum();\n" "$type$ value = $type$.$for_number$(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " unknownFields.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" "} else {\n" " $set_has_field_bit_message$\n" " $name$_ = rawValue;\n" @@ -386,23 +392,25 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " if ($has_oneof_case_message$) {\n" " return (java.lang.Integer) $oneof_name$_;\n" " }\n" " return $default_number$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $type$ result = $type$.$for_number$(\n" " (java.lang.Integer) $oneof_name$_);\n" @@ -410,6 +418,7 @@ GenerateMembers(io::Printer* printer) const { " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumOneofFieldGenerator:: @@ -417,31 +426,35 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ((java.lang.Integer) $oneof_name$_).intValue();\n" " }\n" " return $default_number$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = value;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $type$ result = $type$.$for_number$(\n" " (java.lang.Integer) $oneof_name$_);\n" @@ -449,9 +462,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" @@ -460,9 +474,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" " $oneof_name$_ = null;\n" @@ -470,6 +485,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumOneofFieldGenerator:: @@ -502,12 +518,8 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "int rawValue = input.readEnum();\n" "$type$ value = $type$.$for_number$(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " unknownFields.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" "} else {\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = rawValue;\n" @@ -621,32 +633,38 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return new com.google.protobuf.Internal.ListAdapter<\n" " java.lang.Integer, $type$>($name$_, $name$_converter_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_converter_.convert($name$_.get(index));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<java.lang.Integer>\n" - "get$capitalized_name$ValueList() {\n" + "${$get$capitalized_name$ValueList$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value(int index) {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (descriptor_->is_packed() && @@ -684,23 +702,27 @@ GenerateBuilderMembers(io::Printer* printer) const { // could hold on to the returned list and modify it after the message // has been built, thus mutating the message which is supposed to be // immutable. - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return new com.google.protobuf.Internal.ListAdapter<\n" " java.lang.Integer, $type$>($name$_, $name$_converter_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_converter_.convert($name$_.get(index));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" @@ -710,9 +732,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" @@ -721,9 +744,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $type$> values) {\n" " ensure$capitalized_name$IsMutable();\n" " for ($type$ value : values) {\n" @@ -732,47 +756,54 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ = java.util.Collections.emptyList();\n" " $clear_mutable_bit_builder$;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<java.lang.Integer>\n" - "get$capitalized_name$ValueList() {\n" + "${$get$capitalized_name$ValueList$}$() {\n" " return java.util.Collections.unmodifiableList($name$_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value(int index) {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(\n" + "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n" " int index, int value) {\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.set(index, value);\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$add$capitalized_name$Value$}$(int value) {\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.add(value);\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$Value(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n" " java.lang.Iterable<java.lang.Integer> values) {\n" " ensure$capitalized_name$IsMutable();\n" " for (int value : values) {\n" @@ -781,6 +812,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -848,12 +880,8 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "int rawValue = input.readEnum();\n" "$type$ value = $type$.$for_number$(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " unknownFields.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" "} else {\n" " if (!$get_mutable_bit_parser$) {\n" " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n" 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 1eefdcfc..a4de1e23 100644 --- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -165,23 +165,26 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " $type$ result = $type$.forNumber($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Generate private setters for the builder to proxy into. if (SupportUnknownEnumValue(descriptor_->file())) { @@ -214,43 +217,50 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return instance.get$capitalized_name$Value();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Value(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumFieldLiteGenerator:: @@ -296,12 +306,8 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "int rawValue = input.readEnum();\n" "$type$ value = $type$.forNumber(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " super.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " super.mergeVarintField($number$, rawValue);\n" "} else {\n" " $set_has_field_bit_message$\n" " $name$_ = rawValue;\n" @@ -372,29 +378,32 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " if ($has_oneof_case_message$) {\n" " return (java.lang.Integer) $oneof_name$_;\n" " }\n" " return $default_number$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n" " return result == null ? $unknown$ : result;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Generate private setters for the builder to proxy into. if (SupportUnknownEnumValue(descriptor_->file())) { @@ -430,43 +439,50 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return instance.get$capitalized_name$Value();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Value(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumOneofFieldLiteGenerator:: @@ -487,12 +503,8 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "int rawValue = input.readEnum();\n" "$type$ value = $type$.forNumber(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " super.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " super.mergeVarintField($number$, rawValue);\n" "} else {\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = rawValue;\n" @@ -607,35 +619,41 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return new com.google.protobuf.Internal.ListAdapter<\n" " java.lang.Integer, $type$>($name$_, $name$_converter_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_converter_.convert($name$_.getInt(index));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<java.lang.Integer>\n" - "get$capitalized_name$ValueList() {\n" + "${$get$capitalized_name$ValueList$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value(int index) {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return $name$_.getInt(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } - if (descriptor_->options().packed() && + if (descriptor_->is_packed() && context_->HasGeneratedMethods(descriptor_->containing_type())) { printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n"); @@ -714,85 +732,99 @@ void RepeatedImmutableEnumFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return instance.get$capitalized_name$List();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $type$> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$(values);" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<java.lang.Integer>\n" - "get$capitalized_name$ValueList() {\n" + "${$get$capitalized_name$ValueList$}$() {\n" " return java.util.Collections.unmodifiableList(\n" " instance.get$capitalized_name$ValueList());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value(int index) {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return instance.get$capitalized_name$Value(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(\n" + "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n" " int index, int value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Value(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$add$capitalized_name$Value$}$(int value) {\n" " instance.add$capitalized_name$Value(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$Value(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n" " java.lang.Iterable<java.lang.Integer> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$Value(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -889,7 +921,7 @@ GenerateParsingDoneCode(io::Printer* printer) const { void RepeatedImmutableEnumFieldLiteGenerator:: GenerateSerializationCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (get$capitalized_name$List().size() > 0) {\n" " output.writeUInt32NoTag($tag$);\n" @@ -920,7 +952,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "}\n"); printer->Print( "size += dataSize;\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (!get$capitalized_name$List().isEmpty()) {" " size += $tag_size$;\n" @@ -933,7 +965,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } // cache the data size for packed fields. - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n"); } diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc index 38b054e7..ab3b3323 100644 --- a/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_lite.cc @@ -93,10 +93,12 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { } printer->Print(vars, "$name$($number$),\n"); + printer->Annotate("name", canonical_values_[i]); } if (SupportUnknownEnumValue(descriptor_->file())) { - printer->Print("UNRECOGNIZED(-1),\n"); + printer->Print("${$UNRECOGNIZED$}$(-1),\n", "{", "", "}", ""); + printer->Annotate("{", "}", descriptor_); } printer->Print( @@ -113,15 +115,19 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { WriteEnumValueDocComment(printer, aliases_[i].value); printer->Print(vars, "public static final $classname$ $name$ = $canonical_name$;\n"); + printer->Annotate("name", aliases_[i].value); } for (int i = 0; i < descriptor_->value_count(); i++) { std::map<string, string> vars; vars["name"] = descriptor_->value(i)->name(); vars["number"] = SimpleItoa(descriptor_->value(i)->number()); + vars["{"] = ""; + vars["}"] = ""; WriteEnumValueDocComment(printer, descriptor_->value(i)); printer->Print(vars, - "public static final int $name$_VALUE = $number$;\n"); + "public static final int ${$$name$_VALUE$}$ = $number$;\n"); + printer->Annotate("{", "}", descriptor_->value(i)); } printer->Print("\n"); diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc index cb237bf6..9b9be55b 100644 --- a/src/google/protobuf/compiler/java/java_extension.cc +++ b/src/google/protobuf/compiler/java/java_extension.cc @@ -75,7 +75,7 @@ void ExtensionGenerator::InitTemplateVars( vars["default"] = descriptor->is_repeated() ? "" : DefaultValue(descriptor, immutable, name_resolver); vars["type_constant"] = FieldTypeName(GetType(descriptor)); - vars["packed"] = descriptor->options().packed() ? "true" : "false"; + vars["packed"] = descriptor->is_packed() ? "true" : "false"; vars["enum_map"] = "null"; vars["prototype"] = "null"; diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc index 04917296..1ab18629 100644 --- a/src/google/protobuf/compiler/java/java_field.cc +++ b/src/google/protobuf/compiler/java/java_field.cc @@ -45,8 +45,6 @@ #include <google/protobuf/compiler/java/java_enum_field.h> #include <google/protobuf/compiler/java/java_enum_field_lite.h> #include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/compiler/java/java_lazy_message_field.h> -#include <google/protobuf/compiler/java/java_lazy_message_field_lite.h> #include <google/protobuf/compiler/java/java_map_field.h> #include <google/protobuf/compiler/java/java_map_field_lite.h> #include <google/protobuf/compiler/java/java_message_field.h> @@ -77,13 +75,8 @@ ImmutableFieldGenerator* MakeImmutableGenerator( return new ImmutableMapFieldGenerator( field, messageBitIndex, builderBitIndex, context); } else { - if (IsLazy(field, context->EnforceLite())) { - return new RepeatedImmutableLazyMessageFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new RepeatedImmutableMessageFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new RepeatedImmutableMessageFieldGenerator( + field, messageBitIndex, builderBitIndex, context); } case JAVATYPE_ENUM: return new RepeatedImmutableEnumFieldGenerator( @@ -99,13 +92,8 @@ ImmutableFieldGenerator* MakeImmutableGenerator( if (field->containing_oneof()) { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - if (IsLazy(field, context->EnforceLite())) { - return new ImmutableLazyMessageOneofFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new ImmutableMessageOneofFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new ImmutableMessageOneofFieldGenerator( + field, messageBitIndex, builderBitIndex, context); case JAVATYPE_ENUM: return new ImmutableEnumOneofFieldGenerator( field, messageBitIndex, builderBitIndex, context); @@ -119,13 +107,8 @@ ImmutableFieldGenerator* MakeImmutableGenerator( } else { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - if (IsLazy(field, context->EnforceLite())) { - return new ImmutableLazyMessageFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new ImmutableMessageFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new ImmutableMessageFieldGenerator( + field, messageBitIndex, builderBitIndex, context); case JAVATYPE_ENUM: return new ImmutableEnumFieldGenerator( field, messageBitIndex, builderBitIndex, context); @@ -150,13 +133,8 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator( return new ImmutableMapFieldLiteGenerator( field, messageBitIndex, builderBitIndex, context); } else { - if (IsLazy(field, context->EnforceLite())) { - return new RepeatedImmutableLazyMessageFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new RepeatedImmutableMessageFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new RepeatedImmutableMessageFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); } case JAVATYPE_ENUM: return new RepeatedImmutableEnumFieldLiteGenerator( @@ -172,13 +150,8 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator( if (field->containing_oneof()) { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - if (IsLazy(field, context->EnforceLite())) { - return new ImmutableLazyMessageOneofFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new ImmutableMessageOneofFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new ImmutableMessageOneofFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); case JAVATYPE_ENUM: return new ImmutableEnumOneofFieldLiteGenerator( field, messageBitIndex, builderBitIndex, context); @@ -192,13 +165,8 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator( } else { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - if (IsLazy(field, context->EnforceLite())) { - return new ImmutableLazyMessageFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new ImmutableMessageFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new ImmutableMessageFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); case JAVATYPE_ENUM: return new ImmutableEnumFieldLiteGenerator( field, messageBitIndex, builderBitIndex, context); @@ -293,10 +261,17 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, std::map<string, string>* variables) { (*variables)["field_name"] = descriptor->name(); (*variables)["name"] = info->name; + (*variables)["classname"] = descriptor->containing_type()->name(); (*variables)["capitalized_name"] = info->capitalized_name; (*variables)["disambiguated_reason"] = info->disambiguated_reason; (*variables)["constant_name"] = FieldConstantName(descriptor); (*variables)["number"] = SimpleItoa(descriptor->number()); + // These variables are placeholders to pick out the beginning and ends of + // identifiers for annotations (when doing so with existing variables would + // be ambiguous or impossible). They should never be set to anything but the + // empty string. + (*variables)["{"] = ""; + (*variables)["}"] = ""; } void SetCommonOneofVariables(const FieldDescriptor* descriptor, diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index 0fda166d..2d5465ba 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -499,19 +499,57 @@ void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer* // Try to load immutable messages' outer class. Its initialization code // will take care of interpreting custom options. printer->Print( - "try {\n" - // Note that we have to load the immutable class dynamically here as - // we want the mutable code to be independent from the immutable code - // at compile time. It is required to implement dual-compile for - // mutable and immutable API in blaze. - " java.lang.Class immutableClass = java.lang.Class.forName(\n" - " \"$immutable_classname$\");\n" - "} catch (java.lang.ClassNotFoundException e) {\n" - // The immutable class can not be found. Custom options are left - // as unknown fields. - // TODO(xiaofeng): inform the user with a warning? - "}\n", - "immutable_classname", name_resolver_->GetImmutableClassName(file_)); + "try {\n" + // Note that we have to load the immutable class dynamically here as + // we want the mutable code to be independent from the immutable code + // at compile time. It is required to implement dual-compile for + // mutable and immutable API in blaze. + " java.lang.Class immutableClass = java.lang.Class.forName(\n" + " \"$immutable_classname$\");\n" + "} catch (java.lang.ClassNotFoundException e) {\n", + "immutable_classname", name_resolver_->GetImmutableClassName(file_)); + printer->Indent(); + + // The immutable class can not be found. We try our best to collect all + // custom option extensions to interpret the custom options. + printer->Print( + "com.google.protobuf.ExtensionRegistry registry =\n" + " com.google.protobuf.ExtensionRegistry.newInstance();\n" + "com.google.protobuf.MessageLite defaultExtensionInstance = null;\n"); + FieldDescriptorSet::iterator it; + for (it = extensions.begin(); it != extensions.end(); it++) { + const FieldDescriptor* field = *it; + string scope; + if (field->extension_scope() != NULL) { + scope = name_resolver_->GetMutableClassName(field->extension_scope()) + + ".getDescriptor()"; + } else { + scope = FileJavaPackage(field->file(), true) + "." + + name_resolver_->GetDescriptorClassName(field->file()) + + ".descriptor"; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print( + "defaultExtensionInstance = com.google.protobuf.Internal\n" + " .getDefaultInstance(\"$class$\");\n" + "if (defaultExtensionInstance != null) {\n" + " registry.add(\n" + " $scope$.getExtensions().get($index$),\n" + " (com.google.protobuf.Message) defaultExtensionInstance);\n" + "}\n", + "scope", scope, "index", SimpleItoa(field->index()), "class", + name_resolver_->GetImmutableClassName(field->message_type())); + } else { + printer->Print("registry.add($scope$.getExtensions().get($index$));\n", + "scope", scope, "index", SimpleItoa(field->index())); + } + } + printer->Print( + "com.google.protobuf.Descriptors.FileDescriptor\n" + " .internalUpdateFileDescriptor(descriptor, registry);\n"); + + printer->Outdent(); + printer->Print("}\n"); } // Force descriptor initialization of all dependencies. diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc index 02141210..84a3b90d 100644 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ b/src/google/protobuf/compiler/java/java_generator.cc @@ -42,6 +42,7 @@ #include <google/protobuf/compiler/java/java_file.h> #include <google/protobuf/compiler/java/java_generator_factory.h> #include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/compiler/java/java_options.h> #include <google/protobuf/compiler/java/java_shared_code_generator.h> #include <google/protobuf/io/printer.h> diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index 8469740f..d8ac2db3 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -43,6 +43,8 @@ #include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> + + #include <google/protobuf/stubs/hash.h> // for hash<T *> namespace google { @@ -167,6 +169,14 @@ string UniqueFileScopeIdentifier(const Descriptor* descriptor) { return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); } +string CamelCaseFieldName(const FieldDescriptor* field) { + string fieldName = UnderscoresToCamelCase(field); + if ('0' <= fieldName[0] && fieldName[0] <= '9') { + return '_' + fieldName; + } + return fieldName; +} + string StripProto(const string& filename) { if (HasSuffixString(filename, ".protodevel")) { return StripSuffixString(filename, ".protodevel"); diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index 829ec3d7..bd565ced 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -74,6 +74,10 @@ string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field); // of lower-casing the first letter of the name.) string UnderscoresToCamelCase(const MethodDescriptor* method); +// Similar to UnderscoresToCamelCase, but guarentees that the result is a +// complete Java identifier by adding a _ if needed. +string CamelCaseFieldName(const FieldDescriptor* field); + // Get an identifier that uniquely identifies this type within the file. // This is used to declare static variables related to this type at the // outermost file scope. @@ -242,15 +246,6 @@ inline bool HasGenericServices(const FileDescriptor *file, bool enforce_lite) { file->options().java_generic_services(); } -inline bool IsLazy(const FieldDescriptor* descriptor, bool enforce_lite) { - // Currently, the proto-lite version supports lazy field. - // TODO(niwasaki): Support lazy fields also for other proto runtimes. - if (HasDescriptorMethods(descriptor->file(), enforce_lite)) { - return false; - } - return descriptor->options().lazy(); -} - // Methods for shared bitfields. // Gets the name of the shared bitfield for the given index. @@ -372,10 +367,6 @@ inline bool IsMapField(const FieldDescriptor* descriptor) { return descriptor->is_map(); } -inline bool PreserveUnknownFields(const Descriptor* descriptor) { - return descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3; -} - inline bool IsAnyMessage(const Descriptor* descriptor) { return descriptor->full_name() == "google.protobuf.Any"; } diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc index 608b5378..b22a2199 100644 --- a/src/google/protobuf/compiler/java/java_map_field.cc +++ b/src/google/protobuf/compiler/java/java_map_field.cc @@ -183,12 +183,14 @@ GenerateInterfaceMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$int get$capitalized_name$Count();\n"); + "$deprecation$int ${$get$capitalized_name$Count$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$boolean contains$capitalized_name$(\n" + "$deprecation$boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -197,23 +199,27 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$();\n"); + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map();\n"); + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$$value_enum_type$ get$capitalized_name$OrDefault(\n" + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$$value_enum_type$ get$capitalized_name$OrThrow(\n" + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -222,25 +228,29 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Value();\n"); + "${$get$capitalized_name$Value$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$ValueMap();\n"); + "${$get$capitalized_name$ValueMap$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$ValueOrDefault(\n" + "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$ValueOrThrow(\n" + "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -250,25 +260,29 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$type_parameters$>\n" - "get$capitalized_name$();\n"); + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Map();\n"); + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$OrDefault(\n" + "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$OrThrow(\n" + "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -349,23 +363,27 @@ GenerateBuilderMembers(io::Printer* printer) const { " return $name$_;\n" "}\n"); GenerateMapGetters(printer); - printer->Print(variables_, - "$deprecation$\n" - "public Builder clear$capitalized_name$() {\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .clear();\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder ${$clear$capitalized_name$$}$() {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .clear();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$\n" - "public Builder remove$capitalized_name$(\n" - " $key_type$ key) {\n" - " $key_null_check$\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .remove(key);\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder ${$remove$capitalized_name$$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .remove(key);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -374,13 +392,14 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "getMutable$capitalized_name$() {\n" + "${$getMutable$capitalized_name$$}$() {\n" " return internalGetAdapted$capitalized_name$Map(\n" " internalGetMutable$capitalized_name$().getMutableMap());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder put$capitalized_name$(\n" + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" " $key_type$ key,\n" " $value_enum_type$ value) {\n" " $key_null_check$\n" @@ -389,16 +408,18 @@ GenerateBuilderMembers(io::Printer* printer) const { " .put(key, $name$ValueConverter.doBackward(value));\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder putAll$capitalized_name$(\n" + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" " internalGetAdapted$capitalized_name$Map(\n" " internalGetMutable$capitalized_name$().getMutableMap())\n" " .putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -407,13 +428,14 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "getMutable$capitalized_name$Value() {\n" + "${$getMutable$capitalized_name$Value$}$() {\n" " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder put$capitalized_name$Value(\n" + "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n" " $key_type$ key,\n" " $value_type$ value) {\n" " $key_null_check$\n" @@ -421,15 +443,17 @@ GenerateBuilderMembers(io::Printer* printer) const { " .put(key, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder putAll$capitalized_name$Value(\n" + "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" " internalGetMutable$capitalized_name$().getMutableMap()\n" " .putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -439,30 +463,35 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$type_parameters$>\n" - "getMutable$capitalized_name$() {\n" + "${$getMutable$capitalized_name$$}$() {\n" " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$" - "public Builder put$capitalized_name$(\n" - " $key_type$ key,\n" - " $value_type$ value) {\n" - " $key_null_check$\n" - " $value_null_check$\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .put(key, value);\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$" + "public Builder ${$put$capitalized_name$$}$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .put(key, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$\n" - "public Builder putAll$capitalized_name$(\n" - " java.util.Map<$type_parameters$> values) {\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .putAll(values);\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$type_parameters$> values) {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .putAll(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -471,18 +500,20 @@ GenerateMapGetters(io::Printer* printer) const { printer->Print( variables_, "$deprecation$\n" - "public int get$capitalized_name$Count() {\n" + "public int ${$get$capitalized_name$Count$}$() {\n" " return internalGet$capitalized_name$().getMap().size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public boolean contains$capitalized_name$(\n" + "public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " return internalGet$capitalized_name$().getMap().containsKey(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -491,22 +522,25 @@ GenerateMapGetters(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$() {\n" + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$\n" - "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map() {\n" - " return internalGetAdapted$capitalized_name$Map(\n" - " internalGet$capitalized_name$().getMap());" - "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$Map$}$() {\n" + " return internalGetAdapted$capitalized_name$Map(\n" + " internalGet$capitalized_name$().getMap());" + "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrDefault(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue) {\n" " $key_null_check$\n" @@ -516,11 +550,12 @@ GenerateMapGetters(io::Printer* printer) const { " ? $name$ValueConverter.doForward(map.get(key))\n" " : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrThrow(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -530,6 +565,7 @@ GenerateMapGetters(io::Printer* printer) const { " }\n" " return $name$ValueConverter.doForward(map.get(key));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -538,22 +574,24 @@ GenerateMapGetters(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$Value() {\n" + "${$get$capitalized_name$Value$}$() {\n" " return get$capitalized_name$ValueMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$ValueMap() {\n" + "${$get$capitalized_name$ValueMap$}$() {\n" " return internalGet$capitalized_name$().getMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrDefault(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -561,11 +599,12 @@ GenerateMapGetters(io::Printer* printer) const { " internalGet$capitalized_name$().getMap();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrThrow(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -575,6 +614,7 @@ GenerateMapGetters(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -583,21 +623,25 @@ GenerateMapGetters(io::Printer* printer) const { " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" "@java.lang.Deprecated\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$Map$}$() {\n" " return internalGet$capitalized_name$().getMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrDefault(\n" + "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -605,11 +649,12 @@ GenerateMapGetters(io::Printer* printer) const { " internalGet$capitalized_name$().getMap();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrThrow(\n" + "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$type_parameters$> map =\n" @@ -619,6 +664,7 @@ GenerateMapGetters(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } 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 073d1cfc..f19ec271 100644 --- a/src/google/protobuf/compiler/java/java_map_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc @@ -166,12 +166,14 @@ GenerateInterfaceMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$int get$capitalized_name$Count();\n"); + "$deprecation$int ${$get$capitalized_name$Count$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$boolean contains$capitalized_name$(\n" + "$deprecation$boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -180,23 +182,27 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$();\n"); + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map();\n"); + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$$value_enum_type$ get$capitalized_name$OrDefault(\n" + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$$value_enum_type$ get$capitalized_name$OrThrow(\n" + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -205,25 +211,29 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Value();\n"); + "${$get$capitalized_name$Value$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$ValueMap();\n"); + "${$get$capitalized_name$ValueMap$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$ValueOrDefault(\n" + "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$ValueOrThrow(\n" + "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -233,25 +243,29 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$type_parameters$>\n" - "get$capitalized_name$();\n"); + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Map();\n"); + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$OrDefault(\n" + "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$OrThrow(\n" + "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -288,18 +302,20 @@ GenerateMembers(io::Printer* printer) const { printer->Print( variables_, "$deprecation$\n" - "public int get$capitalized_name$Count() {\n" + "public int ${$get$capitalized_name$Count$}$() {\n" " return internalGet$capitalized_name$().size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public boolean contains$capitalized_name$(\n" + "public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " return internalGet$capitalized_name$().containsKey(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -316,26 +332,28 @@ GenerateMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$() {\n" + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map() {\n" + "${$get$capitalized_name$Map$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " new com.google.protobuf.Internal.MapAdapter<\n" " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" " internalGet$capitalized_name$(),\n" " $name$ValueConverter));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrDefault(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue) {\n" " $key_null_check$\n" @@ -345,11 +363,12 @@ GenerateMembers(io::Printer* printer) const { " ? $name$ValueConverter.doForward(map.get(key))\n" " : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrThrow(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -359,6 +378,7 @@ GenerateMembers(io::Printer* printer) const { " }\n" " return $name$ValueConverter.doForward(map.get(key));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -367,23 +387,25 @@ GenerateMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$Value() {\n" + "${$get$capitalized_name$Value$}$() {\n" " return get$capitalized_name$ValueMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$ValueMap() {\n" + "${$get$capitalized_name$ValueMap$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " internalGet$capitalized_name$());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrDefault(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -391,11 +413,12 @@ GenerateMembers(io::Printer* printer) const { " internalGet$capitalized_name$();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrThrow(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -405,6 +428,7 @@ GenerateMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -413,22 +437,26 @@ GenerateMembers(io::Printer* printer) const { " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" "@java.lang.Deprecated\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$Map$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " internalGet$capitalized_name$());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrDefault(\n" + "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -436,11 +464,12 @@ GenerateMembers(io::Printer* printer) const { " internalGet$capitalized_name$();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrThrow(\n" + "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$type_parameters$> map =\n" @@ -450,6 +479,7 @@ GenerateMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } // Generate private setters for the builder to proxy into. @@ -490,37 +520,41 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print( variables_, "$deprecation$\n" - "public int get$capitalized_name$Count() {\n" + "public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Map().size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public boolean contains$capitalized_name$(\n" + "public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " return instance.get$capitalized_name$Map().containsKey(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); printer->Print( variables_, "$deprecation$\n" - "public Builder clear$capitalized_name$() {\n" + "public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$Map().clear();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public Builder remove$capitalized_name$(\n" + "public Builder ${$remove$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$Map().remove(key);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -529,23 +563,25 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$() {\n" + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map() {\n" + "${$get$capitalized_name$Map$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " instance.get$capitalized_name$Map());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrDefault(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue) {\n" " $key_null_check$\n" @@ -555,11 +591,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " ? map.get(key)\n" " : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrThrow(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n" @@ -569,10 +606,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder put$capitalized_name$(\n" + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" " $key_type$ key,\n" " $value_enum_type$ value) {\n" " $key_null_check$\n" @@ -581,15 +619,17 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.getMutable$capitalized_name$Map().put(key, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder putAll$capitalized_name$(\n" + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$Map().putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -598,23 +638,25 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$Value() {\n" + "${$get$capitalized_name$Value$}$() {\n" " return get$capitalized_name$ValueMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$ValueMap() {\n" + "${$get$capitalized_name$ValueMap$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " instance.get$capitalized_name$ValueMap());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrDefault(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -622,11 +664,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.get$capitalized_name$ValueMap();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrThrow(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -636,10 +679,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder put$capitalized_name$Value(\n" + "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n" " $key_type$ key,\n" " $value_type$ value) {\n" " $key_null_check$\n" @@ -647,15 +691,17 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.getMutable$capitalized_name$ValueMap().put(key, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder putAll$capitalized_name$Value(\n" + "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$ValueMap().putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -664,22 +710,26 @@ GenerateBuilderMembers(io::Printer* printer) const { " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" "@java.lang.Deprecated\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$" - "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$Map$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " instance.get$capitalized_name$Map());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrDefault(\n" + "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -687,11 +737,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.get$capitalized_name$Map();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrThrow(\n" + "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$type_parameters$> map =\n" @@ -701,11 +752,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$" - "public Builder put$capitalized_name$(\n" + "public Builder ${$put$capitalized_name$$}$(\n" " $key_type$ key,\n" " $value_type$ value) {\n" " $key_null_check$\n" @@ -714,16 +766,18 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.getMutable$capitalized_name$Map().put(key, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$" - "public Builder putAll$capitalized_name$(\n" + "public Builder ${$putAll$capitalized_name$$}$(\n" " java.util.Map<$type_parameters$> values) {\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$Map().putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 6e3b4a75..ecc67575 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -56,8 +56,9 @@ #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/stubs/strutil.h> + namespace google { namespace protobuf { @@ -253,7 +254,7 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.GeneratedMessage$ver$.\n" " ExtendableMessageOrBuilder<$classname$> {\n", @@ -261,19 +262,19 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), - "idend", "", "ver", GeneratedCodeVersionSuffix()); + "{", "", "}", "", "ver", GeneratedCodeVersionSuffix()); } else { printer->Print( - "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.MessageOrBuilder {\n", "deprecation", descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), - "idend", ""); + "{", "", "}", ""); } - printer->Annotate("classname", "idend", descriptor_); + printer->Annotate("{", "}", descriptor_); printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { @@ -345,6 +346,9 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { "com.google.protobuf.GeneratedMessage$0.Builder<?>", GeneratedCodeVersionSuffix()); } + printer->Print( + "private static final long serialVersionUID = 0L;\n"); + printer->Indent(); // Using builder_type, instead of Builder, prevents the Builder class from // being loaded into PermGen space when the default instance is created. @@ -370,15 +374,8 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { printer->Print( "@java.lang.Override\n" "public final com.google.protobuf.UnknownFieldSet\n" - "getUnknownFields() {\n"); - if (PreserveUnknownFields(descriptor_)) { - printer->Print( - " return this.unknownFields;\n"); - } else { - printer->Print( - " return com.google.protobuf.UnknownFieldSet.getDefaultInstance();\n"); - } - printer->Print( + "getUnknownFields() {\n" + " return this.unknownFields;\n" "}\n"); if (context_->HasGeneratedMethods(descriptor_)) { @@ -623,14 +620,12 @@ GenerateMessageSerializationMethods(io::Printer* printer) { } } - if (PreserveUnknownFields(descriptor_)) { - if (descriptor_->options().message_set_wire_format()) { - printer->Print( + if (descriptor_->options().message_set_wire_format()) { + printer->Print( "unknownFields.writeAsMessageSetTo(output);\n"); - } else { - printer->Print( + } else { + printer->Print( "unknownFields.writeTo(output);\n"); - } } printer->Outdent(); @@ -658,14 +653,12 @@ GenerateMessageSerializationMethods(io::Printer* printer) { } } - if (PreserveUnknownFields(descriptor_)) { - if (descriptor_->options().message_set_wire_format()) { - printer->Print( + if (descriptor_->options().message_set_wire_format()) { + printer->Print( "size += unknownFields.getSerializedSizeAsMessageSet();\n"); - } else { - printer->Print( + } else { + printer->Print( "size += unknownFields.getSerializedSize();\n"); - } } printer->Outdent(); @@ -674,9 +667,6 @@ GenerateMessageSerializationMethods(io::Printer* printer) { " return size;\n" "}\n" "\n"); - - printer->Print( - "private static final long serialVersionUID = 0L;\n"); } void ImmutableMessageGenerator:: @@ -1078,13 +1068,11 @@ GenerateEqualsAndHashCode(io::Printer* printer) { printer->Print("}\n"); } - if (PreserveUnknownFields(descriptor_)) { - // Always consider unknown fields for equality. This will sometimes return - // false for non-canonical ordering when running in LITE_RUNTIME but it's - // the best we can do. - printer->Print( + // Always consider unknown fields for equality. This will sometimes return + // false for non-canonical ordering when running in LITE_RUNTIME but it's + // the best we can do. + printer->Print( "result = result && unknownFields.equals(other.unknownFields);\n"); - } if (descriptor_->extension_range_count() > 0) { printer->Print( "result = result &&\n" @@ -1226,11 +1214,9 @@ GenerateParsingConstructor(io::Printer* printer) { "bit_field_name", GetBitFieldName(i)); } - if (PreserveUnknownFields(descriptor_)) { - printer->Print( + printer->Print( "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n" " com.google.protobuf.UnknownFieldSet.newBuilder();\n"); - } printer->Print( "try {\n"); @@ -1247,28 +1233,19 @@ GenerateParsingConstructor(io::Printer* printer) { printer->Indent(); printer->Print( - "case 0:\n" // zero signals EOF / limit reached + "case 0:\n" // zero signals EOF / limit reached " done = true;\n" - " break;\n"); - - if (PreserveUnknownFields(descriptor_)) { - printer->Print( - "default: {\n" - " if (!parseUnknownField(input, unknownFields,\n" - " extensionRegistry, tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - } else { - printer->Print( - "default: {\n" - " if (!input.skipField(tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - } + " break;\n" + "default: {\n" + " if (!parseUnknownField$suffix$(\n" + " input, unknownFields, extensionRegistry, tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n", + "suffix", + descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ? "Proto3" + : ""); for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = sorted_fields[i]; @@ -1328,10 +1305,8 @@ GenerateParsingConstructor(io::Printer* printer) { field_generators_.get(field).GenerateParsingDoneCode(printer); } - if (PreserveUnknownFields(descriptor_)) { - // Make unknown fields immutable. - printer->Print("this.unknownFields = unknownFields.build();\n"); - } + // Make unknown fields immutable. + printer->Print("this.unknownFields = unknownFields.build();\n"); // Make extensions immutable. printer->Print( diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc index 56017171..f9bbfbf4 100644 --- a/src/google/protobuf/compiler/java/java_message_builder.cc +++ b/src/google/protobuf/compiler/java/java_message_builder.cc @@ -54,8 +54,9 @@ #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/stubs/strutil.h> + namespace google { namespace protobuf { @@ -171,36 +172,25 @@ Generate(io::Printer* printer) { .GenerateBuilderMembers(printer); } - if (!PreserveUnknownFields(descriptor_)) { - printer->Print( - "public final Builder setUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return this;\n" - "}\n" - "\n" - "public final Builder mergeUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return this;\n" - "}\n" - "\n"); - } else { + bool is_proto3 = + descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; // Override methods declared in GeneratedMessage to return the concrete // generated type so callsites won't depend on GeneratedMessage. This // is needed to keep binary compatibility when we change generated code // to subclass a different GeneratedMessage class (e.g., in v3.0.0 release // we changed all generated code to subclass GeneratedMessageV3). - printer->Print( - "public final Builder setUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return super.setUnknownFields(unknownFields);\n" - "}\n" - "\n" - "public final Builder mergeUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return super.mergeUnknownFields(unknownFields);\n" - "}\n" - "\n"); - } + printer->Print( + "public final Builder setUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return super.setUnknownFields$suffix$(unknownFields);\n" + "}\n" + "\n" + "public final Builder mergeUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return super.mergeUnknownFields(unknownFields);\n" + "}\n" + "\n", + "suffix", is_proto3 ? "Proto3" : ""); printer->Print( "\n" @@ -594,10 +584,8 @@ GenerateCommonBuilderMethods(io::Printer* printer) { " this.mergeExtensionFields(other);\n"); } - if (PreserveUnknownFields(descriptor_)) { - printer->Print( - " this.mergeUnknownFields(other.unknownFields);\n"); - } + printer->Print( + " this.mergeUnknownFields(other.unknownFields);\n"); printer->Print( " onChanged();\n"); diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc index ae84db1c..baa7f872 100644 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ b/src/google/protobuf/compiler/java/java_message_field.cc @@ -150,12 +150,9 @@ GenerateInterfaceMembers(io::Printer* printer) const { // interface so that builders can choose dynamically to either return a // message or a nested builder, so that asking for the interface doesn't // cause a message to ever be built. - if (SupportFieldPresence(descriptor_->file()) || - descriptor_->containing_oneof() == NULL) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$boolean has$capitalized_name$();\n"); - } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); @@ -174,39 +171,45 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$OrBuilder " - "get$capitalized_name$OrBuilder() {\n" + "${$get$capitalized_name$OrBuilder$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } else { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $name$_ != null;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$OrBuilder " - "get$capitalized_name$OrBuilder() {\n" + "${$get$capitalized_name$OrBuilder$}$() {\n" " return get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -232,6 +235,7 @@ void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction( const char* nested_builder_case, const char* trailing_code) const { printer->Print(variables_, method_prototype); + printer->Annotate("{", "}", descriptor_); printer->Print(" {\n"); printer->Indent(); PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); @@ -267,20 +271,22 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); if (support_field_presence) { printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_builder$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } else { printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $name$Builder_ != null || $name$_ != null;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } // Field getField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public $type$ get$capitalized_name$()", + "$deprecation$public $type$ ${$get$capitalized_name$$}$()", "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n", "return $name$Builder_.getMessage();\n", NULL); @@ -288,7 +294,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)", "if (value == null) {\n" " throw new NullPointerException();\n" @@ -304,7 +310,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " $type$.Builder builderForValue)", "$name$_ = builderForValue.build();\n" @@ -318,7 +324,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder merge$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)", support_field_presence ? "if ($get_has_field_bit_builder$ &&\n" @@ -346,7 +352,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder clear$capitalized_name$()", + "$deprecation$public Builder ${$clear$capitalized_name$$}$()", "$name$_ = null;\n" "$on_changed$\n", @@ -361,14 +367,17 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" + "$deprecation$public $type$.Builder " + "${$get$capitalized_name$Builder$}$() {\n" " $set_has_field_bit_builder$\n" " $on_changed$\n" " return get$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" " if ($name$Builder_ != null) {\n" " return $name$Builder_.getMessageOrBuilder();\n" " } else {\n" @@ -376,6 +385,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " $type$.getDefaultInstance() : $name$_;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "private com.google.protobuf.SingleFieldBuilder$ver$<\n" @@ -530,30 +540,32 @@ ImmutableMessageOneofFieldGenerator:: void ImmutableMessageOneofFieldGenerator:: GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $has_oneof_case_message$;\n" - "}\n"); - } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" " }\n" " return $type$.getDefaultInstance();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" " }\n" " return $type$.getDefaultInstance();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableMessageOneofFieldGenerator:: @@ -571,19 +583,18 @@ GenerateBuilderMembers(io::Printer* printer) const { // The comments above the methods below are based on a hypothetical // field of type "Field" called "Field". - if (SupportFieldPresence(descriptor_->file())) { - // boolean hasField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $has_oneof_case_message$;\n" - "}\n"); - } + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); // Field getField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public $type$ get$capitalized_name$()", + "$deprecation$public $type$ ${$get$capitalized_name$$}$()", "if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" @@ -600,7 +611,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)", "if (value == null) {\n" " throw new NullPointerException();\n" @@ -616,7 +627,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " $type$.Builder builderForValue)", "$oneof_name$_ = builderForValue.build();\n" @@ -630,7 +641,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder merge$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)", "if ($has_oneof_case_message$ &&\n" " $oneof_name$_ != $type$.getDefaultInstance()) {\n" @@ -652,7 +663,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder clear$capitalized_name$()", + "$deprecation$public Builder ${$clear$capitalized_name$$}$()", "if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" @@ -670,12 +681,15 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" + "$deprecation$public $type$.Builder " + "${$get$capitalized_name$Builder$}$() {\n" " return get$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n" " return $name$Builder_.getMessageOrBuilder();\n" " } else {\n" @@ -685,11 +699,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " return $type$.getDefaultInstance();\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "private com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> \n" - " get$capitalized_name$FieldBuilder() {\n" + " ${$get$capitalized_name$FieldBuilder$}$() {\n" " if ($name$Builder_ == null) {\n" " if (!($has_oneof_case_message$)) {\n" " $oneof_name$_ = $type$.getDefaultInstance();\n" @@ -705,6 +720,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$;\n" " return $name$Builder_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableMessageOneofFieldGenerator:: @@ -833,31 +849,38 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" - " get$capitalized_name$OrBuilderList() {\n" + " ${$get$capitalized_name$OrBuilderList$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$(\n" " int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } @@ -883,6 +906,7 @@ void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction( const char* nested_builder_case, const char* trailing_code) const { printer->Print(variables_, method_prototype); + printer->Annotate("{", "}", descriptor_); printer->Print(" {\n"); printer->Indent(); PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); @@ -934,7 +958,8 @@ GenerateBuilderMembers(io::Printer* printer) const { // List<Field> getRepeatedFieldList() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List()", + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$()", "return java.util.Collections.unmodifiableList($name$_);\n", "return $name$Builder_.getMessageList();\n", @@ -944,7 +969,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // int getRepeatedFieldCount() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public int get$capitalized_name$Count()", + "$deprecation$public int ${$get$capitalized_name$Count$}$()", "return $name$_.size();\n", "return $name$Builder_.getCount();\n", @@ -954,7 +979,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field getRepeatedField(int index) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public $type$ get$capitalized_name$(int index)", + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index)", "return $name$_.get(index);\n", @@ -965,7 +990,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder setRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value)", "if (value == null) {\n" " throw new NullPointerException();\n" @@ -979,7 +1004,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder setRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$.Builder builderForValue)", "ensure$capitalized_name$IsMutable();\n" @@ -993,7 +1018,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addRepeatedField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value)", "if (value == null) {\n" " throw new NullPointerException();\n" @@ -1010,7 +1035,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " int index, $type$ value)", "if (value == null) {\n" @@ -1027,7 +1052,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addRepeatedField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " $type$.Builder builderForValue)", "ensure$capitalized_name$IsMutable();\n" @@ -1041,7 +1066,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " int index, $type$.Builder builderForValue)", "ensure$capitalized_name$IsMutable();\n" @@ -1055,7 +1080,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addAllRepeatedField(Iterable<Field> values) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $type$> values)", "ensure$capitalized_name$IsMutable();\n" @@ -1070,7 +1095,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder clearAllRepeatedField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder clear$capitalized_name$()", + "$deprecation$public Builder ${$clear$capitalized_name$$}$()", "$name$_ = java.util.Collections.emptyList();\n" "$clear_mutable_bit_builder$;\n" @@ -1083,7 +1108,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder removeRepeatedField(int index) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder remove$capitalized_name$(int index)", + "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)", "ensure$capitalized_name$IsMutable();\n" "$name$_.remove(index);\n" @@ -1095,14 +1120,16 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n" + "$deprecation$public $type$.Builder ${$get$capitalized_name$Builder$}$(\n" " int index) {\n" " return get$capitalized_name$FieldBuilder().getBuilder(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$(\n" " int index) {\n" " if ($name$Builder_ == null) {\n" " return $name$_.get(index);" @@ -1110,35 +1137,40 @@ GenerateBuilderMembers(io::Printer* printer) const { " return $name$Builder_.getMessageOrBuilder(index);\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" - " get$capitalized_name$OrBuilderList() {\n" + " ${$get$capitalized_name$OrBuilderList$}$() {\n" " if ($name$Builder_ != null) {\n" " return $name$Builder_.getMessageOrBuilderList();\n" " } else {\n" " return java.util.Collections.unmodifiableList($name$_);\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n" + "$deprecation$public $type$.Builder " + "${$add$capitalized_name$Builder$}$() {\n" " return get$capitalized_name$FieldBuilder().addBuilder(\n" " $type$.getDefaultInstance());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n" + "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n" " int index) {\n" " return get$capitalized_name$FieldBuilder().addBuilder(\n" " index, $type$.getDefaultInstance());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$type$.Builder> \n" - " get$capitalized_name$BuilderList() {\n" + " ${$get$capitalized_name$BuilderList$}$() {\n" " return get$capitalized_name$FieldBuilder().getBuilderList();\n" "}\n" "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" @@ -1155,6 +1187,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return $name$Builder_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutableMessageFieldGenerator:: 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 c71e9101..df3e80d4 100644 --- a/src/google/protobuf/compiler/java/java_message_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc @@ -129,16 +129,9 @@ int ImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const { void ImmutableMessageFieldLiteGenerator:: GenerateInterfaceMembers(io::Printer* printer) const { - // TODO(jonp): In the future, consider having a method specific to the - // interface so that builders can choose dynamically to either return a - // message or a nested builder, so that asking for the interface doesn't - // cause a message to ever be built. - if (SupportFieldPresence(descriptor_->file()) || - descriptor_->containing_oneof() == NULL) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$boolean has$capitalized_name$();\n"); - } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); @@ -154,25 +147,29 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } else { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $name$_ != null;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } // Field.Builder setField(Field value) @@ -226,53 +223,60 @@ GenerateBuilderMembers(io::Printer* printer) const { // boolean hasField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field getField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" " }\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder " + "${$merge$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.merge$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableMessageFieldLiteGenerator:: @@ -390,21 +394,21 @@ ImmutableMessageOneofFieldLiteGenerator:: void ImmutableMessageOneofFieldLiteGenerator:: GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $has_oneof_case_message$;\n" - "}\n"); - } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" " }\n" " return $type$.getDefaultInstance();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); @@ -457,58 +461,63 @@ GenerateBuilderMembers(io::Printer* printer) const { // The comments above the methods below are based on a hypothetical // field of type "Field" called "Field". - if (SupportFieldPresence(descriptor_->file())) { - // boolean hasField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return instance.has$capitalized_name$();\n" - "}\n"); - } + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); // Field getField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder " + "${$merge$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.merge$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableMessageOneofFieldLiteGenerator:: @@ -615,31 +624,38 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" - " get$capitalized_name$OrBuilderList() {\n" + " ${$get$capitalized_name$OrBuilderList$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$(\n" " int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); printer->Print(variables_, "private void ensure$capitalized_name$IsMutable() {\n" @@ -745,110 +761,123 @@ GenerateBuilderMembers(io::Printer* printer) const { // List<Field> getRepeatedFieldList() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList(\n" " instance.get$capitalized_name$List());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // int getRepeatedFieldCount() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}"); + printer->Annotate("{", "}", descriptor_); // Field getRepeatedField(int index) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder setRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder setRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addRepeatedField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addRepeatedField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " int index, $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(index, builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addAllRepeatedField(Iterable<Field> values) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $type$> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder clearAllRepeatedField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder removeRepeatedField(int index) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder remove$capitalized_name$(int index) {\n" + "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index) {\n" " copyOnWrite();\n" " instance.remove$capitalized_name$(index);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutableMessageFieldLiteGenerator:: diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index aad10bb1..26f16439 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -56,8 +56,9 @@ #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/stubs/strutil.h> + namespace google { namespace protobuf { @@ -124,7 +125,7 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "$deprecation$public interface $classname$OrBuilder$idend$ extends \n" + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends \n" " $extra_interfaces$\n" " com.google.protobuf.GeneratedMessageLite.\n" " ExtendableMessageOrBuilder<\n" @@ -133,19 +134,19 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), - "idend", ""); + "{", "", "}", ""); } else { printer->Print( - "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.MessageLiteOrBuilder {\n", "deprecation", descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), - "idend", ""); + "{", "", "}", ""); } - printer->Annotate("classname", "idend", descriptor_); + printer->Annotate("{", "}", descriptor_); printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { @@ -345,15 +346,15 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { } printer->Print( - "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n" - "protected final java.lang.Object dynamicMethod(\n" - " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" - " java.lang.Object arg0, java.lang.Object arg1) {\n" - " switch (method) {\n" - " case NEW_MUTABLE_INSTANCE: {\n" - " return new $classname$();\n" - " }\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n" + "protected final java.lang.Object dynamicMethod(\n" + " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" + " java.lang.Object arg0, java.lang.Object arg1) {\n" + " switch (method) {\n" + " case NEW_MUTABLE_INSTANCE: {\n" + " return new $classname$();\n" + " }\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); printer->Indent(); printer->Indent(); @@ -530,14 +531,12 @@ GenerateMessageSerializationMethods(io::Printer* printer) { } } - if (PreserveUnknownFields(descriptor_)) { - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "unknownFields.writeAsMessageSetTo(output);\n"); - } else { - printer->Print( - "unknownFields.writeTo(output);\n"); - } + if (descriptor_->options().message_set_wire_format()) { + printer->Print( + "unknownFields.writeAsMessageSetTo(output);\n"); + } else { + printer->Print( + "unknownFields.writeTo(output);\n"); } printer->Outdent(); @@ -565,14 +564,12 @@ GenerateMessageSerializationMethods(io::Printer* printer) { } } - if (PreserveUnknownFields(descriptor_)) { - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "size += unknownFields.getSerializedSizeAsMessageSet();\n"); - } else { - printer->Print( - "size += unknownFields.getSerializedSize();\n"); - } + if (descriptor_->options().message_set_wire_format()) { + printer->Print( + "size += unknownFields.getSerializedSizeAsMessageSet();\n"); + } else { + printer->Print( + "size += unknownFields.getSerializedSize();\n"); } printer->Outdent(); @@ -968,41 +965,31 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream( " done = true;\n" " break;\n"); - if (PreserveUnknownFields(descriptor_)) { - if (descriptor_->extension_range_count() > 0) { - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "default: {\n" - " if (!parseUnknownFieldAsMessageSet(\n" - " getDefaultInstanceForType(), input, extensionRegistry,\n" - " tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - } else { - printer->Print( - "default: {\n" - " if (!parseUnknownField(getDefaultInstanceForType(),\n" - " input, extensionRegistry, tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - } + if (descriptor_->extension_range_count() > 0) { + if (descriptor_->options().message_set_wire_format()) { + printer->Print( + "default: {\n" + " if (!parseUnknownFieldAsMessageSet(\n" + " getDefaultInstanceForType(), input, extensionRegistry,\n" + " tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n"); } else { printer->Print( - "default: {\n" - " if (!parseUnknownField(tag, input)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); + "default: {\n" + " if (!parseUnknownField(getDefaultInstanceForType(),\n" + " input, extensionRegistry, tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n"); } } else { printer->Print( "default: {\n" - " if (!input.skipField(tag)) {\n" + " if (!parseUnknownField(tag, input)) {\n" " done = true;\n" // it's an endgroup tag " }\n" " break;\n" diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc index bffe4f16..1673b4ee 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.cc +++ b/src/google/protobuf/compiler/java/java_name_resolver.cc @@ -33,6 +33,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/stubs/substitute.h> diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index 840252e7..074a6be8 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -190,16 +190,18 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutablePrimitiveFieldGenerator:: @@ -210,31 +212,35 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_builder$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" "$null_check$" " $set_has_field_bit_builder$\n" " $name$_ = value;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $clear_has_field_bit_builder$\n"); + printer->Annotate("{", "}", descriptor_); JavaType type = GetJavaType(descriptor_); if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) { // The default value is not a simple literal so we want to avoid executing @@ -441,19 +447,21 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($boxed_type$) $oneof_name$_;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } @@ -462,33 +470,36 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($boxed_type$) $oneof_name$_;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" "$null_check$" " $set_oneof_case_message$;\n" " $oneof_name$_ = value;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" " $oneof_name$_ = null;\n" @@ -496,6 +507,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutablePrimitiveOneofFieldGenerator:: @@ -604,19 +616,22 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$boxed_type$>\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (descriptor_->is_packed() && context_->HasGeneratedMethods(descriptor_->containing_type())) { @@ -654,22 +669,25 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$boxed_type$>\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList($name$_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" "$null_check$" " ensure$capitalized_name$IsMutable();\n" @@ -677,18 +695,20 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" "$null_check$" " ensure$capitalized_name$IsMutable();\n" " $name$_.add(value);\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $boxed_type$> values) {\n" " ensure$capitalized_name$IsMutable();\n" " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" @@ -696,14 +716,16 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ = $empty_list$;\n" " $clear_mutable_bit_builder$;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutablePrimitiveFieldGenerator:: 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 0e8e492f..f9293171 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc @@ -222,16 +222,18 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -264,32 +266,36 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutablePrimitiveFieldLiteGenerator:: @@ -482,19 +488,21 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($boxed_type$) $oneof_name$_;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -520,32 +528,36 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutablePrimitiveOneofFieldLiteGenerator:: @@ -634,21 +646,24 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$boxed_type$>\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $repeated_get$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); - if (descriptor_->options().packed() && + if (descriptor_->is_packed() && context_->HasGeneratedMethods(descriptor_->containing_type())) { printer->Print(variables_, "private int $name$MemoizedSerializedSize = -1;\n"); @@ -697,50 +712,57 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$boxed_type$>\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList(\n" " instance.get$capitalized_name$List());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $boxed_type$> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutablePrimitiveFieldLiteGenerator:: @@ -829,7 +851,7 @@ GenerateParsingDoneCode(io::Printer* printer) const { void RepeatedImmutablePrimitiveFieldLiteGenerator:: GenerateSerializationCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { // We invoke getSerializedSize in writeTo for messages that have packed // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods. // That makes it safe to rely on the memoized size here. @@ -870,7 +892,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print( "size += dataSize;\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (!get$capitalized_name$List().isEmpty()) {\n" " size += $tag_size$;\n" @@ -883,7 +905,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } // cache the data size for packed fields. - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n"); } diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc index 5c2900ce..2b6e9381 100644 --- a/src/google/protobuf/compiler/java/java_string_field.cc +++ b/src/google/protobuf/compiler/java/java_string_field.cc @@ -217,14 +217,15 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref = $name$_;\n" " if (ref instanceof java.lang.String) {\n" " return (java.lang.String) ref;\n" @@ -232,6 +233,7 @@ GenerateMembers(io::Printer* printer) const { " com.google.protobuf.ByteString bs = \n" " (com.google.protobuf.ByteString) ref;\n" " java.lang.String s = bs.toStringUtf8();\n"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " $name$_ = s;\n"); @@ -248,7 +250,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref = $name$_;\n" " if (ref instanceof java.lang.String) {\n" " com.google.protobuf.ByteString b = \n" @@ -260,6 +262,7 @@ GenerateMembers(io::Printer* printer) const { " return (com.google.protobuf.ByteString) ref;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableStringFieldGenerator:: @@ -269,19 +272,21 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_builder$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref = $name$_;\n" " if (!(ref instanceof java.lang.String)) {\n" " com.google.protobuf.ByteString bs =\n" " (com.google.protobuf.ByteString) ref;\n" " java.lang.String s = bs.toStringUtf8();\n"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " $name$_ = s;\n"); @@ -301,7 +306,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref = $name$_;\n" " if (ref instanceof String) {\n" " com.google.protobuf.ByteString b = \n" @@ -313,10 +318,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " return (com.google.protobuf.ByteString) ref;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" "$null_check$" " $set_has_field_bit_builder$\n" @@ -324,10 +330,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $clear_has_field_bit_builder$\n"); + printer->Annotate("{", "}", descriptor_); // The default value is not a simple literal so we want to avoid executing // it multiple times. Instead, get the default out of the default instance. printer->Print(variables_, @@ -339,9 +347,10 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" "$null_check$"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); @@ -482,14 +491,15 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = $oneof_name$_;\n" @@ -500,6 +510,7 @@ GenerateMembers(io::Printer* printer) const { " com.google.protobuf.ByteString bs = \n" " (com.google.protobuf.ByteString) ref;\n" " java.lang.String s = bs.toStringUtf8();\n"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " if ($has_oneof_case_message$) {\n" @@ -519,7 +530,7 @@ GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = $oneof_name$_;\n" @@ -536,6 +547,7 @@ GenerateMembers(io::Printer* printer) const { " return (com.google.protobuf.ByteString) ref;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableStringOneofFieldGenerator:: @@ -543,14 +555,15 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = $oneof_name$_;\n" @@ -560,6 +573,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " (com.google.protobuf.ByteString) ref;\n" " java.lang.String s = bs.toStringUtf8();\n" " if ($has_oneof_case_message$) {\n"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " $oneof_name$_ = s;\n"); @@ -580,7 +594,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = $oneof_name$_;\n" @@ -597,10 +611,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " return (com.google.protobuf.ByteString) ref;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" "$null_check$" " $set_oneof_case_message$;\n" @@ -608,9 +623,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" " $oneof_name$_ = null;\n" @@ -618,12 +634,14 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" "$null_check$"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); @@ -744,25 +762,30 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ProtocolStringList\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes(int index) {\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return $name$_.getByteString(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutableStringFieldGenerator:: @@ -794,28 +817,33 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ProtocolStringList\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return $name$_.getUnmodifiableView();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes(int index) {\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return $name$_.getByteString(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, java.lang.String value) {\n" "$null_check$" " ensure$capitalized_name$IsMutable();\n" @@ -823,9 +851,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " java.lang.String value) {\n" "$null_check$" " ensure$capitalized_name$IsMutable();\n" @@ -833,9 +862,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<java.lang.String> values) {\n" " ensure$capitalized_name$IsMutable();\n" " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" @@ -843,20 +873,23 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ = $empty_list$;\n" " $clear_mutable_bit_builder$;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" "$null_check$"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); 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 7e3ad1d0..adda307c 100644 --- a/src/google/protobuf/compiler/java/java_string_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc @@ -71,7 +71,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); (*variables)["default_init"] = "= " + ImmutableDefaultValue(descriptor, name_resolver); - (*variables)["capitalized_type"] = "String"; + (*variables)["capitalized_type"] = "java.lang.String"; (*variables)["tag"] = SimpleItoa(static_cast<int32>(WireFormat::MakeTag(descriptor))); (*variables)["tag_size"] = SimpleItoa( @@ -192,22 +192,25 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " return com.google.protobuf.ByteString.copyFromUtf8($name$_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -246,48 +249,54 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " return instance.get$capitalized_name$Bytes();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Bytes(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableStringFieldLiteGenerator:: @@ -324,7 +333,7 @@ void ImmutableStringFieldLiteGenerator:: GenerateParsingCode(io::Printer* printer) const { if (CheckUtf8(descriptor_)) { printer->Print(variables_, - "String s = input.readStringRequireUtf8();\n" + "java.lang.String s = input.readStringRequireUtf8();\n" "$set_has_field_bit_message$\n" "$name$_ = s;\n"); } else { @@ -333,7 +342,7 @@ GenerateParsingCode(io::Printer* printer) const { // spurious intermediary ByteString allocations, cutting overall allocations // in half. printer->Print(variables_, - "String s = input.readString();\n" + "java.lang.String s = input.readString();\n" "$set_has_field_bit_message$\n" "$name$_ = s;\n"); } @@ -410,54 +419,60 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.String ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = (java.lang.String) $oneof_name$_;\n" " }\n" " return ref;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.String ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = (java.lang.String) $oneof_name$_;\n" " }\n" " return com.google.protobuf.ByteString.copyFromUtf8(ref);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "private void set$capitalized_name$(\n" + "private void ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" "$null_check$" " $set_oneof_case_message$;\n" " $oneof_name$_ = value;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "private void clear$capitalized_name$() {\n" + "private void ${$clear$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" " $oneof_name$_ = null;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "private void set$capitalized_name$Bytes(\n" + "private void ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" "$null_check$"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); @@ -474,48 +489,54 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " return instance.get$capitalized_name$Bytes();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Bytes(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableStringOneofFieldLiteGenerator:: @@ -529,7 +550,7 @@ void ImmutableStringOneofFieldLiteGenerator:: GenerateParsingCode(io::Printer* printer) const { if (CheckUtf8(descriptor_)) { printer->Print(variables_, - "String s = input.readStringRequireUtf8();\n" + "java.lang.String s = input.readStringRequireUtf8();\n" "$set_oneof_case_message$;\n" "$oneof_name$_ = s;\n"); } else { @@ -538,7 +559,7 @@ GenerateParsingCode(io::Printer* printer) const { // spurious intermediary ByteString allocations, cutting overall allocations // in half. printer->Print(variables_, - "String s = input.readString();\n" + "java.lang.String s = input.readString();\n" "$set_oneof_case_message$;\n" "$oneof_name$_ = s;\n"); } @@ -597,7 +618,7 @@ void RepeatedImmutableStringFieldLiteGenerator:: GenerateInterfaceMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$java.util.List<String>\n" + "$deprecation$java.util.List<java.lang.String>\n" " get$capitalized_name$List();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -615,30 +636,37 @@ GenerateInterfaceMembers(io::Printer* printer) const { void RepeatedImmutableStringFieldLiteGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private com.google.protobuf.Internal.ProtobufList<String> $name$_;\n"); + "private com.google.protobuf.Internal.ProtobufList<java.lang.String> " + "$name$_;\n"); PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<String> get$capitalized_name$List() {\n" - " return $name$_;\n" // note: unmodifiable list + "$deprecation$public java.util.List<java.lang.String> " + "${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes(int index) {\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return com.google.protobuf.ByteString.copyFromUtf8(\n" " $name$_.get(index));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); printer->Print(variables_, "private void ensure$capitalized_name$IsMutable() {\n" @@ -697,67 +725,77 @@ void RepeatedImmutableStringFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<String>\n" - " get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<java.lang.String>\n" + " ${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList(\n" " instance.get$capitalized_name$List());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes(int index) {\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return instance.get$capitalized_name$Bytes(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, java.lang.String value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " java.lang.String value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<java.lang.String> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$Bytes(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutableStringFieldLiteGenerator:: @@ -787,14 +825,14 @@ void RepeatedImmutableStringFieldLiteGenerator:: GenerateParsingCode(io::Printer* printer) const { if (CheckUtf8(descriptor_)) { printer->Print(variables_, - "String s = input.readStringRequireUtf8();\n"); + "java.lang.String s = input.readStringRequireUtf8();\n"); } else { // Lite runtime should attempt to reduce allocations by attempting to // construct the string directly from the input stream buffer. This avoids // spurious intermediary ByteString allocations, cutting overall allocations // in half. printer->Print(variables_, - "String s = input.readString();\n"); + "java.lang.String s = input.readString();\n"); } printer->Print(variables_, "if (!$is_mutable$) {\n" @@ -868,7 +906,7 @@ GenerateHashCode(io::Printer* printer) const { } string RepeatedImmutableStringFieldLiteGenerator::GetBoxedType() const { - return "String"; + return "java.lang.String"; } } // namespace java diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index 2d86d1c8..73d32762 100755 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -143,12 +143,16 @@ bool IsReserved(const string& ident) { return false; } +bool StrEndsWith(StringPiece sp, StringPiece x) { + return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x; +} + // Returns a copy of |filename| with any trailing ".protodevel" or ".proto // suffix stripped. // TODO(haberman): Unify with copy in compiler/cpp/internal/helpers.cc. string StripProto(const string& filename) { - const char* suffix = HasSuffixString(filename, ".protodevel") - ? ".protodevel" : ".proto"; + const char* suffix = + StrEndsWith(filename, ".protodevel") ? ".protodevel" : ".proto"; return StripSuffixString(filename, suffix); } @@ -757,8 +761,22 @@ string DoubleToString(double value) { return PostProcessFloat(result); } +// Return true if this is an integral field that should be represented as string +// in JS. +bool IsIntegralFieldWithStringJSType(const FieldDescriptor* field) { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT64: + // The default value of JSType is JS_NORMAL, which behaves the same as + // JS_NUMBER. + return field->options().jstype() == google::protobuf::FieldOptions::JS_STRING; + default: + return false; + } +} + string MaybeNumberString(const FieldDescriptor* field, const string& orig) { - return orig; + return IsIntegralFieldWithStringJSType(field) ? ("\"" + orig + "\"") : orig; } string JSFieldDefault(const FieldDescriptor* field) { @@ -857,7 +875,7 @@ string ProtoTypeName(const GeneratorOptions& options, } string JSIntegerTypeName(const FieldDescriptor* field) { - return "number"; + return IsIntegralFieldWithStringJSType(field) ? "string" : "number"; } string JSStringTypeName(const GeneratorOptions& options, @@ -1034,8 +1052,7 @@ string JSBinaryReaderMethodType(const FieldDescriptor* field) { if (name[0] >= 'a' && name[0] <= 'z') { name[0] = (name[0] - 'a') + 'A'; } - - return name; + return IsIntegralFieldWithStringJSType(field) ? (name + "String") : name; } string JSBinaryReadWriteMethodName(const FieldDescriptor* field, @@ -1245,13 +1262,6 @@ string FieldComments(const FieldDescriptor* field, BytesMode bytes_mode) { " * You should avoid comparisons like {@code val === true/false} in " "those cases.\n"; } - if (field->is_repeated()) { - comments += - " * If you change this array by adding, removing or replacing " - "elements, or if you\n" - " * replace the array itself, then you must call the setter to " - "update it.\n"; - } if (field->type() == FieldDescriptor::TYPE_BYTES && bytes_mode == BYTES_U8) { comments += " * Note that Uint8Array is not supported on all browsers.\n" @@ -1324,7 +1334,7 @@ bool IsExtendable(const Descriptor* desc) { // Returns the max index in the underlying data storage array beyond which the // extension object is used. string GetPivot(const Descriptor* desc) { - static const int kDefaultPivot = (1 << 29); // max field number (29 bits) + static const int kDefaultPivot = 500; // Find the max field number int max_field_number = 0; @@ -1336,7 +1346,7 @@ string GetPivot(const Descriptor* desc) { } int pivot = -1; - if (IsExtendable(desc)) { + if (IsExtendable(desc) || (max_field_number >= kDefaultPivot)) { pivot = ((max_field_number + 1) < kDefaultPivot) ? (max_field_number + 1) : kDefaultPivot; } @@ -1508,6 +1518,10 @@ void Generator::GenerateHeader(const GeneratorOptions& options, printer->Print("/**\n" " * @fileoverview\n" " * @enhanceable\n" + " * @suppress {messageConventions} JS Compiler reports an " + "error if a variable or\n" + " * field starts with 'MSG_' and isn't a translatable " + "message.\n" " * @public\n" " */\n" "// GENERATED CODE -- DO NOT EDIT!\n" @@ -1699,18 +1713,16 @@ void Generator::GenerateRequiresImpl(const GeneratorOptions& options, bool require_jspb, bool require_extension, bool require_map) const { if (require_jspb) { - printer->Print( - "goog.require('jspb.Message');\n" - "goog.require('jspb.BinaryReader');\n" - "goog.require('jspb.BinaryWriter');\n"); + required->insert("jspb.Message"); + required->insert("jspb.BinaryReader"); + required->insert("jspb.BinaryWriter"); } if (require_extension) { - printer->Print("goog.require('jspb.ExtensionFieldBinaryInfo');\n"); - printer->Print( - "goog.require('jspb.ExtensionFieldInfo');\n"); + required->insert("jspb.ExtensionFieldBinaryInfo"); + required->insert("jspb.ExtensionFieldInfo"); } if (require_map) { - printer->Print("goog.require('jspb.Map');\n"); + required->insert("jspb.Map"); } std::set<string>::iterator it; @@ -2038,6 +2050,7 @@ void Generator::GenerateClassToObject(const GeneratorOptions& options, " * http://goto/soy-param-migration\n" " * @param {!$classname$} msg The msg instance to transform.\n" " * @return {!Object}\n" + " * @suppress {unusedLocalVariables} f is only used for nested messages\n" " */\n" "$classname$.toObject = function(includeInstance, msg) {\n" " var f, obj = {", @@ -2126,7 +2139,8 @@ void Generator::GenerateFieldValueExpression(io::Printer* printer, "obj", obj_reference); } } else { - printer->Print("jspb.Message.getField($obj$, $index$)", + printer->Print("jspb.Message.get$cardinality$Field($obj$, $index$)", + "cardinality", field->is_repeated() ? "Repeated" : "", "index", JSFieldIndex(field), "obj", obj_reference); } @@ -2334,7 +2348,6 @@ void GenerateBytesWrapper(const GeneratorOptions& options, "defname", JSGetterName(options, field, BYTES_DEFAULT)); } - void Generator::GenerateClassField(const GeneratorOptions& options, io::Printer* printer, const FieldDescriptor* field) const { @@ -2464,7 +2477,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, // Simple (primitive) field, either singular or repeated. // TODO(b/26173701): Always use BYTES_DEFAULT for the getter return type; - // at this point we "lie" to non-binary users and tell the the return + // at this point we "lie" to non-binary users and tell the return // type is always base64 string, pending a LSC to migrate to typed getters. BytesMode bytes_mode = field->type() == FieldDescriptor::TYPE_BYTES && !options.binary ? @@ -2911,6 +2924,7 @@ void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options, " * format), writing to the given BinaryWriter.\n" " * @param {!$class$} message\n" " * @param {!jspb.BinaryWriter} writer\n" + " * @suppress {unusedLocalVariables} f is only used for nested messages\n" " */\n" "$class$.serializeBinaryToWriter = function(message, " "writer) {\n" @@ -2983,7 +2997,13 @@ void Generator::GenerateClassSerializeBinaryField( case FieldDescriptor::CPPTYPE_INT64: case FieldDescriptor::CPPTYPE_UINT32: case FieldDescriptor::CPPTYPE_UINT64: { - { + if (IsIntegralFieldWithStringJSType(field)) { + // We can use `parseInt` here even though it will not be precise for + // 64-bit quantities because we are only testing for zero/nonzero, + // and JS numbers (64-bit floating point values, i.e., doubles) are + // integer-precise in the range that includes zero. + printer->Print(" if (parseInt(f, 10) !== 0) {\n"); + } else { printer->Print(" if (f !== 0) {\n"); } break; @@ -3307,7 +3327,8 @@ void Generator::GenerateFile(const GeneratorOptions& options, printer->Print( "var $alias$ = require('$file$');\n", "alias", ModuleAlias(name), - "file", GetRootPath(file->name(), name) + GetJSFilename(options, name)); + "file", + GetRootPath(file->name(), name) + GetJSFilename(options, name)); } } diff --git a/src/google/protobuf/compiler/js/well_known_types/any.js b/src/google/protobuf/compiler/js/well_known_types/any.js index 22f18919..d7ca6e3a 100644 --- a/src/google/protobuf/compiler/js/well_known_types/any.js +++ b/src/google/protobuf/compiler/js/well_known_types/any.js @@ -69,7 +69,7 @@ proto.google.protobuf.Any.prototype.pack = function(serialized, name, * the binary data properly. * @param {string} name The expected type name of this message object. * @return {?T} If the name matched the expected name, returns the deserialized - * object, otherwise returns undefined. + * object, otherwise returns null. */ proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) { if (this.getTypeName() == name) { diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index 8b7a6146..cc660f4a 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -40,6 +40,7 @@ #endif #include <vector> + #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/logging.h> @@ -52,6 +53,7 @@ #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/descriptor.h> +#include <google/protobuf/text_format.h> #include <google/protobuf/stubs/substitute.h> #include <gtest/gtest.h> @@ -136,11 +138,48 @@ void MockCodeGenerator::ExpectGenerated( } } +namespace { +void CheckSingleAnnotation(const string& expected_file, + const string& expected_text, + const string& file_content, + const GeneratedCodeInfo::Annotation& annotation) { + EXPECT_EQ(expected_file, annotation.source_file()); + ASSERT_GE(file_content.size(), annotation.begin()); + ASSERT_GE(file_content.size(), annotation.end()); + ASSERT_LE(annotation.begin(), annotation.end()); + EXPECT_EQ(expected_text.size(), annotation.end() - annotation.begin()); + EXPECT_EQ(expected_text, + file_content.substr(annotation.begin(), expected_text.size())); +} +} // anonymous namespace + +void MockCodeGenerator::CheckGeneratedAnnotations( + const string& name, const string& file, const string& output_directory) { + string file_content; + GOOGLE_CHECK_OK( + File::GetContents(output_directory + "/" + GetOutputFileName(name, file), + &file_content, true)); + string meta_content; + GOOGLE_CHECK_OK(File::GetContents( + output_directory + "/" + GetOutputFileName(name, file) + ".meta", + &meta_content, true)); + GeneratedCodeInfo annotations; + GOOGLE_CHECK(TextFormat::ParseFromString(meta_content, &annotations)); + ASSERT_EQ(3, annotations.annotation_size()); + CheckSingleAnnotation("first_annotation", "first", file_content, + annotations.annotation(0)); + CheckSingleAnnotation("second_annotation", "second", file_content, + annotations.annotation(1)); + CheckSingleAnnotation("third_annotation", "third", file_content, + annotations.annotation(2)); +} + bool MockCodeGenerator::Generate( const FileDescriptor* file, const string& parameter, GeneratorContext* context, string* error) const { + bool annotate = false; for (int i = 0; i < file->message_type_count(); i++) { if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) { string command = StripPrefixString(file->message_type(i)->name(), @@ -169,6 +208,8 @@ bool MockCodeGenerator::Generate( std::cerr << "Saw json_name: " << field_descriptor_proto.has_json_name() << std::endl; abort(); + } else if (command == "Annotate") { + annotate = true; } else if (command == "ShowVersionNumber") { Version compiler_version; context->GetCompilerVersion(&compiler_version); @@ -219,16 +260,40 @@ bool MockCodeGenerator::Generate( google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( context->Open(GetOutputFileName(name_, file))); - io::Printer printer(output.get(), '$'); - printer.PrintRaw(GetOutputFileContent(name_, parameter, - file, context)); + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( + &annotations); + io::Printer printer(output.get(), '$', + annotate ? &annotation_collector : NULL); + printer.PrintRaw(GetOutputFileContent(name_, parameter, file, context)); + string annotate_suffix = "_annotation"; + if (annotate) { + printer.Print("$p$", "p", "first"); + printer.Annotate("p", "first" + annotate_suffix); + } printer.PrintRaw(kFirstInsertionPoint); + if (annotate) { + printer.Print("$p$", "p", "second"); + printer.Annotate("p", "second" + annotate_suffix); + } printer.PrintRaw(kSecondInsertionPoint); + if (annotate) { + printer.Print("$p$", "p", "third"); + printer.Annotate("p", "third" + annotate_suffix); + } if (printer.failed()) { *error = "MockCodeGenerator detected write error."; return false; } + if (annotate) { + google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> meta_output( + context->Open(GetOutputFileName(name_, file) + ".meta")); + if (!TextFormat::Print(annotations, meta_output.get())) { + *error = "MockCodeGenerator couldn't write .meta"; + return false; + } + } } return true; diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h index e1665f88..cdd9138c 100644 --- a/src/google/protobuf/compiler/mock_code_generator.h +++ b/src/google/protobuf/compiler/mock_code_generator.h @@ -68,6 +68,8 @@ namespace compiler { // printing "Saw message type MockCodeGenerator_HasSourceCodeInfo: FOO." to // stderr, where FOO is "1" if the supplied FileDescriptorProto has source // code info, and "0" otherwise. +// MockCodeGenerator_Annotate: Generate() will add annotations to its output +// that can later be verified with CheckGeneratedAnnotations. class MockCodeGenerator : public CodeGenerator { public: MockCodeGenerator(const string& name); @@ -88,6 +90,12 @@ class MockCodeGenerator : public CodeGenerator { const string& parsed_file_list, const string& output_directory); + // Checks that the correct text ranges were annotated by the + // MockCodeGenerator_Annotate directive. + static void CheckGeneratedAnnotations(const string& name, + const string& file, + const string& output_directory); + // Get the name of the file which would be written by the given generator. static string GetOutputFileName(const string& generator_name, const FileDescriptor* file); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 72b5d5f5..54dc7455 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -50,7 +50,7 @@ #include <google/protobuf/stubs/io_win32.h> #include <google/protobuf/stubs/strutil.h> -#if defined(_WIN32) +#if defined(_MSC_VER) // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. using google::protobuf::internal::win32::open; diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 1a409566..bb4a44c3 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -664,7 +664,7 @@ bool Parser::ParseMessageDefinition( namespace { -const int kMaxExtensionRangeSentinel = -1; +const int kMaxRangeSentinel = -1; bool IsMessageSetWireFormatMessage(const DescriptorProto& message) { const MessageOptions& options = message.options(); @@ -688,12 +688,27 @@ void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) { kint32max : FieldDescriptor::kMaxNumber + 1; for (int i = 0; i < message->extension_range_size(); ++i) { - if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) { + if (message->extension_range(i).end() == kMaxRangeSentinel) { message->mutable_extension_range(i)->set_end(max_extension_number); } } } +// Modifies any reserved ranges that specified 'max' as the end of the +// reserved range, and sets them to the type-specific maximum. The actual max +// tag number can only be determined after all options have been parsed. +void AdjustReservedRangesWithMaxEndNumber(DescriptorProto* message) { + const bool is_message_set = IsMessageSetWireFormatMessage(*message); + const int max_field_number = is_message_set ? + kint32max : + FieldDescriptor::kMaxNumber + 1; + for (int i = 0; i < message->reserved_range_size(); ++i) { + if (message->reserved_range(i).end() == kMaxRangeSentinel) { + message->mutable_reserved_range(i)->set_end(max_field_number); + } + } +} + } // namespace bool Parser::ParseMessageBlock(DescriptorProto* message, @@ -717,6 +732,9 @@ bool Parser::ParseMessageBlock(DescriptorProto* message, if (message->extension_range_size() > 0) { AdjustExtensionRangesWithMaxEndNumber(message); } + if (message->reserved_range_size() > 0) { + AdjustReservedRangesWithMaxEndNumber(message); + } return true; } @@ -1429,6 +1447,8 @@ bool Parser::ParseExtensions(DescriptorProto* message, // Parse the declaration. DO(Consume("extensions")); + int old_range_size = message->extension_range_size(); + do { // Note that kExtensionRangeFieldNumber was already pushed by the parent. LocationRecorder location(extensions_location, @@ -1455,7 +1475,7 @@ bool Parser::ParseExtensions(DescriptorProto* message, // Set to the sentinel value - 1 since we increment the value below. // The actual value of the end of the range should be set with // AdjustExtensionRangesWithMaxEndNumber. - end = kMaxExtensionRangeSentinel - 1; + end = kMaxRangeSentinel - 1; } else { DO(ConsumeInteger(&end, "Expected integer.")); } @@ -1475,12 +1495,36 @@ bool Parser::ParseExtensions(DescriptorProto* message, range->set_end(end); } while (TryConsume(",")); + if (LookingAt("[")) { + LocationRecorder location( + extensions_location, + DescriptorProto::ExtensionRange::kOptionsFieldNumber); + + DO(Consume("[")); + + // Parse extension range options in the first range. + ExtensionRangeOptions* options = + message->mutable_extension_range(old_range_size)->mutable_options(); + do { + DO(ParseOption(options, location, containing_file, OPTION_ASSIGNMENT)); + } while (TryConsume(",")); + + DO(Consume("]")); + + // Then copy the extension range options to all of the other ranges we've + // parsed. + for (int i = old_range_size + 1; i < message->extension_range_size(); i++) { + message->mutable_extension_range(i)->mutable_options() + ->CopyFrom(*options); + } + } + DO(ConsumeEndOfDeclaration(";", &extensions_location)); return true; } -// This is similar to extension range parsing, except that "max" is not -// supported, and accepts field name literals. +// This is similar to extension range parsing, except that it accepts field +// name literals. bool Parser::ParseReserved(DescriptorProto* message, const LocationRecorder& message_location) { // Parse the declaration. @@ -1528,7 +1572,14 @@ bool Parser::ParseReservedNumbers(DescriptorProto* message, if (TryConsume("to")) { LocationRecorder end_location( location, DescriptorProto::ReservedRange::kEndFieldNumber); - DO(ConsumeInteger(&end, "Expected integer.")); + if (TryConsume("max")) { + // Set to the sentinel value - 1 since we increment the value below. + // The actual value of the end of the range should be set with + // AdjustExtensionRangesWithMaxEndNumber. + end = kMaxRangeSentinel - 1; + } else { + DO(ConsumeInteger(&end, "Expected integer.")); + } } else { LocationRecorder end_location( location, DescriptorProto::ReservedRange::kEndFieldNumber); diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index d5e31325..97831f71 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -663,7 +663,7 @@ TEST_F(ParseMessageTest, ReservedRange) { ExpectParsesTo( "message TestMessage {\n" " required int32 foo = 1;\n" - " reserved 2, 15, 9 to 11, 3;\n" + " reserved 2, 15, 9 to 11, 3, 20 to max;\n" "}\n", "message_type {" @@ -673,6 +673,29 @@ TEST_F(ParseMessageTest, ReservedRange) { " reserved_range { start:15 end:16 }" " reserved_range { start:9 end:12 }" " reserved_range { start:3 end:4 }" + " reserved_range { start:20 end:536870912 }" + "}"); +} + +TEST_F(ParseMessageTest, ReservedRangeOnMessageSet) { + ExpectParsesTo( + "message TestMessage {\n" + " option message_set_wire_format = true;\n" + " reserved 20 to max;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"message_set_wire_format\"" + " is_extension: false" + " }" + " identifier_value: \"true\"" + " }" + " }" + " reserved_range { start:20 end:2147483647 }" "}"); } @@ -703,6 +726,30 @@ TEST_F(ParseMessageTest, ExtensionRange) { "}"); } +TEST_F(ParseMessageTest, ExtensionRangeWithOptions) { + ExpectParsesTo( + "message TestMessage {\n" + " extensions 10 to 19 [(i) = 5];\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " extension_range {" + " start:10" + " end:20" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + "}"); +} + TEST_F(ParseMessageTest, CompoundExtensionRange) { ExpectParsesTo( "message TestMessage {\n" @@ -719,6 +766,82 @@ TEST_F(ParseMessageTest, CompoundExtensionRange) { "}"); } +TEST_F(ParseMessageTest, CompoundExtensionRangeWithOptions) { + ExpectParsesTo( + "message TestMessage {\n" + " extensions 2, 15, 9 to 11, 100 to max, 3 [(i) = 5];\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " extension_range {" + " start:2" + " end:3" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + " extension_range {" + " start:15" + " end:16" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + " extension_range {" + " start:9" + " end:12" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + " extension_range {" + " start:100" + " end:536870912" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + " extension_range {" + " start:3" + " end:4" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + "}"); +} + TEST_F(ParseMessageTest, LargerMaxForMessageSetWireFormatMessages) { // Messages using the message_set_wire_format option can accept larger // extension numbers, as the numbers are not encoded as int32 field values @@ -1368,12 +1491,12 @@ TEST_F(ParseErrorTest, EnumValueMissingNumber) { // ------------------------------------------------------------------- // Reserved field number errors -TEST_F(ParseErrorTest, ReservedMaxNotAllowed) { +TEST_F(ParseErrorTest, ReservedStandaloneMaxNotAllowed) { ExpectHasErrors( "message Foo {\n" - " reserved 10 to max;\n" + " reserved max;\n" "}\n", - "1:17: Expected integer.\n"); + "1:11: Expected field name or number range.\n"); } TEST_F(ParseErrorTest, ReservedMixNameAndNumber) { diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index e8ffbb51..cb5e37bb 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -49,7 +49,7 @@ #include <google/protobuf/descriptor.h> #include <google/protobuf/io/zero_copy_stream_impl.h> -#if defined(_WIN32) +#if defined(_MSC_VER) // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. using google::protobuf::internal::win32::setmode; @@ -126,6 +126,7 @@ bool GenerateCode(const CodeGeneratorRequest& request, GeneratorResponseContext context( request.compiler_version(), response, parsed_files); + string error; bool succeeded = generator.GenerateAll( parsed_files, request.parameter(), &context, &error); diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 516a5878..07883a37 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -20,13 +20,25 @@ namespace google { namespace protobuf { namespace compiler { -class VersionDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Version> { +class VersionDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Version> + _instance; } _Version_default_instance_; -class CodeGeneratorRequestDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorRequest> { +class CodeGeneratorRequestDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorRequest> + _instance; } _CodeGeneratorRequest_default_instance_; -class CodeGeneratorResponse_FileDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse_File> { +class CodeGeneratorResponse_FileDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse_File> + _instance; } _CodeGeneratorResponse_File_default_instance_; -class CodeGeneratorResponseDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse> { +class CodeGeneratorResponseDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse> + _instance; } _CodeGeneratorResponse_default_instance_; namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto { @@ -39,23 +51,23 @@ namespace { } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::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 }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _internal_metadata_), ~0u, // no _extensions_ @@ -103,8 +115,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { 0, ~0u, }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, 9, sizeof(Version)}, { 13, 22, sizeof(CodeGeneratorRequest)}, { 26, 34, sizeof(CodeGeneratorResponse_File)}, @@ -140,28 +151,20 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _Version_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; - _CodeGeneratorRequest_default_instance_.Shutdown(); - delete file_level_metadata[1].reflection; - _CodeGeneratorResponse_File_default_instance_.Shutdown(); - delete file_level_metadata[2].reflection; - _CodeGeneratorResponse_default_instance_.Shutdown(); - delete file_level_metadata[3].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); ::google::protobuf::protobuf_google_2fprotobuf_2fdescriptor_2eproto::InitDefaults(); - _Version_default_instance_.DefaultConstruct(); - _CodeGeneratorRequest_default_instance_.DefaultConstruct(); - _CodeGeneratorResponse_File_default_instance_.DefaultConstruct(); - _CodeGeneratorResponse_default_instance_.DefaultConstruct(); - _CodeGeneratorRequest_default_instance_.get_mutable()->compiler_version_ = const_cast< ::google::protobuf::compiler::Version*>( + _Version_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Version_default_instance_);_CodeGeneratorRequest_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_CodeGeneratorRequest_default_instance_);_CodeGeneratorResponse_File_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_CodeGeneratorResponse_File_default_instance_);_CodeGeneratorResponse_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_CodeGeneratorResponse_default_instance_);_CodeGeneratorRequest_default_instance_._instance.get_mutable()->compiler_version_ = const_cast< ::google::protobuf::compiler::Version*>( ::google::protobuf::compiler::Version::internal_default_instance()); } @@ -172,7 +175,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n%google/protobuf/compiler/plugin.proto\022" "\030google.protobuf.compiler\032 google/protob" "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030" @@ -195,7 +198,6 @@ void AddDescriptorsImpl() { ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes); ::google::protobuf::protobuf_google_2fprotobuf_2fdescriptor_2eproto::AddDescriptors(); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -288,11 +290,16 @@ Version* Version::New(::google::protobuf::Arena* arena) const { void Version::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.Version) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + if (has_suffix()) { GOOGLE_DCHECK(!suffix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*suffix_.UnsafeRawStringPointer())->clear(); } - if (_has_bits_[0 / 32] & 14u) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 14u) { ::memset(&major_, 0, static_cast<size_t>( reinterpret_cast<char*>(&patch_) - reinterpret_cast<char*>(&major_)) + sizeof(patch_)); @@ -314,7 +321,7 @@ bool Version::MergePartialFromCodedStream( // optional int32 major = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { set_has_major(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -328,7 +335,7 @@ bool Version::MergePartialFromCodedStream( // optional int32 minor = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { set_has_minor(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -342,7 +349,7 @@ bool Version::MergePartialFromCodedStream( // optional int32 patch = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { + static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) { set_has_patch(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -356,7 +363,7 @@ bool Version::MergePartialFromCodedStream( // optional string suffix = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_suffix())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -371,13 +378,11 @@ bool Version::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -425,7 +430,7 @@ void Version::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.Version) } @@ -466,7 +471,7 @@ void Version::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.Version) return target; @@ -479,7 +484,7 @@ size_t Version::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (_has_bits_[0 / 32] & 15u) { // optional string suffix = 4; @@ -582,13 +587,14 @@ void Version::Swap(Version* other) { InternalSwap(other); } void Version::InternalSwap(Version* other) { + using std::swap; suffix_.Swap(&other->suffix_); - std::swap(major_, other->major_); - std::swap(minor_, other->minor_); - std::swap(patch_, other->patch_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(major_, other->major_); + swap(minor_, other->minor_); + swap(patch_, other->patch_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Version::GetMetadata() const { @@ -786,9 +792,7 @@ CodeGeneratorRequest::~CodeGeneratorRequest() { void CodeGeneratorRequest::SharedDtor() { parameter_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete compiler_version_; - } + if (this != internal_default_instance()) delete compiler_version_; } void CodeGeneratorRequest::SetCachedSize(int size) const { @@ -816,14 +820,19 @@ CodeGeneratorRequest* CodeGeneratorRequest::New(::google::protobuf::Arena* arena void CodeGeneratorRequest::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + file_to_generate_.Clear(); proto_file_.Clear(); - if (_has_bits_[0 / 32] & 3u) { - if (has_parameter()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!parameter_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*parameter_.UnsafeRawStringPointer())->clear(); } - if (has_compiler_version()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(compiler_version_ != NULL); compiler_version_->::google::protobuf::compiler::Version::Clear(); } @@ -845,7 +854,7 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( // repeated string file_to_generate = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->add_file_to_generate())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -862,7 +871,7 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( // optional string parameter = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_parameter())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -878,7 +887,7 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( // optional .google.protobuf.compiler.Version compiler_version = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_compiler_version())); } else { @@ -890,7 +899,7 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( // repeated .google.protobuf.FileDescriptorProto proto_file = 15; case 15: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(122u)) { + static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_proto_file())); } else { @@ -901,13 +910,11 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -963,7 +970,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorRequest) } @@ -1014,7 +1021,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorRequest) return target; @@ -1027,7 +1034,7 @@ size_t CodeGeneratorRequest::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated string file_to_generate = 1; total_size += 1 * @@ -1131,13 +1138,14 @@ void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) { InternalSwap(other); } void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { + using std::swap; 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]); + swap(compiler_version_, other->compiler_version_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const { @@ -1325,9 +1333,10 @@ void CodeGeneratorRequest::clear_compiler_version() { clear_has_compiler_version(); } const ::google::protobuf::compiler::Version& CodeGeneratorRequest::compiler_version() const { + const ::google::protobuf::compiler::Version* p = compiler_version_; // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) - return compiler_version_ != NULL ? *compiler_version_ - : *::google::protobuf::compiler::Version::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::compiler::Version*>( + &::google::protobuf::compiler::_Version_default_instance_); } ::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() { set_has_compiler_version(); @@ -1437,16 +1446,21 @@ CodeGeneratorResponse_File* CodeGeneratorResponse_File::New(::google::protobuf:: void CodeGeneratorResponse_File::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse.File) - if (_has_bits_[0 / 32] & 7u) { - if (has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 7u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_insertion_point()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(!insertion_point_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*insertion_point_.UnsafeRawStringPointer())->clear(); } - if (has_content()) { + if (cached_has_bits & 0x00000004u) { GOOGLE_DCHECK(!content_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*content_.UnsafeRawStringPointer())->clear(); } @@ -1468,7 +1482,7 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -1484,7 +1498,7 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( // optional string insertion_point = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_insertion_point())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -1500,7 +1514,7 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( // optional string content = 15; case 15: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(122u)) { + static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_content())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -1515,13 +1529,11 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1574,7 +1586,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse.File) } @@ -1622,7 +1634,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse.File) return target; @@ -1635,7 +1647,7 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (_has_bits_[0 / 32] & 7u) { // optional string name = 1; @@ -1729,12 +1741,13 @@ void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) { InternalSwap(other); } void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) { + using std::swap; name_.Swap(&other->name_); insertion_point_.Swap(&other->insertion_point_); content_.Swap(&other->content_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const { @@ -2004,6 +2017,10 @@ CodeGeneratorResponse* CodeGeneratorResponse::New(::google::protobuf::Arena* are void CodeGeneratorResponse::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + file_.Clear(); if (has_error()) { GOOGLE_DCHECK(!error_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); @@ -2026,7 +2043,7 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( // optional string error = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_error())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -2042,7 +2059,7 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; case 15: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(122u)) { + static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_file())); } else { @@ -2053,13 +2070,11 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -2099,7 +2114,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse) } @@ -2133,7 +2148,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse) return target; @@ -2146,7 +2161,7 @@ size_t CodeGeneratorResponse::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; { @@ -2225,11 +2240,12 @@ void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) { InternalSwap(other); } void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { + using std::swap; file_.InternalSwap(&other->file_); error_.Swap(&other->error_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const { diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 57e1f77b..2d66f035 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -67,8 +67,9 @@ struct LIBPROTOC_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOC_EXPORT AddDescriptors(); void LIBPROTOC_EXPORT InitDefaults(); @@ -87,11 +88,24 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ CopyFrom(from); return *this; } + #if LANG_CXX11 + Version(Version&& from) noexcept + : Version() { + *this = ::std::move(from); + } + inline Version& operator=(Version&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -107,6 +121,9 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ 0; void Swap(Version* other); + friend void swap(Version& a, Version& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -217,11 +234,24 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message CopyFrom(from); return *this; } + #if LANG_CXX11 + CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept + : CodeGeneratorRequest() { + *this = ::std::move(from); + } + inline CodeGeneratorRequest& operator=(CodeGeneratorRequest&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -237,6 +267,9 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message 1; void Swap(CodeGeneratorRequest* other); + friend void swap(CodeGeneratorRequest& a, CodeGeneratorRequest& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -365,11 +398,24 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M CopyFrom(from); return *this; } + #if LANG_CXX11 + CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept + : CodeGeneratorResponse_File() { + *this = ::std::move(from); + } + inline CodeGeneratorResponse_File& operator=(CodeGeneratorResponse_File&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -385,6 +431,9 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M 2; void Swap(CodeGeneratorResponse_File* other); + friend void swap(CodeGeneratorResponse_File& a, CodeGeneratorResponse_File& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -501,11 +550,24 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag CopyFrom(from); return *this; } + #if LANG_CXX11 + CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept + : CodeGeneratorResponse() { + *this = ::std::move(from); + } + inline CodeGeneratorResponse& operator=(CodeGeneratorResponse&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -521,6 +583,9 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag 3; void Swap(CodeGeneratorResponse* other); + friend void swap(CodeGeneratorResponse& a, CodeGeneratorResponse& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -609,6 +674,10 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // Version // optional int32 major = 1; @@ -927,9 +996,10 @@ inline void CodeGeneratorRequest::clear_compiler_version() { clear_has_compiler_version(); } inline const ::google::protobuf::compiler::Version& CodeGeneratorRequest::compiler_version() const { + const ::google::protobuf::compiler::Version* p = compiler_version_; // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) - return compiler_version_ != NULL ? *compiler_version_ - : *::google::protobuf::compiler::Version::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::compiler::Version*>( + &::google::protobuf::compiler::_Version_default_instance_); } inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() { set_has_compiler_version(); @@ -1247,6 +1317,9 @@ CodeGeneratorResponse::file() const { return file_; } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // ------------------------------------------------------------------- diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto index f04dc73c..5b557452 100644 --- a/src/google/protobuf/compiler/plugin.proto +++ b/src/google/protobuf/compiler/plugin.proto @@ -91,6 +91,7 @@ message CodeGeneratorRequest { // The version number of protocol compiler. optional Version compiler_version = 3; + } // The plugin writes an encoded CodeGeneratorResponse to stdout. diff --git a/src/google/protobuf/compiler/profile.pb.cc b/src/google/protobuf/compiler/profile.pb.cc deleted file mode 100644 index 4616b514..00000000 --- a/src/google/protobuf/compiler/profile.pb.cc +++ /dev/null @@ -1,1453 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/compiler/profile.proto - -#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION -#include <google/protobuf/compiler/profile.pb.h> - -#include <algorithm> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/port.h> -#include <google/protobuf/stubs/once.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/wire_format_lite_inl.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/generated_message_reflection.h> -#include <google/protobuf/reflection_ops.h> -#include <google/protobuf/wire_format.h> -// @@protoc_insertion_point(includes) - -namespace google { -namespace protobuf { -namespace compiler { -class FieldAccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FieldAccessInfo> { -} _FieldAccessInfo_default_instance_; -class MessageAccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<MessageAccessInfo> { -} _MessageAccessInfo_default_instance_; -class AccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<AccessInfo> { -} _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<const ::google::protobuf::Message*>(&_FieldAccessInfo_default_instance_), - reinterpret_cast<const ::google::protobuf::Message*>(&_MessageAccessInfo_default_instance_), - reinterpret_cast<const ::google::protobuf::Message*>(&_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); -} -namespace { -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); -} -} // anonymous namespace - -void AddDescriptors() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl); -} -// Force AddDescriptors() to be called at dynamic 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_, - static_cast<size_t>(reinterpret_cast<char*>(&configs_count_) - - reinterpret_cast<char*>(&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, static_cast<size_t>( - reinterpret_cast<char*>(&configs_count_) - - reinterpret_cast<char*>(&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, static_cast<size_t>( - reinterpret_cast<char*>(&configs_count_) - - reinterpret_cast<char*>(&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(), static_cast<int>(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(), static_cast<int>(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 { - (void)deterministic; // Unused - // @@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(), static_cast<int>(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<const FieldAccessInfo>( - &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<const char*>(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(), static_cast<int>(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(), static_cast<int>(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 = static_cast<unsigned int>(this->field_size()); i < n; i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, this->field(static_cast<int>(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 { - (void)deterministic; // Unused - // @@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(), static_cast<int>(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 = static_cast<unsigned int>(this->field_size()); i < n; i++) { - target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 3, this->field(static_cast<int>(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 = static_cast<unsigned int>(this->field_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->field(static_cast<int>(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<const MessageAccessInfo>( - &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<const char*>(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 = static_cast<unsigned int>(this->message_size()); i < n; i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 1, this->message(static_cast<int>(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 { - (void)deterministic; // Unused - // @@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 = static_cast<unsigned int>(this->message_size()); i < n; i++) { - target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 1, this->message(static_cast<int>(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 = static_cast<unsigned int>(this->message_size()); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->message(static_cast<int>(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<const AccessInfo>( - &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 deleted file mode 100644 index b4931cf1..00000000 --- a/src/google/protobuf/compiler/profile.pb.h +++ /dev/null @@ -1,728 +0,0 @@ -// 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 <string> - -#include <google/protobuf/stubs/common.h> - -#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 3003002 < 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 <google/protobuf/io/coded_stream.h> -#include <google/protobuf/arena.h> -#include <google/protobuf/arenastring.h> -#include <google/protobuf/generated_message_table_driven.h> -#include <google/protobuf/generated_message_util.h> -#include <google/protobuf/metadata.h> -#include <google/protobuf/message.h> -#include <google/protobuf/repeated_field.h> // IWYU pragma: export -#include <google/protobuf/extension_set.h> // IWYU pragma: export -#include <google/protobuf/unknown_field_set.h> -// @@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<const FieldAccessInfo*>( - &_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<const MessageAccessInfo*>( - &_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<const AccessInfo*>( - &_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<const char*>(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<const char*>(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/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc index 21a7e158..97769835 100644 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ b/src/google/protobuf/compiler/python/python_generator.cc @@ -63,11 +63,12 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/stringprintf.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.h> #include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/descriptor.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> + namespace google { namespace protobuf { namespace compiler { @@ -75,12 +76,21 @@ namespace python { namespace { +// Reimplemented here because we can't bring in +// absl/strings/string_view_utils.h because it needs C++11. +bool StrStartsWith(StringPiece sp, StringPiece x) { + return sp.size() >= x.size() && sp.substr(0, x.size()) == x; +} +bool StrEndsWith(StringPiece sp, StringPiece x) { + return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x; +} + // Returns a copy of |filename| with any trailing ".protodevel" or ".proto // suffix stripped. // TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc. string StripProto(const string& filename) { - const char* suffix = HasSuffixString(filename, ".protodevel") - ? ".protodevel" : ".proto"; + const char* suffix = + StrEndsWith(filename, ".protodevel") ? ".protodevel" : ".proto"; return StripSuffixString(filename, suffix); } @@ -350,7 +360,9 @@ bool Generator::Generate(const FileDescriptor* file, // can only be successfully parsed after we register corresponding // extensions. Therefore we parse all options again here to recognize // custom options that may be unknown when we define the descriptors. + // This does not apply to services because they are not used by extensions. FixAllDescriptorOptions(); + PrintServiceDescriptors(); if (HasGenericServices(file)) { PrintServices(); } @@ -562,9 +574,16 @@ void Generator::PrintMessageDescriptors() const { } } -void Generator::PrintServices() const { +void Generator::PrintServiceDescriptors() const { for (int i = 0; i < file_->service_count(); ++i) { PrintServiceDescriptor(*file_->service(i)); + AddServiceToFileDescriptor(*file_->service(i)); + printer_->Print("\n"); + } +} + +void Generator::PrintServices() const { + for (int i = 0; i < file_->service_count(); ++i) { PrintServiceClass(*file_->service(i)); PrintServiceStub(*file_->service(i)); printer_->Print("\n"); @@ -628,7 +647,10 @@ void Generator::PrintServiceDescriptor( } printer_->Outdent(); - printer_->Print("])\n\n"); + printer_->Print("])\n"); + printer_->Print("_sym_db.RegisterServiceDescriptor($name$)\n", "name", + service_name); + printer_->Print("\n"); } @@ -887,6 +909,18 @@ void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const { printer_->Print(m, file_descriptor_template); } +void Generator::AddServiceToFileDescriptor( + const ServiceDescriptor& descriptor) const { + std::map<string, string> m; + m["descriptor_name"] = kDescriptorKey; + m["service_name"] = descriptor.name(); + m["service_descriptor_name"] = ModuleLevelServiceDescriptorName(descriptor); + const char file_descriptor_template[] = + "$descriptor_name$.services_by_name['$service_name$'] = " + "$service_descriptor_name$\n"; + printer_->Print(m, file_descriptor_template); +} + void Generator::AddEnumToFileDescriptor( const EnumDescriptor& descriptor) const { std::map<string, string> m; diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h index 594260af..2b5a028b 100644 --- a/src/google/protobuf/compiler/python/python_generator.h +++ b/src/google/protobuf/compiler/python/python_generator.h @@ -112,6 +112,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { void AddMessageToFileDescriptor(const Descriptor& descriptor) const; void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const; void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const; + void AddServiceToFileDescriptor(const ServiceDescriptor& descriptor) const; string FieldReferencingExpression(const Descriptor* containing_type, const FieldDescriptor& field, const string& python_dict_name) const; @@ -126,11 +127,12 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const; void PrintServices() const; + void PrintServiceDescriptors() const; void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const; void PrintServiceClass(const ServiceDescriptor& descriptor) const; void PrintServiceStub(const ServiceDescriptor& descriptor) const; void PrintDescriptorKeyAndModuleName( - const ServiceDescriptor& descriptor) const ; + const ServiceDescriptor& descriptor) const; void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const; string OptionsValue(const string& class_name, diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc index 933450fa..2e5a89ac 100644 --- a/src/google/protobuf/compiler/subprocess.cc +++ b/src/google/protobuf/compiler/subprocess.cc @@ -33,6 +33,7 @@ #include <google/protobuf/compiler/subprocess.h> #include <algorithm> +#include <cstring> #include <iostream> #ifndef _WIN32 @@ -47,11 +48,20 @@ #include <google/protobuf/message.h> #include <google/protobuf/stubs/substitute.h> - namespace google { namespace protobuf { namespace compiler { +namespace { +char* portable_strdup(const char* s) { + char* ns = (char*) malloc(strlen(s) + 1); + if (ns != NULL) { + strcpy(ns, s); + } + return ns; +} +} // namespace + #ifdef _WIN32 static void CloseHandleOrDie(HANDLE handle) { @@ -115,7 +125,7 @@ void Subprocess::Start(const string& program, SearchMode search_mode) { } // CreateProcess() mutates its second parameter. WTF? - char* name_copy = strdup(program.c_str()); + char* name_copy = portable_strdup(program.c_str()); // Create the process. PROCESS_INFORMATION process_info; @@ -299,7 +309,7 @@ void Subprocess::Start(const string& program, SearchMode search_mode) { GOOGLE_CHECK(pipe(stdin_pipe) != -1); GOOGLE_CHECK(pipe(stdout_pipe) != -1); - char* argv[2] = { strdup(program.c_str()), NULL }; + char* argv[2] = { portable_strdup(program.c_str()), NULL }; child_pid_ = fork(); if (child_pid_ == -1) { @@ -347,7 +357,6 @@ void Subprocess::Start(const string& program, SearchMode search_mode) { bool Subprocess::Communicate(const Message& input, Message* output, string* error) { - GOOGLE_CHECK_NE(child_stdin_, -1) << "Must call Start() first."; // The "sighandler_t" typedef is GNU-specific, so define our own. diff --git a/src/google/protobuf/compiler/subprocess.h b/src/google/protobuf/compiler/subprocess.h index 25138631..9d980b06 100644 --- a/src/google/protobuf/compiler/subprocess.h +++ b/src/google/protobuf/compiler/subprocess.h @@ -44,7 +44,6 @@ #include <string> - namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/zip_output_unittest.sh b/src/google/protobuf/compiler/zip_output_unittest.sh index 6fc7136d..f8597912 100755 --- a/src/google/protobuf/compiler/zip_output_unittest.sh +++ b/src/google/protobuf/compiler/zip_output_unittest.sh @@ -41,6 +41,8 @@ fail() { TEST_TMPDIR=. PROTOC=./protoc +JAR=jar +UNZIP=unzip echo ' syntax = "proto2"; @@ -57,8 +59,9 @@ $PROTOC \ || fail 'protoc failed.' echo "Testing output to zip..." -if unzip -h > /dev/null; then - unzip -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list || fail 'unzip failed.' +if $UNZIP -h > /dev/null; then + $UNZIP -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list \ + || fail 'unzip failed.' grep 'testing: testzip\.pb\.cc *OK$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'testzip.pb.cc not found in output zip.' @@ -73,8 +76,14 @@ else fi echo "Testing output to jar..." -if jar c $TEST_TMPDIR/testzip.proto > /dev/null; then - jar tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list || fail 'jar failed.' +if $JAR c $TEST_TMPDIR/testzip.proto > /dev/null; then + $JAR tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list \ + || fail 'jar failed.' + + # Check that -interface.jar timestamps are normalized: + if [[ "$(TZ=UTC $JAR tvf $TEST_TMPDIR/testzip.jar)" != *'Tue Jan 01 00:00:00 UTC 1980'* ]]; then + fail 'Zip did not contain normalized timestamps' + fi grep '^test/jar/Foo\.java$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'Foo.java not found in output jar.' diff --git a/src/google/protobuf/compiler/zip_writer.cc b/src/google/protobuf/compiler/zip_writer.cc index 458cced2..1799af6a 100644 --- a/src/google/protobuf/compiler/zip_writer.cc +++ b/src/google/protobuf/compiler/zip_writer.cc @@ -70,6 +70,10 @@ namespace google { namespace protobuf { namespace compiler { +// January 1, 1980 as a DOS date. +// see https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx +static const uint16 kDosEpoch = 1 << 5 | 1; + static const uint32 kCRC32Table[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, @@ -154,7 +158,7 @@ bool ZipWriter::Write(const string& filename, const string& contents) { WriteShort(&output, 0); // flags WriteShort(&output, 0); // compression method: stored WriteShort(&output, 0); // last modified time - WriteShort(&output, 0); // last modified date + WriteShort(&output, kDosEpoch); // last modified date output.WriteLittleEndian32(info.crc32); // crc-32 output.WriteLittleEndian32(info.size); // compressed size output.WriteLittleEndian32(info.size); // uncompressed size @@ -185,7 +189,7 @@ bool ZipWriter::WriteDirectory() { WriteShort(&output, 0); // flags WriteShort(&output, 0); // compression method: stored WriteShort(&output, 0); // last modified time - WriteShort(&output, 0); // last modified date + WriteShort(&output, kDosEpoch); // last modified date output.WriteLittleEndian32(crc32); // crc-32 output.WriteLittleEndian32(size); // compressed size output.WriteLittleEndian32(size); // uncompressed size diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 6a807926..89b37ee3 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -44,25 +44,26 @@ #include <algorithm> #include <limits> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/mutex.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/io/strtod.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/tokenizer.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor_database.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/dynamic_message.h> #include <google/protobuf/generated_message_util.h> #include <google/protobuf/text_format.h> #include <google/protobuf/unknown_field_set.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/io/strtod.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/mutex.h> -#include <google/protobuf/stubs/once.h> -#include <google/protobuf/stubs/stringprintf.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> + #include <google/protobuf/stubs/map_util.h> #include <google/protobuf/stubs/stl_util.h> @@ -1953,6 +1954,10 @@ void Descriptor::CopyTo(DescriptorProto* proto) const { DescriptorProto::ExtensionRange* range = proto->add_extension_range(); range->set_start(extension_range(i)->start); range->set_end(extension_range(i)->end); + const ExtensionRangeOptions* options = extension_range(i)->options_; + if (options != &ExtensionRangeOptions::default_instance()) { + range->mutable_options()->CopyFrom(*options); + } } for (int i = 0; i < extension_count(); i++) { extension(i)->CopyTo(proto->add_extension()); @@ -3203,6 +3208,8 @@ class DescriptorBuilder { void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto); void CrossLinkField(FieldDescriptor* field, const FieldDescriptorProto& proto); + void CrossLinkExtensionRange(Descriptor::ExtensionRange* range, + const DescriptorProto::ExtensionRange& proto); void CrossLinkEnum(EnumDescriptor* enum_type, const EnumDescriptorProto& proto); void CrossLinkEnumValue(EnumValueDescriptor* enum_value, @@ -3382,6 +3389,8 @@ class DescriptorBuilder { void DetectMapConflicts(const Descriptor* message, const DescriptorProto& proto); + void ValidateJSType(FieldDescriptor* field, + const FieldDescriptorProto& proto); }; const FileDescriptor* DescriptorPool::BuildFile( @@ -3509,8 +3518,8 @@ void DescriptorBuilder::AddWarning( bool DescriptorBuilder::IsInPackage(const FileDescriptor* file, const string& package_name) { return HasPrefixString(file->package(), package_name) && - (file->package().size() == package_name.size() || - file->package()[package_name.size()] == '.'); + (file->package().size() == package_name.size() || + file->package()[package_name.size()] == '.'); } void DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) { @@ -4776,6 +4785,13 @@ void DescriptorBuilder::BuildExtensionRange( DescriptorPool::ErrorCollector::NUMBER, "Extension range end number must be greater than start number."); } + + if (!proto.has_options()) { + result->options_ = NULL; // Will set to default_instance later. + } else { + AllocateOptionsImpl(parent->full_name(), parent->full_name(), + proto.options(), result); + } } void DescriptorBuilder::BuildReservedRange( @@ -5100,6 +5116,11 @@ void DescriptorBuilder::CrossLinkMessage( CrossLinkField(&message->extensions_[i], proto.extension(i)); } + for (int i = 0; i < message->extension_range_count(); i++) { + CrossLinkExtensionRange(&message->extension_ranges_[i], + proto.extension_range(i)); + } + // Set up field array for each oneof. // First count the number of fields per oneof. @@ -5162,6 +5183,14 @@ void DescriptorBuilder::CrossLinkMessage( } } +void DescriptorBuilder::CrossLinkExtensionRange( + Descriptor::ExtensionRange* range, + const DescriptorProto::ExtensionRange& proto) { + if (range->options_ == NULL) { + range->options_ = &ExtensionRangeOptions::default_instance(); + } +} + void DescriptorBuilder::CrossLinkField( FieldDescriptor* field, const FieldDescriptorProto& proto) { if (field->options_ == NULL) { @@ -5734,6 +5763,8 @@ void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, } } + ValidateJSType(field, proto); + } void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, @@ -5922,6 +5953,40 @@ void DescriptorBuilder::DetectMapConflicts(const Descriptor* message, } } +void DescriptorBuilder::ValidateJSType(FieldDescriptor* field, + const FieldDescriptorProto& proto) { + FieldOptions::JSType jstype = field->options().jstype(); + // The default is always acceptable. + if (jstype == FieldOptions::JS_NORMAL) { + return; + } + + switch (field->type()) { + // Integral 64-bit types may be represented as JavaScript numbers or + // strings. + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + if (jstype == FieldOptions::JS_STRING || + jstype == FieldOptions::JS_NUMBER) { + return; + } + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "Illegal jstype for int64, uint64, sint64, fixed64 " + "or sfixed64 field: " + + FieldOptions_JSType_descriptor()->value(jstype)->name()); + break; + + // No other types permit a jstype option. + default: + AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "jstype is only allowed on int64, uint64, sint64, fixed64 " + "or sfixed64 fields."); + break; + } +} #undef VALIDATE_OPTIONS_FROM_ARRAY @@ -6663,6 +6728,7 @@ void DescriptorBuilder::LogUnusedDependency(const FileDescriptorProto& proto, annotation_extensions.insert("google.protobuf.FieldOptions"); annotation_extensions.insert("google.protobuf.EnumOptions"); annotation_extensions.insert("google.protobuf.EnumValueOptions"); + annotation_extensions.insert("google.protobuf.EnumValueOptions"); annotation_extensions.insert("google.protobuf.ServiceOptions"); annotation_extensions.insert("google.protobuf.MethodOptions"); annotation_extensions.insert("google.protobuf.StreamOptions"); diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 7aea7344..57128e6b 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -99,6 +99,7 @@ class FieldOptions; class OneofOptions; class EnumOptions; class EnumValueOptions; +class ExtensionRangeOptions; class ServiceOptions; class MethodOptions; class FileOptions; @@ -337,8 +338,12 @@ class LIBPROTOBUF_EXPORT Descriptor { // A range of field numbers which are designated for third-party // extensions. struct ExtensionRange { + typedef ExtensionRangeOptions OptionsType; + int start; // inclusive int end; // exclusive + + const ExtensionRangeOptions* options_; }; // The number of extension ranges in this message type. @@ -440,27 +445,30 @@ class LIBPROTOBUF_EXPORT Descriptor { const Descriptor* containing_type_; const MessageOptions* options_; - // True if this is a placeholder for an unknown type. - bool is_placeholder_; - // True if this is a placeholder and the type name wasn't fully-qualified. - bool is_unqualified_placeholder_; + // These arrays are separated from their sizes to minimize padding on 64-bit. + FieldDescriptor* fields_; + OneofDescriptor* oneof_decls_; + Descriptor* nested_types_; + EnumDescriptor* enum_types_; + ExtensionRange* extension_ranges_; + FieldDescriptor* extensions_; + ReservedRange* reserved_ranges_; + const string** reserved_names_; int field_count_; - FieldDescriptor* fields_; int oneof_decl_count_; - OneofDescriptor* oneof_decls_; int nested_type_count_; - Descriptor* nested_types_; int enum_type_count_; - EnumDescriptor* enum_types_; int extension_range_count_; - ExtensionRange* extension_ranges_; int extension_count_; - FieldDescriptor* extensions_; int reserved_range_count_; - ReservedRange* reserved_ranges_; int reserved_name_count_; - const string** reserved_names_; + + // True if this is a placeholder for an unknown type. + bool is_placeholder_; + // True if this is a placeholder and the type name wasn't fully-qualified. + bool is_unqualified_placeholder_; + // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate<Descriptor>() and AllocateArray<Descriptor>() in descriptor.cc // and update them to initialize the field. @@ -477,6 +485,7 @@ class LIBPROTOBUF_EXPORT Descriptor { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor); }; + // Describes a single field of a message. To get the descriptor for a given // field, first get the Descriptor for the message in which it is defined, // then call Descriptor::FindFieldByName(). To get a FieldDescriptor for @@ -736,20 +745,21 @@ class LIBPROTOBUF_EXPORT FieldDescriptor { const string* full_name_; const string* lowercase_name_; const string* camelcase_name_; - // Whether the user has specified the json_name field option in the .proto - // file. - bool has_json_name_; // If has_json_name_ is true, it's the value specified by the user. // Otherwise, it has the same value as camelcase_name_. const string* json_name_; const FileDescriptor* file_; - int number_; GoogleOnceDynamic* type_once_; static void TypeOnceInit(const FieldDescriptor* to_init); void InternalTypeOnceInit() const; mutable Type type_; Label label_; + bool has_default_value_; + // Whether the user has specified the json_name field option in the .proto + // file. + bool has_json_name_; bool is_extension_; + int number_; int index_in_oneof_; const Descriptor* containing_type_; const OneofDescriptor* containing_oneof_; @@ -763,7 +773,6 @@ class LIBPROTOBUF_EXPORT FieldDescriptor { // of Allocate<FieldDescriptor>() and AllocateArray<FieldDescriptor>() in // descriptor.cc and update them to initialize the field. - bool has_default_value_; union { int32 default_value_int32_; int64 default_value_int64_; @@ -794,6 +803,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptor { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor); }; + // Describes a oneof defined in a message type. class LIBPROTOBUF_EXPORT OneofDescriptor { public: @@ -803,6 +813,8 @@ class LIBPROTOBUF_EXPORT OneofDescriptor { // Index of this oneof within the message's oneof array. int index() const; + // The .proto file in which this oneof was defined. Never NULL. + const FileDescriptor* file() const; // The Descriptor for the message containing this oneof. const Descriptor* containing_type() const; @@ -998,6 +1010,8 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptor { // with C++ scoping rules for enums. const string& full_name() const; + // The .proto file in which this value was defined. Never NULL. + const FileDescriptor* file() const; // The type of this value. Never NULL. const EnumDescriptor* type() const; @@ -1122,8 +1136,8 @@ class LIBPROTOBUF_EXPORT ServiceDescriptor { const string* full_name_; const FileDescriptor* file_; const ServiceOptions* options_; - int method_count_; MethodDescriptor* methods_; + int method_count_; // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate<ServiceDescriptor>() and AllocateArray<ServiceDescriptor>() in // descriptor.cc and update them to initialize the field. @@ -1136,6 +1150,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptor { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor); }; + // Describes an individual service method. To obtain a MethodDescriptor given // a service, first get its ServiceDescriptor, then call // ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your @@ -1149,6 +1164,8 @@ class LIBPROTOBUF_EXPORT MethodDescriptor { // Index within the service's Descriptor. int index() const; + // The .proto file in which this method was defined. Never NULL. + const FileDescriptor* file() const; // Gets the service to which this method belongs. Never NULL. const ServiceDescriptor* service() const; @@ -1360,36 +1377,39 @@ class LIBPROTOBUF_EXPORT FileDescriptor { const string* name_; const string* package_; const DescriptorPool* pool_; - int dependency_count_; - mutable const FileDescriptor** dependencies_; - const string** dependencies_names_; GoogleOnceDynamic* dependencies_once_; static void DependenciesOnceInit(const FileDescriptor* to_init); void InternalDependenciesOnceInit() const; + + // These are arranged to minimze padding on 64-bit. + int dependency_count_; int public_dependency_count_; - int* public_dependencies_; int weak_dependency_count_; - int* weak_dependencies_; int message_type_count_; - Descriptor* message_types_; int enum_type_count_; - EnumDescriptor* enum_types_; int service_count_; - ServiceDescriptor* services_; int extension_count_; Syntax syntax_; bool is_placeholder_; - FieldDescriptor* extensions_; - const FileOptions* options_; - - 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_; + mutable const FileDescriptor** dependencies_; + const string** dependencies_names_; + int* public_dependencies_; + int* weak_dependencies_; + Descriptor* message_types_; + EnumDescriptor* enum_types_; + ServiceDescriptor* services_; + FieldDescriptor* extensions_; + const FileOptions* options_; + + const FileDescriptorTables* tables_; + const SourceCodeInfo* source_code_info_; + // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate<FileDescriptor>() and AllocateArray<FileDescriptor>() in // descriptor.cc and update them to initialize the field. @@ -1408,6 +1428,7 @@ class LIBPROTOBUF_EXPORT FileDescriptor { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor); }; + // =================================================================== // Used to construct descriptors. @@ -1748,12 +1769,13 @@ class LIBPROTOBUF_EXPORT DescriptorPool { bool lazily_build_dependencies_; bool allow_unknown_; bool enforce_weak_; - std::set<string> unused_import_track_files_; bool disallow_enforce_utf8_; + std::set<string> unused_import_track_files_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool); }; + // inline methods ==================================================== // These macros makes this repetitive code more readable. @@ -1949,6 +1971,10 @@ inline int Descriptor::index() const { } } +inline const FileDescriptor* OneofDescriptor::file() const { + return containing_type()->file(); +} + inline int OneofDescriptor::index() const { return static_cast<int>(this - containing_type_->oneof_decls_); } @@ -1961,6 +1987,10 @@ inline int EnumDescriptor::index() const { } } +inline const FileDescriptor* EnumValueDescriptor::file() const { + return type()->file(); +} + inline int EnumValueDescriptor::index() const { return static_cast<int>(this - type_->values_); } @@ -1969,6 +1999,10 @@ inline int ServiceDescriptor::index() const { return static_cast<int>(this - file_->services_); } +inline const FileDescriptor* MethodDescriptor::file() const { + return service()->file(); +} + inline int MethodDescriptor::index() const { return static_cast<int>(this - service_->methods_); } diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 78935211..69c0ab0d 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -19,55 +19,135 @@ namespace google { namespace protobuf { -class FileDescriptorSetDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorSet> { +class FileDescriptorSetDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorSet> + _instance; } _FileDescriptorSet_default_instance_; -class FileDescriptorProtoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorProto> { +class FileDescriptorProtoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorProto> + _instance; } _FileDescriptorProto_default_instance_; -class DescriptorProto_ExtensionRangeDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ExtensionRange> { +class DescriptorProto_ExtensionRangeDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ExtensionRange> + _instance; } _DescriptorProto_ExtensionRange_default_instance_; -class DescriptorProto_ReservedRangeDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ReservedRange> { +class DescriptorProto_ReservedRangeDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ReservedRange> + _instance; } _DescriptorProto_ReservedRange_default_instance_; -class DescriptorProtoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto> { +class DescriptorProtoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto> + _instance; } _DescriptorProto_default_instance_; -class FieldDescriptorProtoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FieldDescriptorProto> { +class ExtensionRangeOptionsDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<ExtensionRangeOptions> + _instance; +} _ExtensionRangeOptions_default_instance_; +class FieldDescriptorProtoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<FieldDescriptorProto> + _instance; } _FieldDescriptorProto_default_instance_; -class OneofDescriptorProtoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<OneofDescriptorProto> { +class OneofDescriptorProtoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<OneofDescriptorProto> + _instance; } _OneofDescriptorProto_default_instance_; -class EnumDescriptorProtoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<EnumDescriptorProto> { +class EnumDescriptorProtoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<EnumDescriptorProto> + _instance; } _EnumDescriptorProto_default_instance_; -class EnumValueDescriptorProtoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<EnumValueDescriptorProto> { +class EnumValueDescriptorProtoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<EnumValueDescriptorProto> + _instance; } _EnumValueDescriptorProto_default_instance_; -class ServiceDescriptorProtoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<ServiceDescriptorProto> { +class ServiceDescriptorProtoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<ServiceDescriptorProto> + _instance; } _ServiceDescriptorProto_default_instance_; -class MethodDescriptorProtoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<MethodDescriptorProto> { +class MethodDescriptorProtoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<MethodDescriptorProto> + _instance; } _MethodDescriptorProto_default_instance_; -class FileOptionsDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FileOptions> { +class FileOptionsDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<FileOptions> + _instance; } _FileOptions_default_instance_; -class MessageOptionsDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<MessageOptions> { +class MessageOptionsDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<MessageOptions> + _instance; } _MessageOptions_default_instance_; -class FieldOptionsDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FieldOptions> { +class FieldOptionsDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<FieldOptions> + _instance; } _FieldOptions_default_instance_; -class OneofOptionsDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<OneofOptions> { +class OneofOptionsDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<OneofOptions> + _instance; } _OneofOptions_default_instance_; -class EnumOptionsDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<EnumOptions> { +class EnumOptionsDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<EnumOptions> + _instance; } _EnumOptions_default_instance_; -class EnumValueOptionsDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<EnumValueOptions> { +class EnumValueOptionsDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<EnumValueOptions> + _instance; } _EnumValueOptions_default_instance_; -class ServiceOptionsDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<ServiceOptions> { +class ServiceOptionsDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<ServiceOptions> + _instance; } _ServiceOptions_default_instance_; -class MethodOptionsDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<MethodOptions> { +class MethodOptionsDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<MethodOptions> + _instance; } _MethodOptions_default_instance_; -class UninterpretedOption_NamePartDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption_NamePart> { +class UninterpretedOption_NamePartDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption_NamePart> + _instance; } _UninterpretedOption_NamePart_default_instance_; -class UninterpretedOptionDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption> { +class UninterpretedOptionDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption> + _instance; } _UninterpretedOption_default_instance_; -class SourceCodeInfo_LocationDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo_Location> { +class SourceCodeInfo_LocationDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo_Location> + _instance; } _SourceCodeInfo_Location_default_instance_; -class SourceCodeInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo> { +class SourceCodeInfoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo> + _instance; } _SourceCodeInfo_default_instance_; -class GeneratedCodeInfo_AnnotationDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo_Annotation> { +class GeneratedCodeInfo_AnnotationDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo_Annotation> + _instance; } _GeneratedCodeInfo_Annotation_default_instance_; -class GeneratedCodeInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo> { +class GeneratedCodeInfoDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo> + _instance; } _GeneratedCodeInfo_default_instance_; namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto { @@ -75,50 +155,51 @@ namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto { namespace { -::google::protobuf::Metadata file_level_metadata[25]; +::google::protobuf::Metadata file_level_metadata[26]; const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[6]; } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::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 }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _internal_metadata_), ~0u, // no _extensions_ @@ -162,8 +243,10 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_), - 0, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, options_), 1, + 2, + 0, GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, _internal_metadata_), ~0u, // no _extensions_ @@ -198,6 +281,13 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { 1, ~0u, ~0u, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRangeOptions, _has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRangeOptions, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRangeOptions, _extensions_), + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRangeOptions, uninterpreted_option_), + ~0u, GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ @@ -477,33 +567,33 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo, annotation_), ~0u, }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 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, 187, sizeof(FileOptions)}, - { 206, 216, sizeof(MessageOptions)}, - { 221, 233, sizeof(FieldOptions)}, - { 240, 246, sizeof(OneofOptions)}, - { 247, 255, sizeof(EnumOptions)}, - { 258, 265, sizeof(EnumValueOptions)}, - { 267, 274, sizeof(ServiceOptions)}, - { 276, 284, sizeof(MethodOptions)}, - { 287, 294, sizeof(UninterpretedOption_NamePart)}, - { 296, 308, sizeof(UninterpretedOption)}, - { 315, 325, sizeof(SourceCodeInfo_Location)}, - { 330, 336, sizeof(SourceCodeInfo)}, - { 337, 346, sizeof(GeneratedCodeInfo_Annotation)}, - { 350, 356, sizeof(GeneratedCodeInfo)}, + { 36, 44, sizeof(DescriptorProto_ExtensionRange)}, + { 47, 54, sizeof(DescriptorProto_ReservedRange)}, + { 56, 71, sizeof(DescriptorProto)}, + { 81, 87, sizeof(ExtensionRangeOptions)}, + { 88, 103, sizeof(FieldDescriptorProto)}, + { 113, 120, sizeof(OneofDescriptorProto)}, + { 122, 130, sizeof(EnumDescriptorProto)}, + { 133, 141, sizeof(EnumValueDescriptorProto)}, + { 144, 152, sizeof(ServiceDescriptorProto)}, + { 155, 166, sizeof(MethodDescriptorProto)}, + { 172, 196, sizeof(FileOptions)}, + { 215, 225, sizeof(MessageOptions)}, + { 230, 242, sizeof(FieldOptions)}, + { 249, 255, sizeof(OneofOptions)}, + { 256, 264, sizeof(EnumOptions)}, + { 267, 274, sizeof(EnumValueOptions)}, + { 276, 283, sizeof(ServiceOptions)}, + { 285, 293, sizeof(MethodOptions)}, + { 296, 303, sizeof(UninterpretedOption_NamePart)}, + { 305, 317, sizeof(UninterpretedOption)}, + { 324, 334, sizeof(SourceCodeInfo_Location)}, + { 339, 345, sizeof(SourceCodeInfo)}, + { 346, 355, sizeof(GeneratedCodeInfo_Annotation)}, + { 359, 365, sizeof(GeneratedCodeInfo)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { @@ -512,6 +602,7 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&_DescriptorProto_ExtensionRange_default_instance_), reinterpret_cast<const ::google::protobuf::Message*>(&_DescriptorProto_ReservedRange_default_instance_), reinterpret_cast<const ::google::protobuf::Message*>(&_DescriptorProto_default_instance_), + reinterpret_cast<const ::google::protobuf::Message*>(&_ExtensionRangeOptions_default_instance_), reinterpret_cast<const ::google::protobuf::Message*>(&_FieldDescriptorProto_default_instance_), reinterpret_cast<const ::google::protobuf::Message*>(&_OneofDescriptorProto_default_instance_), reinterpret_cast<const ::google::protobuf::Message*>(&_EnumDescriptorProto_default_instance_), @@ -552,110 +643,85 @@ void protobuf_AssignDescriptorsOnce() { void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); - ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 25); + ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 26); } } // namespace - -void TableStruct::Shutdown() { - _FileDescriptorSet_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; - _FileDescriptorProto_default_instance_.Shutdown(); - delete file_level_metadata[1].reflection; - _DescriptorProto_ExtensionRange_default_instance_.Shutdown(); - delete file_level_metadata[2].reflection; - _DescriptorProto_ReservedRange_default_instance_.Shutdown(); - delete file_level_metadata[3].reflection; - _DescriptorProto_default_instance_.Shutdown(); - delete file_level_metadata[4].reflection; - _FieldDescriptorProto_default_instance_.Shutdown(); - delete file_level_metadata[5].reflection; - _OneofDescriptorProto_default_instance_.Shutdown(); - delete file_level_metadata[6].reflection; - _EnumDescriptorProto_default_instance_.Shutdown(); - delete file_level_metadata[7].reflection; - _EnumValueDescriptorProto_default_instance_.Shutdown(); - delete file_level_metadata[8].reflection; - _ServiceDescriptorProto_default_instance_.Shutdown(); - delete file_level_metadata[9].reflection; - _MethodDescriptorProto_default_instance_.Shutdown(); - delete file_level_metadata[10].reflection; - _FileOptions_default_instance_.Shutdown(); - delete file_level_metadata[11].reflection; - _MessageOptions_default_instance_.Shutdown(); - delete file_level_metadata[12].reflection; - _FieldOptions_default_instance_.Shutdown(); - delete file_level_metadata[13].reflection; - _OneofOptions_default_instance_.Shutdown(); - delete file_level_metadata[14].reflection; - _EnumOptions_default_instance_.Shutdown(); - delete file_level_metadata[15].reflection; - _EnumValueOptions_default_instance_.Shutdown(); - delete file_level_metadata[16].reflection; - _ServiceOptions_default_instance_.Shutdown(); - delete file_level_metadata[17].reflection; - _MethodOptions_default_instance_.Shutdown(); - delete file_level_metadata[18].reflection; - _UninterpretedOption_NamePart_default_instance_.Shutdown(); - delete file_level_metadata[19].reflection; - _UninterpretedOption_default_instance_.Shutdown(); - delete file_level_metadata[20].reflection; - _SourceCodeInfo_Location_default_instance_.Shutdown(); - delete file_level_metadata[21].reflection; - _SourceCodeInfo_default_instance_.Shutdown(); - delete file_level_metadata[22].reflection; - _GeneratedCodeInfo_Annotation_default_instance_.Shutdown(); - delete file_level_metadata[23].reflection; - _GeneratedCodeInfo_default_instance_.Shutdown(); - delete file_level_metadata[24].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); - _FileDescriptorSet_default_instance_.DefaultConstruct(); - _FileDescriptorProto_default_instance_.DefaultConstruct(); - _DescriptorProto_ExtensionRange_default_instance_.DefaultConstruct(); - _DescriptorProto_ReservedRange_default_instance_.DefaultConstruct(); - _DescriptorProto_default_instance_.DefaultConstruct(); - _FieldDescriptorProto_default_instance_.DefaultConstruct(); - _OneofDescriptorProto_default_instance_.DefaultConstruct(); - _EnumDescriptorProto_default_instance_.DefaultConstruct(); - _EnumValueDescriptorProto_default_instance_.DefaultConstruct(); - _ServiceDescriptorProto_default_instance_.DefaultConstruct(); - _MethodDescriptorProto_default_instance_.DefaultConstruct(); - _FileOptions_default_instance_.DefaultConstruct(); - _MessageOptions_default_instance_.DefaultConstruct(); - _FieldOptions_default_instance_.DefaultConstruct(); - _OneofOptions_default_instance_.DefaultConstruct(); - _EnumOptions_default_instance_.DefaultConstruct(); - _EnumValueOptions_default_instance_.DefaultConstruct(); - _ServiceOptions_default_instance_.DefaultConstruct(); - _MethodOptions_default_instance_.DefaultConstruct(); - _UninterpretedOption_NamePart_default_instance_.DefaultConstruct(); - _UninterpretedOption_default_instance_.DefaultConstruct(); - _SourceCodeInfo_Location_default_instance_.DefaultConstruct(); - _SourceCodeInfo_default_instance_.DefaultConstruct(); - _GeneratedCodeInfo_Annotation_default_instance_.DefaultConstruct(); - _GeneratedCodeInfo_default_instance_.DefaultConstruct(); - _FileDescriptorProto_default_instance_.get_mutable()->options_ = const_cast< ::google::protobuf::FileOptions*>( + _FileDescriptorSet_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_FileDescriptorSet_default_instance_);_FileDescriptorProto_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_FileDescriptorProto_default_instance_);_DescriptorProto_ExtensionRange_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_DescriptorProto_ExtensionRange_default_instance_);_DescriptorProto_ReservedRange_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_DescriptorProto_ReservedRange_default_instance_);_DescriptorProto_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_DescriptorProto_default_instance_);_ExtensionRangeOptions_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_ExtensionRangeOptions_default_instance_);_FieldDescriptorProto_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_FieldDescriptorProto_default_instance_);_OneofDescriptorProto_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_OneofDescriptorProto_default_instance_);_EnumDescriptorProto_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_EnumDescriptorProto_default_instance_);_EnumValueDescriptorProto_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_EnumValueDescriptorProto_default_instance_);_ServiceDescriptorProto_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_ServiceDescriptorProto_default_instance_);_MethodDescriptorProto_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_MethodDescriptorProto_default_instance_);_FileOptions_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_FileOptions_default_instance_);_MessageOptions_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_MessageOptions_default_instance_);_FieldOptions_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_FieldOptions_default_instance_);_OneofOptions_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_OneofOptions_default_instance_);_EnumOptions_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_EnumOptions_default_instance_);_EnumValueOptions_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_EnumValueOptions_default_instance_);_ServiceOptions_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_ServiceOptions_default_instance_);_MethodOptions_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_MethodOptions_default_instance_);_UninterpretedOption_NamePart_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_UninterpretedOption_NamePart_default_instance_);_UninterpretedOption_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_UninterpretedOption_default_instance_);_SourceCodeInfo_Location_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_SourceCodeInfo_Location_default_instance_);_SourceCodeInfo_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_SourceCodeInfo_default_instance_);_GeneratedCodeInfo_Annotation_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_GeneratedCodeInfo_Annotation_default_instance_);_GeneratedCodeInfo_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_GeneratedCodeInfo_default_instance_);_FileDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::FileOptions*>( ::google::protobuf::FileOptions::internal_default_instance()); - _FileDescriptorProto_default_instance_.get_mutable()->source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>( + _FileDescriptorProto_default_instance_._instance.get_mutable()->source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>( ::google::protobuf::SourceCodeInfo::internal_default_instance()); - _DescriptorProto_default_instance_.get_mutable()->options_ = const_cast< ::google::protobuf::MessageOptions*>( + _DescriptorProto_ExtensionRange_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::ExtensionRangeOptions*>( + ::google::protobuf::ExtensionRangeOptions::internal_default_instance()); + _DescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::MessageOptions*>( ::google::protobuf::MessageOptions::internal_default_instance()); - _FieldDescriptorProto_default_instance_.get_mutable()->options_ = const_cast< ::google::protobuf::FieldOptions*>( + _FieldDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::FieldOptions*>( ::google::protobuf::FieldOptions::internal_default_instance()); - _OneofDescriptorProto_default_instance_.get_mutable()->options_ = const_cast< ::google::protobuf::OneofOptions*>( + _OneofDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::OneofOptions*>( ::google::protobuf::OneofOptions::internal_default_instance()); - _EnumDescriptorProto_default_instance_.get_mutable()->options_ = const_cast< ::google::protobuf::EnumOptions*>( + _EnumDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::EnumOptions*>( ::google::protobuf::EnumOptions::internal_default_instance()); - _EnumValueDescriptorProto_default_instance_.get_mutable()->options_ = const_cast< ::google::protobuf::EnumValueOptions*>( + _EnumValueDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::EnumValueOptions*>( ::google::protobuf::EnumValueOptions::internal_default_instance()); - _ServiceDescriptorProto_default_instance_.get_mutable()->options_ = const_cast< ::google::protobuf::ServiceOptions*>( + _ServiceDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::ServiceOptions*>( ::google::protobuf::ServiceOptions::internal_default_instance()); - _MethodDescriptorProto_default_instance_.get_mutable()->options_ = const_cast< ::google::protobuf::MethodOptions*>( + _MethodDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::MethodOptions*>( ::google::protobuf::MethodOptions::internal_default_instance()); } @@ -666,7 +732,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n google/protobuf/descriptor.proto\022\017goog" "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file" "\030\001 \003(\0132$.google.protobuf.FileDescriptorP" @@ -682,7 +748,7 @@ void AddDescriptorsImpl() { "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File" "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog" "le.protobuf.SourceCodeInfo\022\016\n\006syntax\030\014 \001" - "(\t\"\360\004\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005" + "(\t\"\251\005\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005" "field\030\002 \003(\0132%.google.protobuf.FieldDescr" "iptorProto\0228\n\textension\030\006 \003(\0132%.google.p" "rotobuf.FieldDescriptorProto\0225\n\013nested_t" @@ -695,126 +761,129 @@ void AddDescriptorsImpl() { "ions\030\007 \001(\0132\037.google.protobuf.MessageOpti" "ons\022F\n\016reserved_range\030\t \003(\0132..google.pro" "tobuf.DescriptorProto.ReservedRange\022\025\n\rr" - "eserved_name\030\n \003(\t\032,\n\016ExtensionRange\022\r\n\005" - "start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\032+\n\rReservedRang" - "e\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\274\005\n\024FieldD" - "escriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\003" - " \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf.Fi" - "eldDescriptorProto.Label\0228\n\004type\030\005 \001(\0162*" - ".google.protobuf.FieldDescriptorProto.Ty" - "pe\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t\022" - "\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_index\030\t " - "\001(\005\022\021\n\tjson_name\030\n \001(\t\022.\n\007options\030\010 \001(\0132" - "\035.google.protobuf.FieldOptions\"\266\002\n\004Type\022" - "\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE" - "_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020" - "\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n" - "\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GR" - "OUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022" - "\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_" - "SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SI" - "NT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LABE" - "L_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABE" - "L_REPEATED\020\003\"T\n\024OneofDescriptorProto\022\014\n\004" - "name\030\001 \001(\t\022.\n\007options\030\002 \001(\0132\035.google.pro" - "tobuf.OneofOptions\"\214\001\n\023EnumDescriptorPro" - "to\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).google" - ".protobuf.EnumValueDescriptorProto\022-\n\007op" - "tions\030\003 \001(\0132\034.google.protobuf.EnumOption" - "s\"l\n\030EnumValueDescriptorProto\022\014\n\004name\030\001 " - "\001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.g" - "oogle.protobuf.EnumValueOptions\"\220\001\n\026Serv" - "iceDescriptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006meth" - "od\030\002 \003(\0132&.google.protobuf.MethodDescrip" - "torProto\0220\n\007options\030\003 \001(\0132\037.google.proto" - "buf.ServiceOptions\"\301\001\n\025MethodDescriptorP" - "roto\022\014\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023" - "\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.g" - "oogle.protobuf.MethodOptions\022\037\n\020client_s" - "treaming\030\005 \001(\010:\005false\022\037\n\020server_streamin" - "g\030\006 \001(\010:\005false\"\360\005\n\013FileOptions\022\024\n\014java_p" - "ackage\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001" - "(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022)" - "\n\035java_generate_equals_and_hash\030\024 \001(\010B\002\030" - "\001\022%\n\026java_string_check_utf8\030\033 \001(\010:\005false" - "\022F\n\014optimize_for\030\t \001(\0162).google.protobuf" - ".FileOptions.OptimizeMode:\005SPEED\022\022\n\ngo_p" - "ackage\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(" - "\010:\005false\022$\n\025java_generic_services\030\021 \001(\010:" - "\005false\022\"\n\023py_generic_services\030\022 \001(\010:\005fal" - "se\022#\n\024php_generic_services\030\023 \001(\010:\005false\022" - "\031\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enable_" - "arenas\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix" - "\030$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014swif" - "t_prefix\030\' \001(\t\022\030\n\020php_class_prefix\030( \001(\t" - "\022\025\n\rphp_namespace\030) \001(\t\022C\n\024uninterpreted" - "_option\030\347\007 \003(\0132$.google.protobuf.Uninter" - "pretedOption\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022" - "\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200" - "\200\200\002J\004\010&\020\'\"\362\001\n\016MessageOptions\022&\n\027message_" - "set_wire_format\030\001 \001(\010:\005false\022.\n\037no_stand" - "ard_descriptor_accessor\030\002 \001(\010:\005false\022\031\n\n" - "deprecated\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007 \001" - "(\010\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goog" - "le.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200" - "\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014FieldOptions\022:\n\005ctype" - "\030\001 \001(\0162#.google.protobuf.FieldOptions.CT" - "ype:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006jstype\030\006 " - "\001(\0162$.google.protobuf.FieldOptions.JSTyp" - "e:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\ndep" - "recated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005fals" - "e\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl" - "e.protobuf.UninterpretedOption\"/\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_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\014Oneof" - "Options\022C\n\024uninterpreted_option\030\347\007 \003(\0132$" - ".google.protobuf.UninterpretedOption*\t\010\350" - "\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013allow_alias\030\002" - " \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022C\n\024unint" + "eserved_name\030\n \003(\t\032e\n\016ExtensionRange\022\r\n\005" + "start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\0227\n\007options\030\003 \001(" + "\0132&.google.protobuf.ExtensionRangeOption" + "s\032+\n\rReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end" + "\030\002 \001(\005\"g\n\025ExtensionRangeOptions\022C\n\024unint" "erpreted_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:\005f" - "alse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go" + ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\274\005\n\024Fiel" + "dDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number" + "\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf." + "FieldDescriptorProto.Label\0228\n\004type\030\005 \001(\016" + "2*.google.protobuf.FieldDescriptorProto." + "Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(" + "\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_index\030" + "\t \001(\005\022\021\n\tjson_name\030\n \001(\t\022.\n\007options\030\010 \001(" + "\0132\035.google.protobuf.FieldOptions\"\266\002\n\004Typ" + "e\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTY" + "PE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT3" + "2\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022" + "\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_" + "GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020" + "\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYP" + "E_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_" + "SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LA" + "BEL_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LA" + "BEL_REPEATED\020\003\"T\n\024OneofDescriptorProto\022\014" + "\n\004name\030\001 \001(\t\022.\n\007options\030\002 \001(\0132\035.google.p" + "rotobuf.OneofOptions\"\214\001\n\023EnumDescriptorP" + "roto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).goog" + "le.protobuf.EnumValueDescriptorProto\022-\n\007" + "options\030\003 \001(\0132\034.google.protobuf.EnumOpti" + "ons\"l\n\030EnumValueDescriptorProto\022\014\n\004name\030" + "\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!" + ".google.protobuf.EnumValueOptions\"\220\001\n\026Se" + "rviceDescriptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006me" + "thod\030\002 \003(\0132&.google.protobuf.MethodDescr" + "iptorProto\0220\n\007options\030\003 \001(\0132\037.google.pro" + "tobuf.ServiceOptions\"\301\001\n\025MethodDescripto" + "rProto\022\014\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t" + "\022\023\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036" + ".google.protobuf.MethodOptions\022\037\n\020client" + "_streaming\030\005 \001(\010:\005false\022\037\n\020server_stream" + "ing\030\006 \001(\010:\005false\"\360\005\n\013FileOptions\022\024\n\014java" + "_package\030\001 \001(\t\022\034\n\024java_outer_classname\030\010" + " \001(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false" + "\022)\n\035java_generate_equals_and_hash\030\024 \001(\010B" + "\002\030\001\022%\n\026java_string_check_utf8\030\033 \001(\010:\005fal" + "se\022F\n\014optimize_for\030\t \001(\0162).google.protob" + "uf.FileOptions.OptimizeMode:\005SPEED\022\022\n\ngo" + "_package\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 " + "\001(\010:\005false\022$\n\025java_generic_services\030\021 \001(" + "\010:\005false\022\"\n\023py_generic_services\030\022 \001(\010:\005f" + "alse\022#\n\024php_generic_services\030\023 \001(\010:\005fals" + "e\022\031\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enabl" + "e_arenas\030\037 \001(\010:\005false\022\031\n\021objc_class_pref" + "ix\030$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014sw" + "ift_prefix\030\' \001(\t\022\030\n\020php_class_prefix\030( \001" + "(\t\022\025\n\rphp_namespace\030) \001(\t\022C\n\024uninterpret" + "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint" + "erpretedOption\":\n\014OptimizeMode\022\t\n\005SPEED\020" + "\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020" + "\200\200\200\200\002J\004\010&\020\'\"\362\001\n\016MessageOptions\022&\n\027messag" + "e_set_wire_format\030\001 \001(\010:\005false\022.\n\037no_sta" + "ndard_descriptor_accessor\030\002 \001(\010:\005false\022\031" + "\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007" + " \001(\010\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go" "ogle.protobuf.UninterpretedOption*\t\010\350\007\020\200" - "\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprecated\030! \001" - "(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\013" + "\200\200\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014FieldOptions\022:\n\005cty" + "pe\030\001 \001(\0162#.google.protobuf.FieldOptions." + "CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006jstype\030" + "\006 \001(\0162$.google.protobuf.FieldOptions.JST" + "ype:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\nd" + "eprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005fa" + "lse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo" + "gle.protobuf.UninterpretedOption\"/\n\005CTyp" + "e\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_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\014One" + "ofOptions\022C\n\024uninterpreted_option\030\347\007 \003(\013" "2$.google.protobuf.UninterpretedOption*\t" - "\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\ndeprecate" - "d\030! \001(\010:\005false\022_\n\021idempotency_level\030\" \001(" - "\0162/.google.protobuf.MethodOptions.Idempo" - "tencyLevel:\023IDEMPOTENCY_UNKNOWN\022C\n\024unint" - "erpreted_option\030\347\007 \003(\0132$.google.protobuf" - ".UninterpretedOption\"P\n\020IdempotencyLevel" - "\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_SIDE_EFF" - "ECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023Un" - "interpretedOption\022;\n\004name\030\002 \003(\0132-.google" - ".protobuf.UninterpretedOption.NamePart\022\030" - "\n\020identifier_value\030\003 \001(\t\022\032\n\022positive_int" - "_value\030\004 \001(\004\022\032\n\022negative_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_value\030\010 \001(\t\0323\n\010NamePar" - "t\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002" - "(\010\"\325\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003(\0132" - "(.google.protobuf.SourceCodeInfo.Locatio" - "n\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\021" - "trailing_comments\030\004 \001(\t\022!\n\031leading_detac" - "hed_comments\030\006 \003(\t\"\247\001\n\021GeneratedCodeInfo" - "\022A\n\nannotation\030\001 \003(\0132-.google.protobuf.G" - "eneratedCodeInfo.Annotation\032O\n\nAnnotatio" - "n\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_file\030\002 \001(\t" - "\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\214\001\n\023com.goo" - "gle.protobufB\020DescriptorProtosH\001Z>github" - ".com/golang/protobuf/protoc-gen-go/descr" - "iptor;descriptor\242\002\003GPB\252\002\032Google.Protobuf" - ".Reflection" + "\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013allow_alias" + "\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022C\n\024uni" + "nterpreted_option\030\347\007 \003(\0132$.google.protob" + "uf.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\024uninterpreted_option\030\347\007 \003(\0132$." + "google.protobuf.UninterpretedOption*\t\010\350\007" + "\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprecated\030!" + " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003" + "(\0132$.google.protobuf.UninterpretedOption" + "*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\ndepreca" + "ted\030! \001(\010:\005false\022_\n\021idempotency_level\030\" " + "\001(\0162/.google.protobuf.MethodOptions.Idem" + "potencyLevel:\023IDEMPOTENCY_UNKNOWN\022C\n\024uni" + "nterpreted_option\030\347\007 \003(\0132$.google.protob" + "uf.UninterpretedOption\"P\n\020IdempotencyLev" + "el\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_SIDE_E" + "FFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023" + "UninterpretedOption\022;\n\004name\030\002 \003(\0132-.goog" + "le.protobuf.UninterpretedOption.NamePart" + "\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022positive_i" + "nt_value\030\004 \001(\004\022\032\n\022negative_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_value\030\010 \001(\t\0323\n\010NameP" + "art\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002" + " \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003(" + "\0132(.google.protobuf.SourceCodeInfo.Locat" + "ion\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004sp" + "an\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031" + "\n\021trailing_comments\030\004 \001(\t\022!\n\031leading_det" + "ached_comments\030\006 \003(\t\"\247\001\n\021GeneratedCodeIn" + "fo\022A\n\nannotation\030\001 \003(\0132-.google.protobuf" + ".GeneratedCodeInfo.Annotation\032O\n\nAnnotat" + "ion\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_file\030\002 \001" + "(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\214\001\n\023com.g" + "oogle.protobufB\020DescriptorProtosH\001Z>gith" + "ub.com/golang/protobuf/protoc-gen-go/des" + "criptor;descriptor\242\002\003GPB\252\002\032Google.Protob" + "uf.Reflection" }; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - descriptor, 5651); + descriptor, 5813); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -1061,6 +1130,10 @@ FileDescriptorSet* FileDescriptorSet::New(::google::protobuf::Arena* arena) cons void FileDescriptorSet::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + file_.Clear(); _has_bits_.Clear(); _internal_metadata_.Clear(); @@ -1079,7 +1152,7 @@ bool FileDescriptorSet::MergePartialFromCodedStream( // repeated .google.protobuf.FileDescriptorProto file = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_file())); } else { @@ -1090,13 +1163,11 @@ bool FileDescriptorSet::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1125,7 +1196,7 @@ void FileDescriptorSet::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorSet) } @@ -1147,7 +1218,7 @@ void FileDescriptorSet::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorSet) return target; @@ -1160,7 +1231,7 @@ size_t FileDescriptorSet::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.FileDescriptorProto file = 1; { @@ -1229,10 +1300,11 @@ void FileDescriptorSet::Swap(FileDescriptorSet* other) { InternalSwap(other); } void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) { + using std::swap; file_.InternalSwap(&other->file_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const { @@ -1357,12 +1429,8 @@ void FileDescriptorProto::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); syntax_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete options_; - } - if (this != internal_default_instance()) { - delete source_code_info_; - } + if (this != internal_default_instance()) delete options_; + if (this != internal_default_instance()) delete source_code_info_; } void FileDescriptorProto::SetCachedSize(int size) const { @@ -1390,6 +1458,10 @@ FileDescriptorProto* FileDescriptorProto::New(::google::protobuf::Arena* arena) void FileDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + dependency_.Clear(); message_type_.Clear(); enum_type_.Clear(); @@ -1397,24 +1469,25 @@ void FileDescriptorProto::Clear() { extension_.Clear(); public_dependency_.Clear(); weak_dependency_.Clear(); - if (_has_bits_[0 / 32] & 31u) { - if (has_name()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 31u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_package()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(!package_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*package_.UnsafeRawStringPointer())->clear(); } - if (has_syntax()) { + if (cached_has_bits & 0x00000004u) { GOOGLE_DCHECK(!syntax_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*syntax_.UnsafeRawStringPointer())->clear(); } - if (has_options()) { + if (cached_has_bits & 0x00000008u) { GOOGLE_DCHECK(options_ != NULL); options_->::google::protobuf::FileOptions::Clear(); } - if (has_source_code_info()) { + if (cached_has_bits & 0x00000010u) { GOOGLE_DCHECK(source_code_info_ != NULL); source_code_info_->::google::protobuf::SourceCodeInfo::Clear(); } @@ -1436,7 +1509,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -1452,7 +1525,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // optional string package = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_package())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -1468,7 +1541,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated string dependency = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->add_dependency())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -1485,7 +1558,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto message_type = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_message_type())); } else { @@ -1497,7 +1570,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(42u)) { + static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_enum_type())); } else { @@ -1509,7 +1582,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.ServiceDescriptorProto service = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(50u)) { + static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_service())); } else { @@ -1521,7 +1594,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.FieldDescriptorProto extension = 7; case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(58u)) { + static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_extension())); } else { @@ -1533,7 +1606,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.FileOptions options = 8; case 8: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(66u)) { + static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); } else { @@ -1545,7 +1618,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.SourceCodeInfo source_code_info = 9; case 9: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(74u)) { + static_cast< ::google::protobuf::uint8>(74u /* 74 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_source_code_info())); } else { @@ -1557,12 +1630,13 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated int32 public_dependency = 10; case 10: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(80u)) { + static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( 1, 80u, input, this->mutable_public_dependency()))); - } else if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(82u)) { + } else if ( + static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, this->mutable_public_dependency()))); @@ -1575,12 +1649,13 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // repeated int32 weak_dependency = 11; case 11: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(88u)) { + static_cast< ::google::protobuf::uint8>(88u /* 88 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( 1, 88u, input, this->mutable_weak_dependency()))); - } else if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(90u)) { + } else if ( + static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, this->mutable_weak_dependency()))); @@ -1593,7 +1668,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( // optional string syntax = 12; case 12: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(98u)) { + static_cast< ::google::protobuf::uint8>(98u /* 98 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_syntax())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -1608,13 +1683,11 @@ bool FileDescriptorProto::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1729,7 +1802,7 @@ void FileDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorProto) } @@ -1841,7 +1914,7 @@ void FileDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorProto) return target; @@ -1854,7 +1927,7 @@ size_t FileDescriptorProto::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated string dependency = 3; total_size += 1 * @@ -2052,6 +2125,7 @@ void FileDescriptorProto::Swap(FileDescriptorProto* other) { InternalSwap(other); } void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { + using std::swap; dependency_.InternalSwap(&other->dependency_); message_type_.InternalSwap(&other->message_type_); enum_type_.InternalSwap(&other->enum_type_); @@ -2062,11 +2136,11 @@ void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { name_.Swap(&other->name_); package_.Swap(&other->package_); syntax_.Swap(&other->syntax_); - std::swap(options_, other->options_); - std::swap(source_code_info_, other->source_code_info_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(options_, other->options_); + swap(source_code_info_, other->source_code_info_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const { @@ -2467,9 +2541,10 @@ void FileDescriptorProto::clear_options() { clear_has_options(); } const ::google::protobuf::FileOptions& FileDescriptorProto::options() const { + const ::google::protobuf::FileOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::FileOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::FileOptions*>( + &::google::protobuf::_FileOptions_default_instance_); } ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() { set_has_options(); @@ -2512,9 +2587,10 @@ void FileDescriptorProto::clear_source_code_info() { clear_has_source_code_info(); } const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const { + const ::google::protobuf::SourceCodeInfo* p = source_code_info_; // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info) - return source_code_info_ != NULL ? *source_code_info_ - : *::google::protobuf::SourceCodeInfo::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::SourceCodeInfo*>( + &::google::protobuf::_SourceCodeInfo_default_instance_); } ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() { set_has_source_code_info(); @@ -2612,6 +2688,7 @@ void FileDescriptorProto::set_allocated_syntax(::std::string* syntax) { #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int DescriptorProto_ExtensionRange::kStartFieldNumber; const int DescriptorProto_ExtensionRange::kEndFieldNumber; +const int DescriptorProto_ExtensionRange::kOptionsFieldNumber; #endif // !defined(_MSC_VER) || _MSC_VER >= 1900 DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() @@ -2628,6 +2705,11 @@ DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorP _has_bits_(from._has_bits_), _cached_size_(0) { _internal_metadata_.MergeFrom(from._internal_metadata_); + if (from.has_options()) { + options_ = new ::google::protobuf::ExtensionRangeOptions(*from.options_); + } else { + options_ = NULL; + } ::memcpy(&start_, &from.start_, static_cast<size_t>(reinterpret_cast<char*>(&end_) - reinterpret_cast<char*>(&start_)) + sizeof(end_)); @@ -2636,9 +2718,9 @@ DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorP void DescriptorProto_ExtensionRange::SharedCtor() { _cached_size_ = 0; - ::memset(&start_, 0, static_cast<size_t>( + ::memset(&options_, 0, static_cast<size_t>( reinterpret_cast<char*>(&end_) - - reinterpret_cast<char*>(&start_)) + sizeof(end_)); + reinterpret_cast<char*>(&options_)) + sizeof(end_)); } DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() { @@ -2647,6 +2729,7 @@ DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() { } void DescriptorProto_ExtensionRange::SharedDtor() { + if (this != internal_default_instance()) delete options_; } void DescriptorProto_ExtensionRange::SetCachedSize(int size) const { @@ -2674,7 +2757,16 @@ DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New(::google::pr void DescriptorProto_ExtensionRange::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange) - if (_has_bits_[0 / 32] & 3u) { + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + if (has_options()) { + GOOGLE_DCHECK(options_ != NULL); + options_->::google::protobuf::ExtensionRangeOptions::Clear(); + } + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 6u) { ::memset(&start_, 0, static_cast<size_t>( reinterpret_cast<char*>(&end_) - reinterpret_cast<char*>(&start_)) + sizeof(end_)); @@ -2696,7 +2788,7 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( // optional int32 start = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { set_has_start(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -2710,7 +2802,7 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( // optional int32 end = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { set_has_end(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -2721,15 +2813,25 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( break; } + // optional .google.protobuf.ExtensionRangeOptions options = 3; + case 3: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_options())); + } else { + goto handle_unusual; + } + break; + } + default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -2751,18 +2853,24 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( cached_has_bits = _has_bits_[0]; // optional int32 start = 1; - if (cached_has_bits & 0x00000001u) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output); } // optional int32 end = 2; - if (cached_has_bits & 0x00000002u) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output); } + // optional .google.protobuf.ExtensionRangeOptions options = 3; + if (cached_has_bits & 0x00000001u) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, *this->options_, output); + } + if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ExtensionRange) } @@ -2776,18 +2884,25 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( cached_has_bits = _has_bits_[0]; // optional int32 start = 1; - if (cached_has_bits & 0x00000001u) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target); } // optional int32 end = 2; - if (cached_has_bits & 0x00000002u) { + if (cached_has_bits & 0x00000004u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target); } + // optional .google.protobuf.ExtensionRangeOptions options = 3; + if (cached_has_bits & 0x00000001u) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageNoVirtualToArray( + 3, *this->options_, deterministic, target); + } + if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ExtensionRange) return target; @@ -2800,9 +2915,16 @@ size_t DescriptorProto_ExtensionRange::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } - if (_has_bits_[0 / 32] & 3u) { + if (_has_bits_[0 / 32] & 7u) { + // optional .google.protobuf.ExtensionRangeOptions options = 3; + if (has_options()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->options_); + } + // optional int32 start = 1; if (has_start()) { total_size += 1 + @@ -2848,11 +2970,14 @@ void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRa (void) cached_has_bits; cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 3u) { + if (cached_has_bits & 7u) { if (cached_has_bits & 0x00000001u) { - start_ = from.start_; + mutable_options()->::google::protobuf::ExtensionRangeOptions::MergeFrom(from.options()); } if (cached_has_bits & 0x00000002u) { + start_ = from.start_; + } + if (cached_has_bits & 0x00000004u) { end_ = from.end_; } _has_bits_[0] |= cached_has_bits; @@ -2874,6 +2999,9 @@ void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRan } bool DescriptorProto_ExtensionRange::IsInitialized() const { + if (has_options()) { + if (!this->options_->IsInitialized()) return false; + } return true; } @@ -2882,11 +3010,13 @@ void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) InternalSwap(other); } void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* other) { - std::swap(start_, other->start_); - std::swap(end_, other->end_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + using std::swap; + swap(options_, other->options_); + swap(start_, other->start_); + swap(end_, other->end_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const { @@ -2899,13 +3029,13 @@ void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange // optional int32 start = 1; bool DescriptorProto_ExtensionRange::has_start() const { - return (_has_bits_[0] & 0x00000001u) != 0; + return (_has_bits_[0] & 0x00000002u) != 0; } void DescriptorProto_ExtensionRange::set_has_start() { - _has_bits_[0] |= 0x00000001u; + _has_bits_[0] |= 0x00000002u; } void DescriptorProto_ExtensionRange::clear_has_start() { - _has_bits_[0] &= ~0x00000001u; + _has_bits_[0] &= ~0x00000002u; } void DescriptorProto_ExtensionRange::clear_start() { start_ = 0; @@ -2923,13 +3053,13 @@ void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) // optional int32 end = 2; bool DescriptorProto_ExtensionRange::has_end() const { - return (_has_bits_[0] & 0x00000002u) != 0; + return (_has_bits_[0] & 0x00000004u) != 0; } void DescriptorProto_ExtensionRange::set_has_end() { - _has_bits_[0] |= 0x00000002u; + _has_bits_[0] |= 0x00000004u; } void DescriptorProto_ExtensionRange::clear_has_end() { - _has_bits_[0] &= ~0x00000002u; + _has_bits_[0] &= ~0x00000004u; } void DescriptorProto_ExtensionRange::clear_end() { end_ = 0; @@ -2945,6 +3075,52 @@ void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) { // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end) } +// optional .google.protobuf.ExtensionRangeOptions options = 3; +bool DescriptorProto_ExtensionRange::has_options() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void DescriptorProto_ExtensionRange::set_has_options() { + _has_bits_[0] |= 0x00000001u; +} +void DescriptorProto_ExtensionRange::clear_has_options() { + _has_bits_[0] &= ~0x00000001u; +} +void DescriptorProto_ExtensionRange::clear_options() { + if (options_ != NULL) options_->::google::protobuf::ExtensionRangeOptions::Clear(); + clear_has_options(); +} +const ::google::protobuf::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const { + const ::google::protobuf::ExtensionRangeOptions* p = options_; + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.options) + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::ExtensionRangeOptions*>( + &::google::protobuf::_ExtensionRangeOptions_default_instance_); +} +::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::ExtensionRangeOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.ExtensionRange.options) + return options_; +} +::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.ExtensionRange.options) + clear_has_options(); + ::google::protobuf::ExtensionRangeOptions* temp = options_; + options_ = NULL; + return temp; +} +void DescriptorProto_ExtensionRange::set_allocated_options(::google::protobuf::ExtensionRangeOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options) +} + #endif // PROTOBUF_INLINE_NOT_IN_HEADERS // =================================================================== @@ -3014,7 +3190,12 @@ DescriptorProto_ReservedRange* DescriptorProto_ReservedRange::New(::google::prot void DescriptorProto_ReservedRange::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange) - if (_has_bits_[0 / 32] & 3u) { + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { ::memset(&start_, 0, static_cast<size_t>( reinterpret_cast<char*>(&end_) - reinterpret_cast<char*>(&start_)) + sizeof(end_)); @@ -3036,7 +3217,7 @@ bool DescriptorProto_ReservedRange::MergePartialFromCodedStream( // optional int32 start = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { set_has_start(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -3050,7 +3231,7 @@ bool DescriptorProto_ReservedRange::MergePartialFromCodedStream( // optional int32 end = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { set_has_end(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -3063,13 +3244,11 @@ bool DescriptorProto_ReservedRange::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -3102,7 +3281,7 @@ void DescriptorProto_ReservedRange::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ReservedRange) } @@ -3127,7 +3306,7 @@ void DescriptorProto_ReservedRange::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ReservedRange) return target; @@ -3140,7 +3319,7 @@ size_t DescriptorProto_ReservedRange::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (_has_bits_[0 / 32] & 3u) { // optional int32 start = 1; @@ -3222,11 +3401,12 @@ void DescriptorProto_ReservedRange::Swap(DescriptorProto_ReservedRange* other) { InternalSwap(other); } void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* other) { - std::swap(start_, other->start_); - std::swap(end_, other->end_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + using std::swap; + swap(start_, other->start_); + swap(end_, other->end_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata DescriptorProto_ReservedRange::GetMetadata() const { @@ -3349,9 +3529,7 @@ DescriptorProto::~DescriptorProto() { void DescriptorProto::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete options_; - } + if (this != internal_default_instance()) delete options_; } void DescriptorProto::SetCachedSize(int size) const { @@ -3379,6 +3557,10 @@ DescriptorProto* DescriptorProto::New(::google::protobuf::Arena* arena) const { void DescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + field_.Clear(); nested_type_.Clear(); enum_type_.Clear(); @@ -3387,12 +3569,13 @@ void DescriptorProto::Clear() { oneof_decl_.Clear(); reserved_range_.Clear(); reserved_name_.Clear(); - if (_has_bits_[0 / 32] & 3u) { - if (has_name()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_options()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(options_ != NULL); options_->::google::protobuf::MessageOptions::Clear(); } @@ -3414,7 +3597,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -3430,7 +3613,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.FieldDescriptorProto field = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_field())); } else { @@ -3442,7 +3625,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto nested_type = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_nested_type())); } else { @@ -3454,7 +3637,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_enum_type())); } else { @@ -3466,7 +3649,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(42u)) { + static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_extension_range())); } else { @@ -3478,7 +3661,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.FieldDescriptorProto extension = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(50u)) { + static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_extension())); } else { @@ -3490,7 +3673,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.MessageOptions options = 7; case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(58u)) { + static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); } else { @@ -3502,7 +3685,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; case 8: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(66u)) { + static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_oneof_decl())); } else { @@ -3514,7 +3697,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; case 9: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(74u)) { + static_cast< ::google::protobuf::uint8>(74u /* 74 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_reserved_range())); } else { @@ -3526,7 +3709,7 @@ bool DescriptorProto::MergePartialFromCodedStream( // repeated string reserved_name = 10; case 10: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(82u)) { + static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->add_reserved_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -3542,13 +3725,11 @@ bool DescriptorProto::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -3646,7 +3827,7 @@ void DescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto) } @@ -3745,7 +3926,7 @@ void DescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto) return target; @@ -3758,7 +3939,7 @@ size_t DescriptorProto::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.FieldDescriptorProto field = 2; { @@ -3928,6 +4109,7 @@ bool DescriptorProto::IsInitialized() const { if (!::google::protobuf::internal::AllAreInitialized(this->field())) 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_range())) return false; if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false; if (!::google::protobuf::internal::AllAreInitialized(this->oneof_decl())) return false; if (has_options()) { @@ -3941,6 +4123,7 @@ void DescriptorProto::Swap(DescriptorProto* other) { InternalSwap(other); } void DescriptorProto::InternalSwap(DescriptorProto* other) { + using std::swap; field_.InternalSwap(&other->field_); nested_type_.InternalSwap(&other->nested_type_); enum_type_.InternalSwap(&other->enum_type_); @@ -3950,10 +4133,10 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { 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]); + swap(options_, other->options_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata DescriptorProto::GetMetadata() const { @@ -4222,9 +4405,10 @@ void DescriptorProto::clear_options() { clear_has_options(); } const ::google::protobuf::MessageOptions& DescriptorProto::options() const { + const ::google::protobuf::MessageOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::MessageOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::MessageOptions*>( + &::google::protobuf::_MessageOptions_default_instance_); } ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() { set_has_options(); @@ -4356,6 +4540,308 @@ DescriptorProto::mutable_reserved_name() { // =================================================================== #if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int ExtensionRangeOptions::kUninterpretedOptionFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +ExtensionRangeOptions::ExtensionRangeOptions() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { + protobuf_google_2fprotobuf_2fdescriptor_2eproto::InitDefaults(); + } + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.ExtensionRangeOptions) +} +ExtensionRangeOptions::ExtensionRangeOptions(const ExtensionRangeOptions& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL), + _has_bits_(from._has_bits_), + _cached_size_(0), + uninterpreted_option_(from.uninterpreted_option_) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + _extensions_.MergeFrom(from._extensions_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions) +} + +void ExtensionRangeOptions::SharedCtor() { + _cached_size_ = 0; +} + +ExtensionRangeOptions::~ExtensionRangeOptions() { + // @@protoc_insertion_point(destructor:google.protobuf.ExtensionRangeOptions) + SharedDtor(); +} + +void ExtensionRangeOptions::SharedDtor() { +} + +void ExtensionRangeOptions::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ExtensionRangeOptions::descriptor() { + protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; +} + +const ExtensionRangeOptions& ExtensionRangeOptions::default_instance() { + protobuf_google_2fprotobuf_2fdescriptor_2eproto::InitDefaults(); + return *internal_default_instance(); +} + +ExtensionRangeOptions* ExtensionRangeOptions::New(::google::protobuf::Arena* arena) const { + ExtensionRangeOptions* n = new ExtensionRangeOptions; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void ExtensionRangeOptions::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _extensions_.Clear(); + uninterpreted_option_.Clear(); + _has_bits_.Clear(); + _internal_metadata_.Clear(); +} + +bool ExtensionRangeOptions::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.ExtensionRangeOptions) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + case 999: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_uninterpreted_option())); + } else { + goto handle_unusual; + } + break; + } + + default: { + handle_unusual: + if (tag == 0) { + goto success; + } + if ((8000u <= tag)) { + DO_(_extensions_.ParseField(tag, input, + internal_default_instance(), + _internal_metadata_.mutable_unknown_fields())); + continue; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.ExtensionRangeOptions) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.ExtensionRangeOptions) + return false; +#undef DO_ +} + +void ExtensionRangeOptions::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.ExtensionRangeOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 999, this->uninterpreted_option(static_cast<int>(i)), output); + } + + // Extension range [1000, 536870912) + _extensions_.SerializeWithCachedSizes( + 1000, 536870912, output); + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + _internal_metadata_.unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:google.protobuf.ExtensionRangeOptions) +} + +::google::protobuf::uint8* ExtensionRangeOptions::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + (void)deterministic; // Unused + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ExtensionRangeOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->uninterpreted_option_size()); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageNoVirtualToArray( + 999, this->uninterpreted_option(static_cast<int>(i)), deterministic, target); + } + + // Extension range [1000, 536870912) + target = _extensions_.InternalSerializeWithCachedSizesToArray( + 1000, 536870912, deterministic, target); + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ExtensionRangeOptions) + return target; +} + +size_t ExtensionRangeOptions::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ExtensionRangeOptions) + size_t total_size = 0; + + total_size += _extensions_.ByteSize(); + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + _internal_metadata_.unknown_fields()); + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; + { + unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size()); + total_size += 2UL * count; + for (unsigned int i = 0; i < count; i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->uninterpreted_option(static_cast<int>(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 ExtensionRangeOptions::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ExtensionRangeOptions) + GOOGLE_DCHECK_NE(&from, this); + const ExtensionRangeOptions* source = + ::google::protobuf::internal::DynamicCastToGenerated<const ExtensionRangeOptions>( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.ExtensionRangeOptions) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.ExtensionRangeOptions) + MergeFrom(*source); + } +} + +void ExtensionRangeOptions::MergeFrom(const ExtensionRangeOptions& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions) + 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_); +} + +void ExtensionRangeOptions::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.ExtensionRangeOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ExtensionRangeOptions::CopyFrom(const ExtensionRangeOptions& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ExtensionRangeOptions) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ExtensionRangeOptions::IsInitialized() const { + if (!_extensions_.IsInitialized()) { + return false; + } + + if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false; + return true; +} + +void ExtensionRangeOptions::Swap(ExtensionRangeOptions* other) { + if (other == this) return; + InternalSwap(other); +} +void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* other) { + using std::swap; + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); + swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); + _extensions_.Swap(&other->_extensions_); +} + +::google::protobuf::Metadata ExtensionRangeOptions::GetMetadata() const { + protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// ExtensionRangeOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +int ExtensionRangeOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +void ExtensionRangeOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +const ::google::protobuf::UninterpretedOption& ExtensionRangeOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +::google::protobuf::UninterpretedOption* ExtensionRangeOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +::google::protobuf::UninterpretedOption* ExtensionRangeOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +ExtensionRangeOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return &uninterpreted_option_; +} +const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +ExtensionRangeOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#if !defined(_MSC_VER) || _MSC_VER >= 1900 const int FieldDescriptorProto::kNameFieldNumber; const int FieldDescriptorProto::kNumberFieldNumber; const int FieldDescriptorProto::kLabelFieldNumber; @@ -4438,9 +4924,7 @@ void FieldDescriptorProto::SharedDtor() { 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()) { - delete options_; - } + if (this != internal_default_instance()) delete options_; } void FieldDescriptorProto::SetCachedSize(int size) const { @@ -4468,38 +4952,43 @@ FieldDescriptorProto* FieldDescriptorProto::New(::google::protobuf::Arena* arena void FieldDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto) - if (_has_bits_[0 / 32] & 63u) { - if (has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 63u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_extendee()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(!extendee_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*extendee_.UnsafeRawStringPointer())->clear(); } - if (has_type_name()) { + if (cached_has_bits & 0x00000004u) { GOOGLE_DCHECK(!type_name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*type_name_.UnsafeRawStringPointer())->clear(); } - if (has_default_value()) { + if (cached_has_bits & 0x00000008u) { GOOGLE_DCHECK(!default_value_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*default_value_.UnsafeRawStringPointer())->clear(); } - if (has_json_name()) { + if (cached_has_bits & 0x00000010u) { GOOGLE_DCHECK(!json_name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*json_name_.UnsafeRawStringPointer())->clear(); } - if (has_options()) { + if (cached_has_bits & 0x00000020u) { GOOGLE_DCHECK(options_ != NULL); options_->::google::protobuf::FieldOptions::Clear(); } } - if (_has_bits_[0 / 32] & 192u) { + if (cached_has_bits & 192u) { ::memset(&number_, 0, static_cast<size_t>( reinterpret_cast<char*>(&oneof_index_) - reinterpret_cast<char*>(&number_)) + sizeof(oneof_index_)); } - if (_has_bits_[8 / 32] & 768u) { + if (cached_has_bits & 768u) { label_ = 1; type_ = 1; } @@ -4520,7 +5009,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -4536,7 +5025,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional string extendee = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_extendee())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -4552,7 +5041,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional int32 number = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { + static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) { set_has_number(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -4566,7 +5055,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.FieldDescriptorProto.Label label = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(32u)) { + static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -4586,7 +5075,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.FieldDescriptorProto.Type type = 5; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(40u)) { + static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -4606,7 +5095,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional string type_name = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(50u)) { + static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_type_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -4622,7 +5111,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional string default_value = 7; case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(58u)) { + static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_default_value())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -4638,7 +5127,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.FieldOptions options = 8; case 8: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(66u)) { + static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); } else { @@ -4650,7 +5139,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional int32 oneof_index = 9; case 9: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(72u)) { + static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) { set_has_oneof_index(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -4664,7 +5153,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( // optional string json_name = 10; case 10: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(82u)) { + static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_json_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -4679,13 +5168,11 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -4786,7 +5273,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.FieldDescriptorProto) } @@ -4885,7 +5372,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldDescriptorProto) return target; @@ -4898,7 +5385,7 @@ size_t FieldDescriptorProto::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (_has_bits_[0 / 32] & 255u) { // optional string name = 1; @@ -5071,19 +5558,20 @@ void FieldDescriptorProto::Swap(FieldDescriptorProto* other) { InternalSwap(other); } void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { + using std::swap; name_.Swap(&other->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_); - std::swap(number_, other->number_); - std::swap(oneof_index_, other->oneof_index_); - std::swap(label_, other->label_); - std::swap(type_, other->type_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(options_, other->options_); + swap(number_, other->number_); + swap(oneof_index_, other->oneof_index_); + swap(label_, other->label_); + swap(type_, other->type_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const { @@ -5522,9 +6010,10 @@ void FieldDescriptorProto::clear_options() { clear_has_options(); } const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const { + const ::google::protobuf::FieldOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::FieldOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::FieldOptions*>( + &::google::protobuf::_FieldOptions_default_instance_); } ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() { set_has_options(); @@ -5600,9 +6089,7 @@ OneofDescriptorProto::~OneofDescriptorProto() { void OneofDescriptorProto::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete options_; - } + if (this != internal_default_instance()) delete options_; } void OneofDescriptorProto::SetCachedSize(int size) const { @@ -5630,12 +6117,17 @@ OneofDescriptorProto* OneofDescriptorProto::New(::google::protobuf::Arena* arena void OneofDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto) - if (_has_bits_[0 / 32] & 3u) { - if (has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_options()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(options_ != NULL); options_->::google::protobuf::OneofOptions::Clear(); } @@ -5657,7 +6149,7 @@ bool OneofDescriptorProto::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -5673,7 +6165,7 @@ bool OneofDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.OneofOptions options = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); } else { @@ -5684,13 +6176,11 @@ bool OneofDescriptorProto::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -5729,7 +6219,7 @@ void OneofDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.OneofDescriptorProto) } @@ -5762,7 +6252,7 @@ void OneofDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofDescriptorProto) return target; @@ -5775,7 +6265,7 @@ size_t OneofDescriptorProto::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (_has_bits_[0 / 32] & 3u) { // optional string name = 1; @@ -5860,11 +6350,12 @@ void OneofDescriptorProto::Swap(OneofDescriptorProto* other) { InternalSwap(other); } void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) { + using std::swap; name_.Swap(&other->name_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(options_, other->options_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const { @@ -5953,9 +6444,10 @@ void OneofDescriptorProto::clear_options() { clear_has_options(); } const ::google::protobuf::OneofOptions& OneofDescriptorProto::options() const { + const ::google::protobuf::OneofOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::OneofOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::OneofOptions*>( + &::google::protobuf::_OneofOptions_default_instance_); } ::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() { set_has_options(); @@ -6033,9 +6525,7 @@ EnumDescriptorProto::~EnumDescriptorProto() { void EnumDescriptorProto::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete options_; - } + if (this != internal_default_instance()) delete options_; } void EnumDescriptorProto::SetCachedSize(int size) const { @@ -6063,13 +6553,18 @@ EnumDescriptorProto* EnumDescriptorProto::New(::google::protobuf::Arena* arena) void EnumDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_.Clear(); - if (_has_bits_[0 / 32] & 3u) { - if (has_name()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_options()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(options_ != NULL); options_->::google::protobuf::EnumOptions::Clear(); } @@ -6091,7 +6586,7 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -6107,7 +6602,7 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.EnumValueDescriptorProto value = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_value())); } else { @@ -6119,7 +6614,7 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.EnumOptions options = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); } else { @@ -6130,13 +6625,11 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -6182,7 +6675,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.EnumDescriptorProto) } @@ -6223,7 +6716,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto) return target; @@ -6236,7 +6729,7 @@ size_t EnumDescriptorProto::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.EnumValueDescriptorProto value = 2; { @@ -6334,12 +6827,13 @@ void EnumDescriptorProto::Swap(EnumDescriptorProto* other) { InternalSwap(other); } void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) { + using std::swap; value_.InternalSwap(&other->value_); name_.Swap(&other->name_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(options_, other->options_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const { @@ -6458,9 +6952,10 @@ void EnumDescriptorProto::clear_options() { clear_has_options(); } const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const { + const ::google::protobuf::EnumOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::EnumOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::EnumOptions*>( + &::google::protobuf::_EnumOptions_default_instance_); } ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() { set_has_options(); @@ -6540,9 +7035,7 @@ EnumValueDescriptorProto::~EnumValueDescriptorProto() { void EnumValueDescriptorProto::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete options_; - } + if (this != internal_default_instance()) delete options_; } void EnumValueDescriptorProto::SetCachedSize(int size) const { @@ -6570,12 +7063,17 @@ EnumValueDescriptorProto* EnumValueDescriptorProto::New(::google::protobuf::Aren void EnumValueDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto) - if (_has_bits_[0 / 32] & 3u) { - if (has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_options()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(options_ != NULL); options_->::google::protobuf::EnumValueOptions::Clear(); } @@ -6598,7 +7096,7 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -6614,7 +7112,7 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( // optional int32 number = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { set_has_number(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -6628,7 +7126,7 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.EnumValueOptions options = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); } else { @@ -6639,13 +7137,11 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -6689,7 +7185,7 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueDescriptorProto) } @@ -6727,7 +7223,7 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueDescriptorProto) return target; @@ -6740,7 +7236,7 @@ size_t EnumValueDescriptorProto::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (_has_bits_[0 / 32] & 7u) { // optional string name = 1; @@ -6836,12 +7332,13 @@ void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) { InternalSwap(other); } void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) { + using std::swap; name_.Swap(&other->name_); - std::swap(options_, other->options_); - std::swap(number_, other->number_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(options_, other->options_); + swap(number_, other->number_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const { @@ -6954,9 +7451,10 @@ void EnumValueDescriptorProto::clear_options() { clear_has_options(); } const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const { + const ::google::protobuf::EnumValueOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::EnumValueOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::EnumValueOptions*>( + &::google::protobuf::_EnumValueOptions_default_instance_); } ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() { set_has_options(); @@ -7034,9 +7532,7 @@ ServiceDescriptorProto::~ServiceDescriptorProto() { void ServiceDescriptorProto::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete options_; - } + if (this != internal_default_instance()) delete options_; } void ServiceDescriptorProto::SetCachedSize(int size) const { @@ -7064,13 +7560,18 @@ ServiceDescriptorProto* ServiceDescriptorProto::New(::google::protobuf::Arena* a void ServiceDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + method_.Clear(); - if (_has_bits_[0 / 32] & 3u) { - if (has_name()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_options()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(options_ != NULL); options_->::google::protobuf::ServiceOptions::Clear(); } @@ -7092,7 +7593,7 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -7108,7 +7609,7 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( // repeated .google.protobuf.MethodDescriptorProto method = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_method())); } else { @@ -7120,7 +7621,7 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.ServiceOptions options = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); } else { @@ -7131,13 +7632,11 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -7183,7 +7682,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceDescriptorProto) } @@ -7224,7 +7723,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceDescriptorProto) return target; @@ -7237,7 +7736,7 @@ size_t ServiceDescriptorProto::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.MethodDescriptorProto method = 2; { @@ -7335,12 +7834,13 @@ void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) { InternalSwap(other); } void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) { + using std::swap; method_.InternalSwap(&other->method_); name_.Swap(&other->name_); - std::swap(options_, other->options_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(options_, other->options_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const { @@ -7459,9 +7959,10 @@ void ServiceDescriptorProto::clear_options() { clear_has_options(); } const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const { + const ::google::protobuf::ServiceOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::ServiceOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::ServiceOptions*>( + &::google::protobuf::_ServiceOptions_default_instance_); } ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() { set_has_options(); @@ -7558,9 +8059,7 @@ void MethodDescriptorProto::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); input_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); output_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete options_; - } + if (this != internal_default_instance()) delete options_; } void MethodDescriptorProto::SetCachedSize(int size) const { @@ -7588,25 +8087,30 @@ MethodDescriptorProto* MethodDescriptorProto::New(::google::protobuf::Arena* are void MethodDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto) - if (_has_bits_[0 / 32] & 15u) { - if (has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 15u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_input_type()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(!input_type_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*input_type_.UnsafeRawStringPointer())->clear(); } - if (has_output_type()) { + if (cached_has_bits & 0x00000004u) { GOOGLE_DCHECK(!output_type_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*output_type_.UnsafeRawStringPointer())->clear(); } - if (has_options()) { + if (cached_has_bits & 0x00000008u) { GOOGLE_DCHECK(options_ != NULL); options_->::google::protobuf::MethodOptions::Clear(); } } - if (_has_bits_[0 / 32] & 48u) { + if (cached_has_bits & 48u) { ::memset(&client_streaming_, 0, static_cast<size_t>( reinterpret_cast<char*>(&server_streaming_) - reinterpret_cast<char*>(&client_streaming_)) + sizeof(server_streaming_)); @@ -7628,7 +8132,7 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -7644,7 +8148,7 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( // optional string input_type = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_input_type())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -7660,7 +8164,7 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( // optional string output_type = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_output_type())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -7676,7 +8180,7 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( // optional .google.protobuf.MethodOptions options = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_options())); } else { @@ -7688,7 +8192,7 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( // optional bool client_streaming = 5 [default = false]; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(40u)) { + static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { set_has_client_streaming(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -7702,7 +8206,7 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( // optional bool server_streaming = 6 [default = false]; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(48u)) { + static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) { set_has_server_streaming(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -7715,13 +8219,11 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -7790,7 +8292,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.MethodDescriptorProto) } @@ -7855,7 +8357,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodDescriptorProto) return target; @@ -7868,7 +8370,7 @@ size_t MethodDescriptorProto::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (_has_bits_[0 / 32] & 63u) { // optional string name = 1; @@ -7992,15 +8494,16 @@ void MethodDescriptorProto::Swap(MethodDescriptorProto* other) { InternalSwap(other); } void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { + using std::swap; name_.Swap(&other->name_); input_type_.Swap(&other->input_type_); output_type_.Swap(&other->output_type_); - std::swap(options_, other->options_); - std::swap(client_streaming_, other->client_streaming_); - std::swap(server_streaming_, other->server_streaming_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(options_, other->options_); + swap(client_streaming_, other->client_streaming_); + swap(server_streaming_, other->server_streaming_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const { @@ -8215,9 +8718,10 @@ void MethodDescriptorProto::clear_options() { clear_has_options(); } const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const { + const ::google::protobuf::MethodOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::MethodOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::MethodOptions*>( + &::google::protobuf::_MethodOptions_default_instance_); } ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() { set_has_options(); @@ -8430,48 +8934,53 @@ FileOptions* FileOptions::New(::google::protobuf::Arena* arena) const { void FileOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + _extensions_.Clear(); uninterpreted_option_.Clear(); - if (_has_bits_[0 / 32] & 255u) { - if (has_java_package()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 255u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!java_package_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*java_package_.UnsafeRawStringPointer())->clear(); } - if (has_java_outer_classname()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(!java_outer_classname_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*java_outer_classname_.UnsafeRawStringPointer())->clear(); } - if (has_go_package()) { + if (cached_has_bits & 0x00000004u) { GOOGLE_DCHECK(!go_package_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*go_package_.UnsafeRawStringPointer())->clear(); } - if (has_objc_class_prefix()) { + if (cached_has_bits & 0x00000008u) { GOOGLE_DCHECK(!objc_class_prefix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*objc_class_prefix_.UnsafeRawStringPointer())->clear(); } - if (has_csharp_namespace()) { + if (cached_has_bits & 0x00000010u) { GOOGLE_DCHECK(!csharp_namespace_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*csharp_namespace_.UnsafeRawStringPointer())->clear(); } - if (has_swift_prefix()) { + if (cached_has_bits & 0x00000020u) { GOOGLE_DCHECK(!swift_prefix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*swift_prefix_.UnsafeRawStringPointer())->clear(); } - if (has_php_class_prefix()) { + if (cached_has_bits & 0x00000040u) { GOOGLE_DCHECK(!php_class_prefix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*php_class_prefix_.UnsafeRawStringPointer())->clear(); } - if (has_php_namespace()) { + if (cached_has_bits & 0x00000080u) { GOOGLE_DCHECK(!php_namespace_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*php_namespace_.UnsafeRawStringPointer())->clear(); } } - if (_has_bits_[8 / 32] & 65280u) { + if (cached_has_bits & 65280u) { ::memset(&java_multiple_files_, 0, static_cast<size_t>( reinterpret_cast<char*>(&deprecated_) - reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(deprecated_)); } - if (_has_bits_[16 / 32] & 196608u) { + if (cached_has_bits & 196608u) { cc_enable_arenas_ = false; optimize_for_ = 1; } @@ -8492,7 +9001,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional string java_package = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_java_package())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -8508,7 +9017,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional string java_outer_classname = 8; case 8: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(66u)) { + static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_java_outer_classname())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -8524,7 +9033,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; case 9: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(72u)) { + static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -8544,7 +9053,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool java_multiple_files = 10 [default = false]; case 10: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(80u)) { + static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) { set_has_java_multiple_files(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -8558,7 +9067,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional string go_package = 11; case 11: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(90u)) { + static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_go_package())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -8574,7 +9083,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool cc_generic_services = 16 [default = false]; case 16: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(128u)) { + static_cast< ::google::protobuf::uint8>(128u /* 128 & 0xFF */)) { set_has_cc_generic_services(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -8588,7 +9097,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool java_generic_services = 17 [default = false]; case 17: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(136u)) { + static_cast< ::google::protobuf::uint8>(136u /* 136 & 0xFF */)) { set_has_java_generic_services(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -8602,7 +9111,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool py_generic_services = 18 [default = false]; case 18: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(144u)) { + static_cast< ::google::protobuf::uint8>(144u /* 144 & 0xFF */)) { set_has_py_generic_services(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -8616,7 +9125,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool php_generic_services = 19 [default = false]; case 19: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(152u)) { + static_cast< ::google::protobuf::uint8>(152u /* 152 & 0xFF */)) { set_has_php_generic_services(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -8630,7 +9139,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; case 20: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(160u)) { + static_cast< ::google::protobuf::uint8>(160u /* 160 & 0xFF */)) { set_has_java_generate_equals_and_hash(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -8644,7 +9153,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool deprecated = 23 [default = false]; case 23: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(184u)) { + static_cast< ::google::protobuf::uint8>(184u /* 184 & 0xFF */)) { set_has_deprecated(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -8658,7 +9167,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool java_string_check_utf8 = 27 [default = false]; case 27: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(216u)) { + static_cast< ::google::protobuf::uint8>(216u /* 216 & 0xFF */)) { set_has_java_string_check_utf8(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -8672,7 +9181,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional bool cc_enable_arenas = 31 [default = false]; case 31: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(248u)) { + static_cast< ::google::protobuf::uint8>(248u /* 248 & 0xFF */)) { set_has_cc_enable_arenas(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -8686,7 +9195,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional string objc_class_prefix = 36; case 36: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(290u)) { + static_cast< ::google::protobuf::uint8>(34u /* 290 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_objc_class_prefix())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -8702,7 +9211,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional string csharp_namespace = 37; case 37: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(298u)) { + static_cast< ::google::protobuf::uint8>(42u /* 298 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_csharp_namespace())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -8718,7 +9227,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional string swift_prefix = 39; case 39: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(314u)) { + static_cast< ::google::protobuf::uint8>(58u /* 314 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_swift_prefix())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -8734,7 +9243,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional string php_class_prefix = 40; case 40: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(322u)) { + static_cast< ::google::protobuf::uint8>(66u /* 322 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_php_class_prefix())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -8750,7 +9259,7 @@ bool FileOptions::MergePartialFromCodedStream( // optional string php_namespace = 41; case 41: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(330u)) { + static_cast< ::google::protobuf::uint8>(74u /* 330 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_php_namespace())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -8766,7 +9275,7 @@ bool FileOptions::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(7994u)) { + static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { @@ -8777,18 +9286,17 @@ bool FileOptions::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, internal_default_instance(), - mutable_unknown_fields())); + DO_(_extensions_.ParseField(tag, input, + internal_default_instance(), + _internal_metadata_.mutable_unknown_fields())); continue; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -8953,7 +9461,7 @@ void FileOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.FileOptions) } @@ -9119,7 +9627,7 @@ void FileOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileOptions) return target; @@ -9134,7 +9642,7 @@ size_t FileOptions::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; { @@ -9392,6 +9900,7 @@ void FileOptions::Swap(FileOptions* other) { InternalSwap(other); } void FileOptions::InternalSwap(FileOptions* other) { + using std::swap; uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); java_package_.Swap(&other->java_package_); java_outer_classname_.Swap(&other->java_outer_classname_); @@ -9401,19 +9910,19 @@ void FileOptions::InternalSwap(FileOptions* other) { swift_prefix_.Swap(&other->swift_prefix_); php_class_prefix_.Swap(&other->php_class_prefix_); php_namespace_.Swap(&other->php_namespace_); - std::swap(java_multiple_files_, other->java_multiple_files_); - std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_); - std::swap(java_string_check_utf8_, other->java_string_check_utf8_); - std::swap(cc_generic_services_, other->cc_generic_services_); - std::swap(java_generic_services_, other->java_generic_services_); - std::swap(py_generic_services_, other->py_generic_services_); - std::swap(php_generic_services_, other->php_generic_services_); - std::swap(deprecated_, other->deprecated_); - std::swap(cc_enable_arenas_, other->cc_enable_arenas_); - std::swap(optimize_for_, other->optimize_for_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(java_multiple_files_, other->java_multiple_files_); + swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_); + swap(java_string_check_utf8_, other->java_string_check_utf8_); + swap(cc_generic_services_, other->cc_generic_services_); + swap(java_generic_services_, other->java_generic_services_); + swap(py_generic_services_, other->py_generic_services_); + swap(php_generic_services_, other->php_generic_services_); + swap(deprecated_, other->deprecated_); + swap(cc_enable_arenas_, other->cc_enable_arenas_); + swap(optimize_for_, other->optimize_for_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); _extensions_.Swap(&other->_extensions_); } @@ -10274,9 +10783,14 @@ MessageOptions* MessageOptions::New(::google::protobuf::Arena* arena) const { void MessageOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + _extensions_.Clear(); uninterpreted_option_.Clear(); - if (_has_bits_[0 / 32] & 15u) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 15u) { ::memset(&message_set_wire_format_, 0, static_cast<size_t>( reinterpret_cast<char*>(&map_entry_) - reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_)); @@ -10298,7 +10812,7 @@ bool MessageOptions::MergePartialFromCodedStream( // optional bool message_set_wire_format = 1 [default = false]; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { set_has_message_set_wire_format(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -10312,7 +10826,7 @@ bool MessageOptions::MergePartialFromCodedStream( // optional bool no_standard_descriptor_accessor = 2 [default = false]; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { set_has_no_standard_descriptor_accessor(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -10326,7 +10840,7 @@ bool MessageOptions::MergePartialFromCodedStream( // optional bool deprecated = 3 [default = false]; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { + static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) { set_has_deprecated(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -10340,7 +10854,7 @@ bool MessageOptions::MergePartialFromCodedStream( // optional bool map_entry = 7; case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(56u)) { + static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) { set_has_map_entry(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -10354,7 +10868,7 @@ bool MessageOptions::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(7994u)) { + static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { @@ -10365,18 +10879,17 @@ bool MessageOptions::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, internal_default_instance(), - mutable_unknown_fields())); + DO_(_extensions_.ParseField(tag, input, + internal_default_instance(), + _internal_metadata_.mutable_unknown_fields())); continue; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -10430,7 +10943,7 @@ void MessageOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.MessageOptions) } @@ -10477,7 +10990,7 @@ void MessageOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MessageOptions) return target; @@ -10492,7 +11005,7 @@ size_t MessageOptions::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; { @@ -10604,14 +11117,15 @@ void MessageOptions::Swap(MessageOptions* other) { InternalSwap(other); } void MessageOptions::InternalSwap(MessageOptions* other) { + using std::swap; 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_); - std::swap(map_entry_, other->map_entry_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(message_set_wire_format_, other->message_set_wire_format_); + swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_); + swap(deprecated_, other->deprecated_); + swap(map_entry_, other->map_entry_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); _extensions_.Swap(&other->_extensions_); } @@ -10825,9 +11339,14 @@ FieldOptions* FieldOptions::New(::google::protobuf::Arena* arena) const { void FieldOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + _extensions_.Clear(); uninterpreted_option_.Clear(); - if (_has_bits_[0 / 32] & 63u) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 63u) { ::memset(&ctype_, 0, static_cast<size_t>( reinterpret_cast<char*>(&jstype_) - reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_)); @@ -10849,7 +11368,7 @@ bool FieldOptions::MergePartialFromCodedStream( // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -10869,7 +11388,7 @@ bool FieldOptions::MergePartialFromCodedStream( // optional bool packed = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { set_has_packed(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -10883,7 +11402,7 @@ bool FieldOptions::MergePartialFromCodedStream( // optional bool deprecated = 3 [default = false]; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { + static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) { set_has_deprecated(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -10897,7 +11416,7 @@ bool FieldOptions::MergePartialFromCodedStream( // optional bool lazy = 5 [default = false]; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(40u)) { + static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { set_has_lazy(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -10911,7 +11430,7 @@ bool FieldOptions::MergePartialFromCodedStream( // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(48u)) { + static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -10931,7 +11450,7 @@ bool FieldOptions::MergePartialFromCodedStream( // optional bool weak = 10 [default = false]; case 10: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(80u)) { + static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) { set_has_weak(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -10945,7 +11464,7 @@ bool FieldOptions::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(7994u)) { + static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { @@ -10956,18 +11475,17 @@ bool FieldOptions::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, internal_default_instance(), - mutable_unknown_fields())); + DO_(_extensions_.ParseField(tag, input, + internal_default_instance(), + _internal_metadata_.mutable_unknown_fields())); continue; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -11033,7 +11551,7 @@ void FieldOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.FieldOptions) } @@ -11092,7 +11610,7 @@ void FieldOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldOptions) return target; @@ -11107,7 +11625,7 @@ size_t FieldOptions::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; { @@ -11237,16 +11755,17 @@ void FieldOptions::Swap(FieldOptions* other) { InternalSwap(other); } void FieldOptions::InternalSwap(FieldOptions* other) { + using std::swap; uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); - std::swap(ctype_, other->ctype_); - 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]); + swap(ctype_, other->ctype_); + swap(packed_, other->packed_); + swap(lazy_, other->lazy_); + swap(deprecated_, other->deprecated_); + swap(weak_, other->weak_); + swap(jstype_, other->jstype_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); _extensions_.Swap(&other->_extensions_); } @@ -11498,6 +12017,10 @@ OneofOptions* OneofOptions::New(::google::protobuf::Arena* arena) const { void OneofOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + _extensions_.Clear(); uninterpreted_option_.Clear(); _has_bits_.Clear(); @@ -11517,7 +12040,7 @@ bool OneofOptions::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(7994u)) { + static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { @@ -11528,18 +12051,17 @@ bool OneofOptions::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, internal_default_instance(), - mutable_unknown_fields())); + DO_(_extensions_.ParseField(tag, input, + internal_default_instance(), + _internal_metadata_.mutable_unknown_fields())); continue; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -11572,7 +12094,7 @@ void OneofOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.OneofOptions) } @@ -11598,7 +12120,7 @@ void OneofOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofOptions) return target; @@ -11613,7 +12135,7 @@ size_t OneofOptions::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; { @@ -11687,10 +12209,11 @@ void OneofOptions::Swap(OneofOptions* other) { InternalSwap(other); } void OneofOptions::InternalSwap(OneofOptions* other) { + using std::swap; uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); _extensions_.Swap(&other->_extensions_); } @@ -11804,9 +12327,14 @@ EnumOptions* EnumOptions::New(::google::protobuf::Arena* arena) const { void EnumOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + _extensions_.Clear(); uninterpreted_option_.Clear(); - if (_has_bits_[0 / 32] & 3u) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { ::memset(&allow_alias_, 0, static_cast<size_t>( reinterpret_cast<char*>(&deprecated_) - reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_)); @@ -11828,7 +12356,7 @@ bool EnumOptions::MergePartialFromCodedStream( // optional bool allow_alias = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { set_has_allow_alias(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -11842,7 +12370,7 @@ bool EnumOptions::MergePartialFromCodedStream( // optional bool deprecated = 3 [default = false]; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { + static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) { set_has_deprecated(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -11856,7 +12384,7 @@ bool EnumOptions::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(7994u)) { + static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { @@ -11867,18 +12395,17 @@ bool EnumOptions::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, internal_default_instance(), - mutable_unknown_fields())); + DO_(_extensions_.ParseField(tag, input, + internal_default_instance(), + _internal_metadata_.mutable_unknown_fields())); continue; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -11922,7 +12449,7 @@ void EnumOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.EnumOptions) } @@ -11959,7 +12486,7 @@ void EnumOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumOptions) return target; @@ -11974,7 +12501,7 @@ size_t EnumOptions::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; { @@ -12070,12 +12597,13 @@ void EnumOptions::Swap(EnumOptions* other) { InternalSwap(other); } void EnumOptions::InternalSwap(EnumOptions* other) { + using std::swap; 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]); + swap(allow_alias_, other->allow_alias_); + swap(deprecated_, other->deprecated_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); _extensions_.Swap(&other->_extensions_); } @@ -12232,6 +12760,10 @@ EnumValueOptions* EnumValueOptions::New(::google::protobuf::Arena* arena) const void EnumValueOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + _extensions_.Clear(); uninterpreted_option_.Clear(); deprecated_ = false; @@ -12252,7 +12784,7 @@ bool EnumValueOptions::MergePartialFromCodedStream( // optional bool deprecated = 1 [default = false]; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { set_has_deprecated(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -12266,7 +12798,7 @@ bool EnumValueOptions::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(7994u)) { + static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { @@ -12277,18 +12809,17 @@ bool EnumValueOptions::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, internal_default_instance(), - mutable_unknown_fields())); + DO_(_extensions_.ParseField(tag, input, + internal_default_instance(), + _internal_metadata_.mutable_unknown_fields())); continue; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -12327,7 +12858,7 @@ void EnumValueOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueOptions) } @@ -12359,7 +12890,7 @@ void EnumValueOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueOptions) return target; @@ -12374,7 +12905,7 @@ size_t EnumValueOptions::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; { @@ -12456,11 +12987,12 @@ void EnumValueOptions::Swap(EnumValueOptions* other) { InternalSwap(other); } void EnumValueOptions::InternalSwap(EnumValueOptions* other) { + using std::swap; uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); - std::swap(deprecated_, other->deprecated_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(deprecated_, other->deprecated_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); _extensions_.Swap(&other->_extensions_); } @@ -12593,6 +13125,10 @@ ServiceOptions* ServiceOptions::New(::google::protobuf::Arena* arena) const { void ServiceOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + _extensions_.Clear(); uninterpreted_option_.Clear(); deprecated_ = false; @@ -12613,7 +13149,7 @@ bool ServiceOptions::MergePartialFromCodedStream( // optional bool deprecated = 33 [default = false]; case 33: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(264u)) { + static_cast< ::google::protobuf::uint8>(8u /* 264 & 0xFF */)) { set_has_deprecated(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -12627,7 +13163,7 @@ bool ServiceOptions::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(7994u)) { + static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { @@ -12638,18 +13174,17 @@ bool ServiceOptions::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, internal_default_instance(), - mutable_unknown_fields())); + DO_(_extensions_.ParseField(tag, input, + internal_default_instance(), + _internal_metadata_.mutable_unknown_fields())); continue; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -12688,7 +13223,7 @@ void ServiceOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceOptions) } @@ -12720,7 +13255,7 @@ void ServiceOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceOptions) return target; @@ -12735,7 +13270,7 @@ size_t ServiceOptions::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; { @@ -12817,11 +13352,12 @@ void ServiceOptions::Swap(ServiceOptions* other) { InternalSwap(other); } void ServiceOptions::InternalSwap(ServiceOptions* other) { + using std::swap; uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); - std::swap(deprecated_, other->deprecated_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(deprecated_, other->deprecated_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); _extensions_.Swap(&other->_extensions_); } @@ -12959,9 +13495,14 @@ MethodOptions* MethodOptions::New(::google::protobuf::Arena* arena) const { void MethodOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + _extensions_.Clear(); uninterpreted_option_.Clear(); - if (_has_bits_[0 / 32] & 3u) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { ::memset(&deprecated_, 0, static_cast<size_t>( reinterpret_cast<char*>(&idempotency_level_) - reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_)); @@ -12983,7 +13524,7 @@ bool MethodOptions::MergePartialFromCodedStream( // optional bool deprecated = 33 [default = false]; case 33: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(264u)) { + static_cast< ::google::protobuf::uint8>(8u /* 264 & 0xFF */)) { set_has_deprecated(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -12997,7 +13538,7 @@ bool MethodOptions::MergePartialFromCodedStream( // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; case 34: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(272u)) { + static_cast< ::google::protobuf::uint8>(16u /* 272 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -13017,7 +13558,7 @@ bool MethodOptions::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(7994u)) { + static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { @@ -13028,18 +13569,17 @@ bool MethodOptions::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } if ((8000u <= tag)) { - DO_(_extensions_.ParseField(tag, input, internal_default_instance(), - mutable_unknown_fields())); + DO_(_extensions_.ParseField(tag, input, + internal_default_instance(), + _internal_metadata_.mutable_unknown_fields())); continue; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -13084,7 +13624,7 @@ void MethodOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.MethodOptions) } @@ -13122,7 +13662,7 @@ void MethodOptions::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodOptions) return target; @@ -13137,7 +13677,7 @@ size_t MethodOptions::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; { @@ -13234,12 +13774,13 @@ void MethodOptions::Swap(MethodOptions* other) { InternalSwap(other); } void MethodOptions::InternalSwap(MethodOptions* other) { + using std::swap; 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]); + swap(deprecated_, other->deprecated_); + swap(idempotency_level_, other->idempotency_level_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); _extensions_.Swap(&other->_extensions_); } @@ -13401,6 +13942,10 @@ UninterpretedOption_NamePart* UninterpretedOption_NamePart::New(::google::protob void UninterpretedOption_NamePart::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + if (has_name_part()) { GOOGLE_DCHECK(!name_part_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_part_.UnsafeRawStringPointer())->clear(); @@ -13423,7 +13968,7 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream( // required string name_part = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name_part())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -13439,7 +13984,7 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream( // required bool is_extension = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { set_has_is_extension(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -13452,13 +13997,11 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -13496,7 +14039,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption.NamePart) } @@ -13527,7 +14070,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption.NamePart) return target; @@ -13558,7 +14101,7 @@ size_t UninterpretedOption_NamePart::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) { // All required fields are present. // required string name_part = 1; @@ -13638,11 +14181,12 @@ void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) { InternalSwap(other); } void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* other) { + using std::swap; name_part_.Swap(&other->name_part_); - std::swap(is_extension_, other->is_extension_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(is_extension_, other->is_extension_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const { @@ -13833,22 +14377,27 @@ UninterpretedOption* UninterpretedOption::New(::google::protobuf::Arena* arena) void UninterpretedOption::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + name_.Clear(); - if (_has_bits_[0 / 32] & 7u) { - if (has_identifier_value()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 7u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!identifier_value_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*identifier_value_.UnsafeRawStringPointer())->clear(); } - if (has_string_value()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(!string_value_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*string_value_.UnsafeRawStringPointer())->clear(); } - if (has_aggregate_value()) { + if (cached_has_bits & 0x00000004u) { GOOGLE_DCHECK(!aggregate_value_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*aggregate_value_.UnsafeRawStringPointer())->clear(); } } - if (_has_bits_[0 / 32] & 56u) { + if (cached_has_bits & 56u) { ::memset(&positive_int_value_, 0, static_cast<size_t>( reinterpret_cast<char*>(&double_value_) - reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_)); @@ -13870,7 +14419,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_name())); } else { @@ -13882,7 +14431,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional string identifier_value = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_identifier_value())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -13898,7 +14447,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional uint64 positive_int_value = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(32u)) { + static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) { set_has_positive_int_value(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( @@ -13912,7 +14461,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional int64 negative_int_value = 5; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(40u)) { + static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { set_has_negative_int_value(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( @@ -13926,7 +14475,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional double double_value = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(49u)) { + static_cast< ::google::protobuf::uint8>(49u /* 49 & 0xFF */)) { set_has_double_value(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( @@ -13940,7 +14489,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional bytes string_value = 7; case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(58u)) { + static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( input, this->mutable_string_value())); } else { @@ -13952,7 +14501,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( // optional string aggregate_value = 8; case 8: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(66u)) { + static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_aggregate_value())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -13967,13 +14516,11 @@ bool UninterpretedOption::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -14044,7 +14591,7 @@ void UninterpretedOption::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption) } @@ -14111,7 +14658,7 @@ void UninterpretedOption::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption) return target; @@ -14124,7 +14671,7 @@ size_t UninterpretedOption::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; { @@ -14260,16 +14807,17 @@ void UninterpretedOption::Swap(UninterpretedOption* other) { InternalSwap(other); } void UninterpretedOption::InternalSwap(UninterpretedOption* other) { + using std::swap; name_.InternalSwap(&other->name_); identifier_value_.Swap(&other->identifier_value_); string_value_.Swap(&other->string_value_); aggregate_value_.Swap(&other->aggregate_value_); - std::swap(positive_int_value_, other->positive_int_value_); - std::swap(negative_int_value_, other->negative_int_value_); - std::swap(double_value_, other->double_value_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(positive_int_value_, other->positive_int_value_); + swap(negative_int_value_, other->negative_int_value_); + swap(double_value_, other->double_value_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata UninterpretedOption::GetMetadata() const { @@ -14652,15 +15200,20 @@ SourceCodeInfo_Location* SourceCodeInfo_Location::New(::google::protobuf::Arena* void SourceCodeInfo_Location::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + path_.Clear(); span_.Clear(); leading_detached_comments_.Clear(); - if (_has_bits_[0 / 32] & 3u) { - if (has_leading_comments()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!leading_comments_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*leading_comments_.UnsafeRawStringPointer())->clear(); } - if (has_trailing_comments()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(!trailing_comments_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*trailing_comments_.UnsafeRawStringPointer())->clear(); } @@ -14682,12 +15235,13 @@ bool SourceCodeInfo_Location::MergePartialFromCodedStream( // repeated int32 path = 1 [packed = true]; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, this->mutable_path()))); - } else if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + } else if ( + static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( 1, 10u, input, this->mutable_path()))); @@ -14700,12 +15254,13 @@ bool SourceCodeInfo_Location::MergePartialFromCodedStream( // repeated int32 span = 2 [packed = true]; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, this->mutable_span()))); - } else if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + } else if ( + static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( 1, 18u, input, this->mutable_span()))); @@ -14718,7 +15273,7 @@ bool SourceCodeInfo_Location::MergePartialFromCodedStream( // optional string leading_comments = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_leading_comments())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -14734,7 +15289,7 @@ bool SourceCodeInfo_Location::MergePartialFromCodedStream( // optional string trailing_comments = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_trailing_comments())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -14750,7 +15305,7 @@ bool SourceCodeInfo_Location::MergePartialFromCodedStream( // repeated string leading_detached_comments = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(50u)) { + static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->add_leading_detached_comments())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -14766,13 +15321,11 @@ bool SourceCodeInfo_Location::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -14847,7 +15400,7 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo.Location) } @@ -14920,7 +15473,7 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo.Location) return target; @@ -14933,7 +15486,7 @@ size_t SourceCodeInfo_Location::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated int32 path = 1 [packed = true]; { @@ -15059,14 +15612,15 @@ void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) { InternalSwap(other); } void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) { + using std::swap; 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]); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const { @@ -15395,6 +15949,10 @@ SourceCodeInfo* SourceCodeInfo::New(::google::protobuf::Arena* arena) const { void SourceCodeInfo::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + location_.Clear(); _has_bits_.Clear(); _internal_metadata_.Clear(); @@ -15413,7 +15971,7 @@ bool SourceCodeInfo::MergePartialFromCodedStream( // repeated .google.protobuf.SourceCodeInfo.Location location = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_location())); } else { @@ -15424,13 +15982,11 @@ bool SourceCodeInfo::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -15459,7 +16015,7 @@ void SourceCodeInfo::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo) } @@ -15481,7 +16037,7 @@ void SourceCodeInfo::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo) return target; @@ -15494,7 +16050,7 @@ size_t SourceCodeInfo::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.SourceCodeInfo.Location location = 1; { @@ -15562,10 +16118,11 @@ void SourceCodeInfo::Swap(SourceCodeInfo* other) { InternalSwap(other); } void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) { + using std::swap; location_.InternalSwap(&other->location_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const { @@ -15684,12 +16241,17 @@ GeneratedCodeInfo_Annotation* GeneratedCodeInfo_Annotation::New(::google::protob void GeneratedCodeInfo_Annotation::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + path_.Clear(); if (has_source_file()) { GOOGLE_DCHECK(!source_file_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*source_file_.UnsafeRawStringPointer())->clear(); } - if (_has_bits_[0 / 32] & 6u) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 6u) { ::memset(&begin_, 0, static_cast<size_t>( reinterpret_cast<char*>(&end_) - reinterpret_cast<char*>(&begin_)) + sizeof(end_)); @@ -15711,12 +16273,13 @@ bool GeneratedCodeInfo_Annotation::MergePartialFromCodedStream( // repeated int32 path = 1 [packed = true]; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, this->mutable_path()))); - } else if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + } else if ( + static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( 1, 10u, input, this->mutable_path()))); @@ -15729,7 +16292,7 @@ bool GeneratedCodeInfo_Annotation::MergePartialFromCodedStream( // optional string source_file = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_source_file())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -15745,7 +16308,7 @@ bool GeneratedCodeInfo_Annotation::MergePartialFromCodedStream( // optional int32 begin = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { + static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) { set_has_begin(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -15759,7 +16322,7 @@ bool GeneratedCodeInfo_Annotation::MergePartialFromCodedStream( // optional int32 end = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(32u)) { + static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) { set_has_end(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -15772,13 +16335,11 @@ bool GeneratedCodeInfo_Annotation::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -15832,7 +16393,7 @@ void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.GeneratedCodeInfo.Annotation) } @@ -15881,7 +16442,7 @@ void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo.Annotation) return target; @@ -15894,7 +16455,7 @@ size_t GeneratedCodeInfo_Annotation::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated int32 path = 1 [packed = true]; { @@ -16004,13 +16565,14 @@ void GeneratedCodeInfo_Annotation::Swap(GeneratedCodeInfo_Annotation* other) { InternalSwap(other); } void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) { + using std::swap; path_.InternalSwap(&other->path_); source_file_.Swap(&other->source_file_); - std::swap(begin_, other->begin_); - std::swap(end_, other->end_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(begin_, other->begin_); + swap(end_, other->end_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const { @@ -16225,6 +16787,10 @@ GeneratedCodeInfo* GeneratedCodeInfo::New(::google::protobuf::Arena* arena) cons void GeneratedCodeInfo::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + annotation_.Clear(); _has_bits_.Clear(); _internal_metadata_.Clear(); @@ -16243,7 +16809,7 @@ bool GeneratedCodeInfo::MergePartialFromCodedStream( // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_annotation())); } else { @@ -16254,13 +16820,11 @@ bool GeneratedCodeInfo::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -16289,7 +16853,7 @@ void GeneratedCodeInfo::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.GeneratedCodeInfo) } @@ -16311,7 +16875,7 @@ void GeneratedCodeInfo::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo) return target; @@ -16324,7 +16888,7 @@ size_t GeneratedCodeInfo::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; { @@ -16392,10 +16956,11 @@ void GeneratedCodeInfo::Swap(GeneratedCodeInfo* other) { InternalSwap(other); } void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) { + using std::swap; annotation_.InternalSwap(&other->annotation_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata GeneratedCodeInfo::GetMetadata() const { diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 2aaa9fde..7ec516ab 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -54,6 +54,9 @@ LIBPROTOBUF_EXPORT extern EnumValueDescriptorProtoDefaultTypeInternal _EnumValue class EnumValueOptions; class EnumValueOptionsDefaultTypeInternal; LIBPROTOBUF_EXPORT extern EnumValueOptionsDefaultTypeInternal _EnumValueOptions_default_instance_; +class ExtensionRangeOptions; +class ExtensionRangeOptionsDefaultTypeInternal; +LIBPROTOBUF_EXPORT extern ExtensionRangeOptionsDefaultTypeInternal _ExtensionRangeOptions_default_instance_; class FieldDescriptorProto; class FieldDescriptorProtoDefaultTypeInternal; LIBPROTOBUF_EXPORT extern FieldDescriptorProtoDefaultTypeInternal _FieldDescriptorProto_default_instance_; @@ -121,8 +124,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -276,11 +280,24 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message CopyFrom(from); return *this; } + #if LANG_CXX11 + FileDescriptorSet(FileDescriptorSet&& from) noexcept + : FileDescriptorSet() { + *this = ::std::move(from); + } + inline FileDescriptorSet& operator=(FileDescriptorSet&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -296,6 +313,9 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message 0; void Swap(FileDescriptorSet* other); + friend void swap(FileDescriptorSet& a, FileDescriptorSet& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -371,11 +391,24 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag CopyFrom(from); return *this; } + #if LANG_CXX11 + FileDescriptorProto(FileDescriptorProto&& from) noexcept + : FileDescriptorProto() { + *this = ::std::move(from); + } + inline FileDescriptorProto& operator=(FileDescriptorProto&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -391,6 +424,9 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag 1; void Swap(FileDescriptorProto* other); + friend void swap(FileDescriptorProto& a, FileDescriptorProto& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -632,11 +668,24 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto CopyFrom(from); return *this; } + #if LANG_CXX11 + DescriptorProto_ExtensionRange(DescriptorProto_ExtensionRange&& from) noexcept + : DescriptorProto_ExtensionRange() { + *this = ::std::move(from); + } + inline DescriptorProto_ExtensionRange& operator=(DescriptorProto_ExtensionRange&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -652,6 +701,9 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto 2; void Swap(DescriptorProto_ExtensionRange* other); + friend void swap(DescriptorProto_ExtensionRange& a, DescriptorProto_ExtensionRange& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -693,6 +745,15 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto // accessors ------------------------------------------------------- + // optional .google.protobuf.ExtensionRangeOptions options = 3; + bool has_options() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::ExtensionRangeOptions& options() const; + ::google::protobuf::ExtensionRangeOptions* mutable_options(); + ::google::protobuf::ExtensionRangeOptions* release_options(); + void set_allocated_options(::google::protobuf::ExtensionRangeOptions* options); + // optional int32 start = 1; bool has_start() const; void clear_start(); @@ -713,10 +774,13 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto void clear_has_start(); void set_has_end(); void clear_has_end(); + void set_has_options(); + void clear_has_options(); ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; ::google::protobuf::internal::HasBits<1> _has_bits_; mutable int _cached_size_; + ::google::protobuf::ExtensionRangeOptions* options_; ::google::protobuf::int32 start_; ::google::protobuf::int32 end_; friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; @@ -734,11 +798,24 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protob CopyFrom(from); return *this; } + #if LANG_CXX11 + DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&& from) noexcept + : DescriptorProto_ReservedRange() { + *this = ::std::move(from); + } + inline DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -754,6 +831,9 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protob 3; void Swap(DescriptorProto_ReservedRange* other); + friend void swap(DescriptorProto_ReservedRange& a, DescriptorProto_ReservedRange& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -836,11 +916,24 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* CopyFrom(from); return *this; } + #if LANG_CXX11 + DescriptorProto(DescriptorProto&& from) noexcept + : DescriptorProto() { + *this = ::std::move(from); + } + inline DescriptorProto& operator=(DescriptorProto&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -856,6 +949,9 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* 4; void Swap(DescriptorProto* other); + friend void swap(DescriptorProto& a, DescriptorProto& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -1054,6 +1150,120 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* }; // ------------------------------------------------------------------- +class LIBPROTOBUF_EXPORT ExtensionRangeOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions) */ { + public: + ExtensionRangeOptions(); + virtual ~ExtensionRangeOptions(); + + ExtensionRangeOptions(const ExtensionRangeOptions& from); + + inline ExtensionRangeOptions& operator=(const ExtensionRangeOptions& from) { + CopyFrom(from); + return *this; + } + #if LANG_CXX11 + ExtensionRangeOptions(ExtensionRangeOptions&& from) noexcept + : ExtensionRangeOptions() { + *this = ::std::move(from); + } + + inline ExtensionRangeOptions& operator=(ExtensionRangeOptions&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif + 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 ExtensionRangeOptions& default_instance(); + + static inline const ExtensionRangeOptions* internal_default_instance() { + return reinterpret_cast<const ExtensionRangeOptions*>( + &_ExtensionRangeOptions_default_instance_); + } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 5; + + void Swap(ExtensionRangeOptions* other); + friend void swap(ExtensionRangeOptions& a, ExtensionRangeOptions& b) { + a.Swap(&b); + } + + // implements Message ---------------------------------------------- + + inline ExtensionRangeOptions* New() const PROTOBUF_FINAL { return New(NULL); } + + ExtensionRangeOptions* 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 ExtensionRangeOptions& from); + void MergeFrom(const ExtensionRangeOptions& 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(ExtensionRangeOptions* 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.UninterpretedOption uninterpreted_option = 999; + int uninterpreted_option_size() const; + void clear_uninterpreted_option(); + static const int kUninterpretedOptionFieldNumber = 999; + const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; + ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); + ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* + mutable_uninterpreted_option(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& + uninterpreted_option() const; + + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ExtensionRangeOptions) + // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions) + private: + + ::google::protobuf::internal::ExtensionSet _extensions_; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::internal::HasBits<1> _has_bits_; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; +}; +// ------------------------------------------------------------------- + class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ { public: FieldDescriptorProto(); @@ -1065,11 +1275,24 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa CopyFrom(from); return *this; } + #if LANG_CXX11 + FieldDescriptorProto(FieldDescriptorProto&& from) noexcept + : FieldDescriptorProto() { + *this = ::std::move(from); + } + inline FieldDescriptorProto& operator=(FieldDescriptorProto&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -1082,9 +1305,12 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa &_FieldDescriptorProto_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 5; + 6; void Swap(FieldDescriptorProto* other); + friend void swap(FieldDescriptorProto& a, FieldDescriptorProto& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -1375,11 +1601,24 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa CopyFrom(from); return *this; } + #if LANG_CXX11 + OneofDescriptorProto(OneofDescriptorProto&& from) noexcept + : OneofDescriptorProto() { + *this = ::std::move(from); + } + inline OneofDescriptorProto& operator=(OneofDescriptorProto&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -1392,9 +1631,12 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa &_OneofDescriptorProto_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 6; + 7; void Swap(OneofDescriptorProto* other); + friend void swap(OneofDescriptorProto& a, OneofDescriptorProto& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -1487,11 +1729,24 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag CopyFrom(from); return *this; } + #if LANG_CXX11 + EnumDescriptorProto(EnumDescriptorProto&& from) noexcept + : EnumDescriptorProto() { + *this = ::std::move(from); + } + inline EnumDescriptorProto& operator=(EnumDescriptorProto&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -1504,9 +1759,12 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag &_EnumDescriptorProto_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 7; + 8; void Swap(EnumDescriptorProto* other); + friend void swap(EnumDescriptorProto& a, EnumDescriptorProto& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -1612,11 +1870,24 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M CopyFrom(from); return *this; } + #if LANG_CXX11 + EnumValueDescriptorProto(EnumValueDescriptorProto&& from) noexcept + : EnumValueDescriptorProto() { + *this = ::std::move(from); + } + inline EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -1629,9 +1900,12 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M &_EnumValueDescriptorProto_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 8; + 9; void Swap(EnumValueDescriptorProto* other); + friend void swap(EnumValueDescriptorProto& a, EnumValueDescriptorProto& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -1734,11 +2008,24 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes CopyFrom(from); return *this; } + #if LANG_CXX11 + ServiceDescriptorProto(ServiceDescriptorProto&& from) noexcept + : ServiceDescriptorProto() { + *this = ::std::move(from); + } + inline ServiceDescriptorProto& operator=(ServiceDescriptorProto&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -1751,9 +2038,12 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes &_ServiceDescriptorProto_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 9; + 10; void Swap(ServiceDescriptorProto* other); + friend void swap(ServiceDescriptorProto& a, ServiceDescriptorProto& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -1859,11 +2149,24 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess CopyFrom(from); return *this; } + #if LANG_CXX11 + MethodDescriptorProto(MethodDescriptorProto&& from) noexcept + : MethodDescriptorProto() { + *this = ::std::move(from); + } + inline MethodDescriptorProto& operator=(MethodDescriptorProto&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -1876,9 +2179,12 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess &_MethodDescriptorProto_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 10; + 11; void Swap(MethodDescriptorProto* other); + friend void swap(MethodDescriptorProto& a, MethodDescriptorProto& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -2027,11 +2333,24 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@p CopyFrom(from); return *this; } + #if LANG_CXX11 + FileOptions(FileOptions&& from) noexcept + : FileOptions() { + *this = ::std::move(from); + } + inline FileOptions& operator=(FileOptions&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -2044,9 +2363,12 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@p &_FileOptions_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 11; + 12; void Swap(FileOptions* other); + friend void swap(FileOptions& a, FileOptions& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -2397,11 +2719,24 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message /* CopyFrom(from); return *this; } + #if LANG_CXX11 + MessageOptions(MessageOptions&& from) noexcept + : MessageOptions() { + *this = ::std::move(from); + } + inline MessageOptions& operator=(MessageOptions&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -2414,9 +2749,12 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message /* &_MessageOptions_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 12; + 13; void Swap(MessageOptions* other); + friend void swap(MessageOptions& a, MessageOptions& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -2535,11 +2873,24 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@ CopyFrom(from); return *this; } + #if LANG_CXX11 + FieldOptions(FieldOptions&& from) noexcept + : FieldOptions() { + *this = ::std::move(from); + } + inline FieldOptions& operator=(FieldOptions&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -2552,9 +2903,12 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@ &_FieldOptions_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 13; + 14; void Swap(FieldOptions* other); + friend void swap(FieldOptions& a, FieldOptions& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -2749,11 +3103,24 @@ class LIBPROTOBUF_EXPORT OneofOptions : public ::google::protobuf::Message /* @@ CopyFrom(from); return *this; } + #if LANG_CXX11 + OneofOptions(OneofOptions&& from) noexcept + : OneofOptions() { + *this = ::std::move(from); + } + inline OneofOptions& operator=(OneofOptions&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -2766,9 +3133,12 @@ class LIBPROTOBUF_EXPORT OneofOptions : public ::google::protobuf::Message /* @@ &_OneofOptions_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 14; + 15; void Swap(OneofOptions* other); + friend void swap(OneofOptions& a, OneofOptions& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -2847,11 +3217,24 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message /* @@p CopyFrom(from); return *this; } + #if LANG_CXX11 + EnumOptions(EnumOptions&& from) noexcept + : EnumOptions() { + *this = ::std::move(from); + } + inline EnumOptions& operator=(EnumOptions&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -2864,9 +3247,12 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message /* @@p &_EnumOptions_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 15; + 16; void Swap(EnumOptions* other); + friend void swap(EnumOptions& a, EnumOptions& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -2965,11 +3351,24 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message / CopyFrom(from); return *this; } + #if LANG_CXX11 + EnumValueOptions(EnumValueOptions&& from) noexcept + : EnumValueOptions() { + *this = ::std::move(from); + } + inline EnumValueOptions& operator=(EnumValueOptions&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -2982,9 +3381,12 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message / &_EnumValueOptions_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 16; + 17; void Swap(EnumValueOptions* other); + friend void swap(EnumValueOptions& a, EnumValueOptions& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -3073,11 +3475,24 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message /* CopyFrom(from); return *this; } + #if LANG_CXX11 + ServiceOptions(ServiceOptions&& from) noexcept + : ServiceOptions() { + *this = ::std::move(from); + } + inline ServiceOptions& operator=(ServiceOptions&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -3090,9 +3505,12 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message /* &_ServiceOptions_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 17; + 18; void Swap(ServiceOptions* other); + friend void swap(ServiceOptions& a, ServiceOptions& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -3181,11 +3599,24 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message /* @ CopyFrom(from); return *this; } + #if LANG_CXX11 + MethodOptions(MethodOptions&& from) noexcept + : MethodOptions() { + *this = ::std::move(from); + } + inline MethodOptions& operator=(MethodOptions&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -3198,9 +3629,12 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message /* @ &_MethodOptions_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 18; + 19; void Swap(MethodOptions* other); + friend void swap(MethodOptions& a, MethodOptions& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -3327,11 +3761,24 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu CopyFrom(from); return *this; } + #if LANG_CXX11 + UninterpretedOption_NamePart(UninterpretedOption_NamePart&& from) noexcept + : UninterpretedOption_NamePart() { + *this = ::std::move(from); + } + inline UninterpretedOption_NamePart& operator=(UninterpretedOption_NamePart&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -3344,9 +3791,12 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu &_UninterpretedOption_NamePart_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 19; + 20; void Swap(UninterpretedOption_NamePart* other); + friend void swap(UninterpretedOption_NamePart& a, UninterpretedOption_NamePart& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -3440,11 +3890,24 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag CopyFrom(from); return *this; } + #if LANG_CXX11 + UninterpretedOption(UninterpretedOption&& from) noexcept + : UninterpretedOption() { + *this = ::std::move(from); + } + inline UninterpretedOption& operator=(UninterpretedOption&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -3457,9 +3920,12 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag &_UninterpretedOption_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 20; + 21; void Swap(UninterpretedOption* other); + friend void swap(UninterpretedOption& a, UninterpretedOption& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -3621,11 +4087,24 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me CopyFrom(from); return *this; } + #if LANG_CXX11 + SourceCodeInfo_Location(SourceCodeInfo_Location&& from) noexcept + : SourceCodeInfo_Location() { + *this = ::std::move(from); + } + inline SourceCodeInfo_Location& operator=(SourceCodeInfo_Location&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -3638,9 +4117,12 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me &_SourceCodeInfo_Location_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 21; + 22; void Swap(SourceCodeInfo_Location* other); + friend void swap(SourceCodeInfo_Location& a, SourceCodeInfo_Location& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -3790,11 +4272,24 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message /* CopyFrom(from); return *this; } + #if LANG_CXX11 + SourceCodeInfo(SourceCodeInfo&& from) noexcept + : SourceCodeInfo() { + *this = ::std::move(from); + } + inline SourceCodeInfo& operator=(SourceCodeInfo&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -3807,9 +4302,12 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message /* &_SourceCodeInfo_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 22; + 23; void Swap(SourceCodeInfo* other); + friend void swap(SourceCodeInfo& a, SourceCodeInfo& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -3887,11 +4385,24 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobu CopyFrom(from); return *this; } + #if LANG_CXX11 + GeneratedCodeInfo_Annotation(GeneratedCodeInfo_Annotation&& from) noexcept + : GeneratedCodeInfo_Annotation() { + *this = ::std::move(from); + } + inline GeneratedCodeInfo_Annotation& operator=(GeneratedCodeInfo_Annotation&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -3904,9 +4415,12 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobu &_GeneratedCodeInfo_Annotation_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 23; + 24; void Swap(GeneratedCodeInfo_Annotation* other); + friend void swap(GeneratedCodeInfo_Annotation& a, GeneratedCodeInfo_Annotation& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -4021,11 +4535,24 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message CopyFrom(from); return *this; } + #if LANG_CXX11 + GeneratedCodeInfo(GeneratedCodeInfo&& from) noexcept + : GeneratedCodeInfo() { + *this = ::std::move(from); + } + inline GeneratedCodeInfo& operator=(GeneratedCodeInfo&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif 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(); } @@ -4038,9 +4565,12 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message &_GeneratedCodeInfo_default_instance_); } static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 24; + 25; void Swap(GeneratedCodeInfo* other); + friend void swap(GeneratedCodeInfo& a, GeneratedCodeInfo& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -4111,6 +4641,10 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // FileDescriptorSet // repeated .google.protobuf.FileDescriptorProto file = 1; @@ -4537,9 +5071,10 @@ inline void FileDescriptorProto::clear_options() { clear_has_options(); } inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const { + const ::google::protobuf::FileOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::FileOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::FileOptions*>( + &::google::protobuf::_FileOptions_default_instance_); } inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() { set_has_options(); @@ -4582,9 +5117,10 @@ inline void FileDescriptorProto::clear_source_code_info() { clear_has_source_code_info(); } inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const { + const ::google::protobuf::SourceCodeInfo* p = source_code_info_; // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info) - return source_code_info_ != NULL ? *source_code_info_ - : *::google::protobuf::SourceCodeInfo::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::SourceCodeInfo*>( + &::google::protobuf::_SourceCodeInfo_default_instance_); } inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() { set_has_source_code_info(); @@ -4681,13 +5217,13 @@ inline void FileDescriptorProto::set_allocated_syntax(::std::string* syntax) { // optional int32 start = 1; inline bool DescriptorProto_ExtensionRange::has_start() const { - return (_has_bits_[0] & 0x00000001u) != 0; + return (_has_bits_[0] & 0x00000002u) != 0; } inline void DescriptorProto_ExtensionRange::set_has_start() { - _has_bits_[0] |= 0x00000001u; + _has_bits_[0] |= 0x00000002u; } inline void DescriptorProto_ExtensionRange::clear_has_start() { - _has_bits_[0] &= ~0x00000001u; + _has_bits_[0] &= ~0x00000002u; } inline void DescriptorProto_ExtensionRange::clear_start() { start_ = 0; @@ -4705,13 +5241,13 @@ inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 // optional int32 end = 2; inline bool DescriptorProto_ExtensionRange::has_end() const { - return (_has_bits_[0] & 0x00000002u) != 0; + return (_has_bits_[0] & 0x00000004u) != 0; } inline void DescriptorProto_ExtensionRange::set_has_end() { - _has_bits_[0] |= 0x00000002u; + _has_bits_[0] |= 0x00000004u; } inline void DescriptorProto_ExtensionRange::clear_has_end() { - _has_bits_[0] &= ~0x00000002u; + _has_bits_[0] &= ~0x00000004u; } inline void DescriptorProto_ExtensionRange::clear_end() { end_ = 0; @@ -4727,6 +5263,52 @@ inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 va // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end) } +// optional .google.protobuf.ExtensionRangeOptions options = 3; +inline bool DescriptorProto_ExtensionRange::has_options() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DescriptorProto_ExtensionRange::set_has_options() { + _has_bits_[0] |= 0x00000001u; +} +inline void DescriptorProto_ExtensionRange::clear_has_options() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DescriptorProto_ExtensionRange::clear_options() { + if (options_ != NULL) options_->::google::protobuf::ExtensionRangeOptions::Clear(); + clear_has_options(); +} +inline const ::google::protobuf::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const { + const ::google::protobuf::ExtensionRangeOptions* p = options_; + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.options) + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::ExtensionRangeOptions*>( + &::google::protobuf::_ExtensionRangeOptions_default_instance_); +} +inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::mutable_options() { + set_has_options(); + if (options_ == NULL) { + options_ = new ::google::protobuf::ExtensionRangeOptions; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.ExtensionRange.options) + return options_; +} +inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.ExtensionRange.options) + clear_has_options(); + ::google::protobuf::ExtensionRangeOptions* temp = options_; + options_ = NULL; + return temp; +} +inline void DescriptorProto_ExtensionRange::set_allocated_options(::google::protobuf::ExtensionRangeOptions* options) { + delete options_; + options_ = options; + if (options) { + set_has_options(); + } else { + clear_has_options(); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options) +} + // ------------------------------------------------------------------- // DescriptorProto_ReservedRange @@ -5041,9 +5623,10 @@ inline void DescriptorProto::clear_options() { clear_has_options(); } inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const { + const ::google::protobuf::MessageOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::MessageOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::MessageOptions*>( + &::google::protobuf::_MessageOptions_default_instance_); } inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() { set_has_options(); @@ -5172,6 +5755,40 @@ DescriptorProto::mutable_reserved_name() { // ------------------------------------------------------------------- +// ExtensionRangeOptions + +// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; +inline int ExtensionRangeOptions::uninterpreted_option_size() const { + return uninterpreted_option_.size(); +} +inline void ExtensionRangeOptions::clear_uninterpreted_option() { + uninterpreted_option_.Clear(); +} +inline const ::google::protobuf::UninterpretedOption& ExtensionRangeOptions::uninterpreted_option(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_.Get(index); +} +inline ::google::protobuf::UninterpretedOption* ExtensionRangeOptions::mutable_uninterpreted_option(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_.Mutable(index); +} +inline ::google::protobuf::UninterpretedOption* ExtensionRangeOptions::add_uninterpreted_option() { + // @@protoc_insertion_point(field_add:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* +ExtensionRangeOptions::mutable_uninterpreted_option() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return &uninterpreted_option_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& +ExtensionRangeOptions::uninterpreted_option() const { + // @@protoc_insertion_point(field_list:google.protobuf.ExtensionRangeOptions.uninterpreted_option) + return uninterpreted_option_; +} + +// ------------------------------------------------------------------- + // FieldDescriptorProto // optional string name = 1; @@ -5602,9 +6219,10 @@ inline void FieldDescriptorProto::clear_options() { clear_has_options(); } inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const { + const ::google::protobuf::FieldOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::FieldOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::FieldOptions*>( + &::google::protobuf::_FieldOptions_default_instance_); } inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() { set_has_options(); @@ -5714,9 +6332,10 @@ inline void OneofDescriptorProto::clear_options() { clear_has_options(); } inline const ::google::protobuf::OneofOptions& OneofDescriptorProto::options() const { + const ::google::protobuf::OneofOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::OneofOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::OneofOptions*>( + &::google::protobuf::_OneofOptions_default_instance_); } inline ::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() { set_has_options(); @@ -5856,9 +6475,10 @@ inline void EnumDescriptorProto::clear_options() { clear_has_options(); } inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const { + const ::google::protobuf::EnumOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::EnumOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::EnumOptions*>( + &::google::protobuf::_EnumOptions_default_instance_); } inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() { set_has_options(); @@ -5992,9 +6612,10 @@ inline void EnumValueDescriptorProto::clear_options() { clear_has_options(); } inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const { + const ::google::protobuf::EnumValueOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::EnumValueOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::EnumValueOptions*>( + &::google::protobuf::_EnumValueOptions_default_instance_); } inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() { set_has_options(); @@ -6134,9 +6755,10 @@ inline void ServiceDescriptorProto::clear_options() { clear_has_options(); } inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const { + const ::google::protobuf::ServiceOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::ServiceOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::ServiceOptions*>( + &::google::protobuf::_ServiceOptions_default_instance_); } inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() { set_has_options(); @@ -6372,9 +6994,10 @@ inline void MethodDescriptorProto::clear_options() { clear_has_options(); } inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const { + const ::google::protobuf::MethodOptions* p = options_; // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options) - return options_ != NULL ? *options_ - : *::google::protobuf::MethodOptions::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::MethodOptions*>( + &::google::protobuf::_MethodOptions_default_instance_); } inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() { set_has_options(); @@ -8712,6 +9335,9 @@ GeneratedCodeInfo::annotation() const { return annotation_; } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // ------------------------------------------------------------------- @@ -8761,6 +9387,8 @@ GeneratedCodeInfo::annotation() const { // ------------------------------------------------------------------- +// ------------------------------------------------------------------- + // @@protoc_insertion_point(namespace_scope) @@ -8768,7 +9396,6 @@ GeneratedCodeInfo::annotation() const { } // namespace protobuf } // namespace google -#ifndef SWIG namespace google { namespace protobuf { @@ -8805,7 +9432,6 @@ inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::MethodOption } // namespace protobuf } // namespace google -#endif // SWIG // @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index 70b82a4d..f1ec5735 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -101,6 +101,8 @@ message DescriptorProto { message ExtensionRange { optional int32 start = 1; optional int32 end = 2; + + optional ExtensionRangeOptions options = 3; } repeated ExtensionRange extension_range = 5; @@ -121,6 +123,14 @@ message DescriptorProto { repeated string reserved_name = 10; } +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + // Describes a field within a message. message FieldDescriptorProto { enum Type { @@ -483,13 +493,15 @@ message FieldOptions { // The jstype option determines the JavaScript type used for values of the // field. The option is permitted only for 64 bit integral and fixed types - // (int64, uint64, sint64, fixed64, sfixed64). By default these types are - // represented as JavaScript strings. This avoids loss of precision that can - // happen when a large value is converted to a floating point JavaScript - // numbers. Specifying JS_NUMBER for the jstype causes the generated - // JavaScript code to use the JavaScript "number" type instead of strings. - // This option is an enum to permit additional types to be added, - // e.g. goog.math.Integer. + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. optional JSType jstype = 6 [default = JS_NORMAL]; enum JSType { // Use the default type. diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index 4e46b2a8..ba85ef13 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc @@ -39,8 +39,9 @@ #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format_lite_inl.h> #include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/stl_util.h> + #include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/stl_util.h> namespace google { namespace protobuf { @@ -230,7 +231,7 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::IsSubSymbol( const string& sub_symbol, const string& super_symbol) { return sub_symbol == super_symbol || (HasPrefixString(super_symbol, sub_symbol) && - super_symbol[sub_symbol.size()] == '.'); + super_symbol[sub_symbol.size()] == '.'); } template <typename Value> diff --git a/src/google/protobuf/drop_unknown_fields_test.cc b/src/google/protobuf/drop_unknown_fields_test.cc index 6f16dc53..f2f2f749 100644 --- a/src/google/protobuf/drop_unknown_fields_test.cc +++ b/src/google/protobuf/drop_unknown_fields_test.cc @@ -35,6 +35,7 @@ #include <google/protobuf/unittest_drop_unknown_fields.pb.h> #include <google/protobuf/dynamic_message.h> +#include <google/protobuf/message_lite.h> #include <gtest/gtest.h> namespace google { @@ -43,7 +44,8 @@ using unittest_drop_unknown_fields::FooWithExtraFields; namespace protobuf { -TEST(DropUnknownFieldsTest, GeneratedMessage) { +TEST(DropUnknownFieldsTest, GeneratedMessageDefaultDrop) { + ::google::protobuf::internal::SetProto3PreserveUnknownsDefault(false); FooWithExtraFields foo_with_extra_fields; foo_with_extra_fields.set_int32_value(1); foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX); @@ -54,8 +56,6 @@ TEST(DropUnknownFieldsTest, GeneratedMessage) { EXPECT_EQ(1, foo.int32_value()); EXPECT_EQ(static_cast<int>(FooWithExtraFields::QUX), static_cast<int>(foo.enum_value())); - // We don't generate unknown field accessors but the UnknownFieldSet is - // still exposed through reflection API. EXPECT_TRUE(foo.GetReflection()->GetUnknownFields(foo).empty()); ASSERT_TRUE(foo_with_extra_fields.ParseFromString(foo.SerializeAsString())); @@ -65,7 +65,29 @@ TEST(DropUnknownFieldsTest, GeneratedMessage) { EXPECT_EQ(0, foo_with_extra_fields.extra_int32_value()); } -TEST(DropUnknownFieldsTest, DynamicMessage) { +TEST(DropUnknownFieldsTest, GeneratedMessageDefaultPreserve) { + ::google::protobuf::internal::SetProto3PreserveUnknownsDefault(true); + FooWithExtraFields foo_with_extra_fields; + foo_with_extra_fields.set_int32_value(1); + foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX); + foo_with_extra_fields.set_extra_int32_value(2); + + Foo foo; + ASSERT_TRUE(foo.ParseFromString(foo_with_extra_fields.SerializeAsString())); + EXPECT_EQ(1, foo.int32_value()); + EXPECT_EQ(static_cast<int>(FooWithExtraFields::QUX), + static_cast<int>(foo.enum_value())); + EXPECT_FALSE(foo.GetReflection()->GetUnknownFields(foo).empty()); + + ASSERT_TRUE(foo_with_extra_fields.ParseFromString(foo.SerializeAsString())); + EXPECT_EQ(1, foo_with_extra_fields.int32_value()); + EXPECT_EQ(FooWithExtraFields::QUX, foo_with_extra_fields.enum_value()); + // The "extra_int32_value" field should not be lost. + EXPECT_EQ(2, foo_with_extra_fields.extra_int32_value()); +} + +TEST(DropUnknownFieldsTest, DynamicMessageDefaultDrop) { + internal::SetProto3PreserveUnknownsDefault(false); FooWithExtraFields foo_with_extra_fields; foo_with_extra_fields.set_int32_value(1); foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX); @@ -84,5 +106,25 @@ TEST(DropUnknownFieldsTest, DynamicMessage) { EXPECT_EQ(0, foo_with_extra_fields.extra_int32_value()); } +TEST(DropUnknownFieldsTest, DynamicMessageDefaultPreserve) { + internal::SetProto3PreserveUnknownsDefault(true); + FooWithExtraFields foo_with_extra_fields; + foo_with_extra_fields.set_int32_value(1); + foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX); + foo_with_extra_fields.set_extra_int32_value(2); + + google::protobuf::DynamicMessageFactory factory; + google::protobuf::scoped_ptr<google::protobuf::Message> foo( + factory.GetPrototype(Foo::descriptor())->New()); + ASSERT_TRUE(foo->ParseFromString(foo_with_extra_fields.SerializeAsString())); + EXPECT_FALSE(foo->GetReflection()->GetUnknownFields(*foo).empty()); + + ASSERT_TRUE(foo_with_extra_fields.ParseFromString(foo->SerializeAsString())); + EXPECT_EQ(1, foo_with_extra_fields.int32_value()); + EXPECT_EQ(FooWithExtraFields::QUX, foo_with_extra_fields.enum_value()); + // The "extra_int32_value" field should not be lost. + EXPECT_EQ(2, foo_with_extra_fields.extra_int32_value()); +} + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index e3c522f5..ad0eeb45 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -19,7 +19,10 @@ namespace google { namespace protobuf { -class DurationDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Duration> { +class DurationDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Duration> + _instance; } _Duration_default_instance_; namespace protobuf_google_2fprotobuf_2fduration_2eproto { @@ -32,20 +35,20 @@ namespace { } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::google::protobuf::internal::AuxillaryParseTableField(), }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const - TableStruct::schema[] = { - { NULL, NULL, 0, -1, -1, false }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, _internal_metadata_), ~0u, // no _extensions_ @@ -54,8 +57,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, seconds_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, nanos_), }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(Duration)}, }; @@ -85,18 +87,13 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _Duration_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); - _Duration_default_instance_.DefaultConstruct(); -} + _Duration_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Duration_default_instance_);} void InitDefaults() { static GOOGLE_PROTOBUF_DECLARE_ONCE(once); @@ -105,7 +102,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\036google/protobuf/duration.proto\022\017google" ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r" "\n\005nanos\030\002 \001(\005B|\n\023com.google.protobufB\rDu" @@ -117,7 +114,6 @@ void AddDescriptorsImpl() { descriptor, 227); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/duration.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -183,6 +179,7 @@ Duration::~Duration() { void Duration::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -216,9 +213,14 @@ Duration* Duration::New(::google::protobuf::Arena* arena) const { void Duration::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Duration) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + ::memset(&seconds_, 0, static_cast<size_t>( reinterpret_cast<char*>(&nanos_) - reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_)); + _internal_metadata_.Clear(); } bool Duration::MergePartialFromCodedStream( @@ -234,7 +236,7 @@ bool Duration::MergePartialFromCodedStream( // int64 seconds = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( @@ -248,7 +250,7 @@ bool Duration::MergePartialFromCodedStream( // int32 nanos = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -261,12 +263,11 @@ bool Duration::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -296,6 +297,10 @@ void Duration::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->nanos(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Duration) } @@ -316,6 +321,10 @@ void Duration::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->nanos(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Duration) return target; } @@ -324,6 +333,11 @@ size_t Duration::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Duration) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // int64 seconds = 1; if (this->seconds() != 0) { total_size += 1 + @@ -413,9 +427,11 @@ void Duration::UnsafeArenaSwap(Duration* other) { InternalSwap(other); } void Duration::InternalSwap(Duration* other) { - std::swap(seconds_, other->seconds_); - std::swap(nanos_, other->nanos_); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(seconds_, other->seconds_); + swap(nanos_, other->nanos_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Duration::GetMetadata() const { diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 02679c6a..bed112b5 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -48,8 +48,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -68,7 +69,21 @@ class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@prot CopyFrom(from); return *this; } + #if LANG_CXX11 + Duration(Duration&& from) noexcept + : Duration() { + *this = ::std::move(from); + } + inline Duration& operator=(Duration&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -87,6 +102,9 @@ class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@prot void UnsafeArenaSwap(Duration* other); void Swap(Duration* other); + friend void swap(Duration& a, Duration& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -149,7 +167,7 @@ class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@prot private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::int64 seconds_; @@ -163,6 +181,10 @@ class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@prot // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // Duration // int64 seconds = 1; @@ -193,6 +215,9 @@ inline void Duration::set_nanos(::google::protobuf::int32 value) { // @@protoc_insertion_point(field_set:google.protobuf.Duration.nanos) } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // @@protoc_insertion_point(namespace_scope) diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index ee8113e3..cdd43243 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -250,6 +250,10 @@ class DynamicMessage : public Message { }; DynamicMessage(const TypeInfo* type_info); + + // This should only be used by GetPrototypeNoLock() to avoid dead lock. + DynamicMessage(const TypeInfo* type_info, bool lock_factory); + ~DynamicMessage(); // Called on the prototype after construction to initialize message fields. @@ -280,7 +284,8 @@ class DynamicMessage : public Message { private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage); DynamicMessage(const TypeInfo* type_info, ::google::protobuf::Arena* arena); - void SharedCtor(); + + void SharedCtor(bool lock_factory); inline bool is_prototype() const { return type_info_->prototype == this || @@ -304,17 +309,22 @@ class DynamicMessage : public Message { DynamicMessage::DynamicMessage(const TypeInfo* type_info) : type_info_(type_info), cached_byte_size_(0) { - SharedCtor(); + SharedCtor(true); } DynamicMessage::DynamicMessage(const TypeInfo* type_info, ::google::protobuf::Arena* arena) : type_info_(type_info), cached_byte_size_(0) { - SharedCtor(); + SharedCtor(true); +} + +DynamicMessage::DynamicMessage(const TypeInfo* type_info, bool lock_factory) + : type_info_(type_info), cached_byte_size_(0) { + SharedCtor(lock_factory); } -void DynamicMessage::SharedCtor() { +void DynamicMessage::SharedCtor(bool lock_factory) { // We need to call constructors for various fields manually and set // default values where appropriate. We use placement new to call // constructors. If you haven't heard of placement new, I suggest Googling @@ -398,8 +408,17 @@ void DynamicMessage::SharedCtor() { new(field_ptr) Message*(NULL); } else { if (IsMapFieldInApi(field)) { - new (field_ptr) DynamicMapField( - type_info_->factory->GetPrototypeNoLock(field->message_type())); + // We need to lock in most cases to avoid data racing. Only not lock + // when the constructor is called inside GetPrototype(), in which + // case we have already locked the factory. + if (lock_factory) { + new (field_ptr) DynamicMapField( + type_info_->factory->GetPrototype(field->message_type())); + } else { + new (field_ptr) + DynamicMapField(type_info_->factory->GetPrototypeNoLock( + field->message_type())); + } } else { new (field_ptr) RepeatedPtrField<Message>(); } @@ -751,7 +770,10 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // map). To break the cyclic dependency, we have to assgin the address of // prototype into type_info first. type_info->prototype = static_cast<DynamicMessage*>(base); - DynamicMessage* prototype = new(base) DynamicMessage(type_info); + + // We have already locked the factory so we should not lock in the constructor + // of dynamic message to avoid dead lock. + DynamicMessage* prototype = new (base) DynamicMessage(type_info, false); if (type->oneof_decl_count() > 0 || num_weak_fields > 0) { // Construct default oneof instance. diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h index eed8e5bd..e29b148d 100644 --- a/src/google/protobuf/dynamic_message.h +++ b/src/google/protobuf/dynamic_message.h @@ -166,14 +166,14 @@ class LIBPROTOBUF_EXPORT DynamicMapSorter { } GOOGLE_DCHECK_EQ(result.size(), i); MapEntryMessageComparator comparator(field->message_type()); - std::sort(result.begin(), result.end(), comparator); + std::stable_sort(result.begin(), result.end(), comparator); // Complain if the keys aren't in ascending order. #ifndef NDEBUG for (size_t j = 1; j < static_cast<size_t>(map_size); j++) { if (!comparator(result[j - 1], result[j])) { GOOGLE_LOG(ERROR) << (comparator(result[j], result[j - 1]) ? - "internal error in map key sorting" : - "map keys are not unique"); + "internal error in map key sorting" : + "map keys are not unique"); } } #endif diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index 9ff146f0..6d2ea338 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -19,7 +19,10 @@ namespace google { namespace protobuf { -class EmptyDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Empty> { +class EmptyDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Empty> + _instance; } _Empty_default_instance_; namespace protobuf_google_2fprotobuf_2fempty_2eproto { @@ -32,28 +35,27 @@ namespace { } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::google::protobuf::internal::AuxillaryParseTableField(), }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const - TableStruct::schema[] = { - { NULL, NULL, 0, -1, -1, false }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~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[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(Empty)}, }; @@ -83,18 +85,13 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _Empty_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); - _Empty_default_instance_.DefaultConstruct(); -} + _Empty_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Empty_default_instance_);} void InitDefaults() { static GOOGLE_PROTOBUF_DECLARE_ONCE(once); @@ -103,7 +100,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\033google/protobuf/empty.proto\022\017google.pr" "otobuf\"\007\n\005EmptyBv\n\023com.google.protobufB\n" "EmptyProtoP\001Z\'github.com/golang/protobuf" @@ -114,7 +111,6 @@ void AddDescriptorsImpl() { descriptor, 183); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/empty.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -172,6 +168,7 @@ Empty::~Empty() { void Empty::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -205,6 +202,11 @@ Empty* Empty::New(::google::protobuf::Arena* arena) const { void Empty::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Empty) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + _internal_metadata_.Clear(); } bool Empty::MergePartialFromCodedStream( @@ -217,12 +219,11 @@ bool Empty::MergePartialFromCodedStream( tag = p.first; if (!p.second) goto handle_unusual; handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); } success: // @@protoc_insertion_point(parse_success:google.protobuf.Empty) @@ -239,6 +240,10 @@ void Empty::SerializeWithCachedSizes( ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Empty) } @@ -249,6 +254,10 @@ void Empty::SerializeWithCachedSizes( ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty) return target; } @@ -257,6 +266,11 @@ size_t Empty::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Empty) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = cached_size; @@ -326,7 +340,9 @@ void Empty::UnsafeArenaSwap(Empty* other) { InternalSwap(other); } void Empty::InternalSwap(Empty* other) { - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Empty::GetMetadata() const { diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index 306301a4..1c6e53e6 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -48,8 +48,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -68,7 +69,21 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_ CopyFrom(from); return *this; } + #if LANG_CXX11 + Empty(Empty&& from) noexcept + : Empty() { + *this = ::std::move(from); + } + inline Empty& operator=(Empty&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -87,6 +102,9 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_ void UnsafeArenaSwap(Empty* other); void Swap(Empty* other); + friend void swap(Empty& a, Empty& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -137,7 +155,7 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_ private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; mutable int _cached_size_; @@ -149,8 +167,15 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_ // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // Empty +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // @@protoc_insertion_point(namespace_scope) diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index cf5f652d..6f47c4a6 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -438,6 +438,11 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // SpaceUsed()). size_t SpaceUsedExcludingSelfLong() const; + // This method just calls SpaceUsedExcludingSelfLong() but it can not be + // inlined because the definition of SpaceUsedExcludingSelfLong() is not + // included in lite runtime and when an inline method refers to it MSVC + // will complain about unresolved symbols when building the lite runtime + // as .dll. int SpaceUsedExcludingSelf() const; private: diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index 772d2734..3e71b253 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 <google/protobuf/stubs/strutil.h> #include <google/protobuf/extension_set.h> #include <google/protobuf/unittest.pb.h> diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index 5b29d247..afc3db56 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -19,7 +19,10 @@ namespace google { namespace protobuf { -class FieldMaskDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FieldMask> { +class FieldMaskDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<FieldMask> + _instance; } _FieldMask_default_instance_; namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto { @@ -32,20 +35,20 @@ namespace { } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::google::protobuf::internal::AuxillaryParseTableField(), }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const - TableStruct::schema[] = { - { NULL, NULL, 0, -1, -1, false }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldMask, _internal_metadata_), ~0u, // no _extensions_ @@ -53,8 +56,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldMask, paths_), }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(FieldMask)}, }; @@ -84,18 +86,13 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _FieldMask_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); - _FieldMask_default_instance_.DefaultConstruct(); -} + _FieldMask_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_FieldMask_default_instance_);} void InitDefaults() { static GOOGLE_PROTOBUF_DECLARE_ONCE(once); @@ -104,7 +101,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n google/protobuf/field_mask.proto\022\017goog" "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB" "\211\001\n\023com.google.protobufB\016FieldMaskProtoP" @@ -116,7 +113,6 @@ void AddDescriptorsImpl() { descriptor, 227); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/field_mask.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -194,7 +190,12 @@ FieldMask* FieldMask::New(::google::protobuf::Arena* arena) const { void FieldMask::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldMask) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + paths_.Clear(); + _internal_metadata_.Clear(); } bool FieldMask::MergePartialFromCodedStream( @@ -210,7 +211,7 @@ bool FieldMask::MergePartialFromCodedStream( // repeated string paths = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->add_paths())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -226,12 +227,11 @@ bool FieldMask::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -261,6 +261,10 @@ void FieldMask::SerializeWithCachedSizes( 1, this->paths(i), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.FieldMask) } @@ -281,6 +285,10 @@ void FieldMask::SerializeWithCachedSizes( WriteStringToArray(1, this->paths(i), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldMask) return target; } @@ -289,6 +297,11 @@ size_t FieldMask::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldMask) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // repeated string paths = 1; total_size += 1 * ::google::protobuf::internal::FromIntSize(this->paths_size()); @@ -352,8 +365,10 @@ void FieldMask::Swap(FieldMask* other) { InternalSwap(other); } void FieldMask::InternalSwap(FieldMask* other) { + using std::swap; paths_.InternalSwap(&other->paths_); - std::swap(_cached_size_, other->_cached_size_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata FieldMask::GetMetadata() const { diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index 42110be6..b8f10389 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -48,8 +48,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -68,7 +69,21 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@pro CopyFrom(from); return *this; } + #if LANG_CXX11 + FieldMask(FieldMask&& from) noexcept + : FieldMask() { + *this = ::std::move(from); + } + inline FieldMask& operator=(FieldMask&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif static const ::google::protobuf::Descriptor* descriptor(); static const FieldMask& default_instance(); @@ -80,6 +95,9 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@pro 0; void Swap(FieldMask* other); + friend void swap(FieldMask& a, FieldMask& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -157,6 +175,10 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@pro // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // FieldMask // repeated string paths = 1; @@ -228,6 +250,9 @@ FieldMask::mutable_paths() { return &paths_; } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // @@protoc_insertion_point(namespace_scope) diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 9aebd901..263d52ab 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -44,7 +44,7 @@ #include <google/protobuf/generated_message_util.h> #include <google/protobuf/map_field.h> #include <google/protobuf/repeated_field.h> -// #include "google/protobuf/bridge/compatibility_mode_support.h" +#include <google/protobuf/wire_format.h> #define GOOGLE_PROTOBUF_HAS_ONEOF @@ -197,32 +197,14 @@ GeneratedMessageReflection::GeneratedMessageReflection( GeneratedMessageReflection::~GeneratedMessageReflection() {} -namespace { -UnknownFieldSet* empty_unknown_field_set_ = NULL; -GOOGLE_PROTOBUF_DECLARE_ONCE(empty_unknown_field_set_once_); - -void DeleteEmptyUnknownFieldSet() { - delete empty_unknown_field_set_; - empty_unknown_field_set_ = NULL; -} - -void InitEmptyUnknownFieldSet() { - empty_unknown_field_set_ = new UnknownFieldSet; - internal::OnShutdown(&DeleteEmptyUnknownFieldSet); -} - -const UnknownFieldSet& GetEmptyUnknownFieldSet() { - ::google::protobuf::GoogleOnceInit(&empty_unknown_field_set_once_, &InitEmptyUnknownFieldSet); - return *empty_unknown_field_set_; -} -} // namespace - const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields( const Message& message) const { - if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { + if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 && + !GetProto3PreserveUnknownsDefault()) { // We have to ensure that any mutations made to the return value of - // MutableUnknownFields() are not reflected here. - return GetEmptyUnknownFieldSet(); + // MutableUnknownFields() are not reflected here when Proto3 defaults to + // discard unknowns. + return *UnknownFieldSet::default_instance(); } else { return GetInternalMetadataWithArena(message).unknown_fields(); } @@ -1020,7 +1002,7 @@ void GeneratedMessageReflection::ListFields( schema_.HasHasbits() ? GetHasBits(message) : NULL; const uint32* const has_bits_indices = schema_.has_bit_indices_; const uint32* const oneof_case_array = - &GetConstRefAtOffset<uint32>(message, schema_.oneof_case_offset_); + GetConstPointerAtOffset<uint32>(&message, schema_.oneof_case_offset_); output->reserve(descriptor_->field_count()); for (int i = 0; i <= last_non_weak_field_index_; i++) { const FieldDescriptor* field = descriptor_->field(i); @@ -2288,6 +2270,8 @@ class AssignDescriptorsHelper { file_level_enum_descriptors_++; } + const Metadata* GetCurrentMetadataPtr() const { return file_level_metadata_; } + private: MessageFactory* factory_; Metadata* file_level_metadata_; @@ -2297,6 +2281,41 @@ class AssignDescriptorsHelper { const uint32* offsets_; }; +// We have the routines that assign descriptors and build reflection +// automatically delete the allocated reflection. MetadataOwner owns +// all the allocated reflection instances. +struct MetadataOwner { + void AddArray(const Metadata* begin, const Metadata* end) { + MutexLock lock(&mu_); + metadata_arrays_.push_back(std::make_pair(begin, end)); + } + + static MetadataOwner* Instance() { + static MetadataOwner* res = new MetadataOwner; + return res; + } + + private: + // Use the constructor to register the shutdown code. Because c++ makes sure + // this called only once. + MetadataOwner() { OnShutdown(&DeleteMetadata); } + ~MetadataOwner() { + for (int i = 0; i < metadata_arrays_.size(); i++) { + for (const Metadata* m = metadata_arrays_[i].first; + m < metadata_arrays_[i].second; m++) { + delete m->reflection; + } + } + } + + static void DeleteMetadata() { + delete Instance(); + } + + Mutex mu_; + std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_; +}; + } // namespace void AssignDescriptors( @@ -2329,6 +2348,8 @@ void AssignDescriptors( file_level_service_descriptors[i] = file->service(i); } } + MetadataOwner::Instance()->AddArray( + file_level_metadata, helper.GetCurrentMetadataPtr()); } void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) { @@ -2349,6 +2370,18 @@ void RegisterAllTypes(const Metadata* file_level_metadata, int size) { RegisterAllTypesInternal(file_level_metadata, size); } +void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag, + uint32 has_offset, + ::google::protobuf::io::CodedOutputStream* output) { + const void* ptr = base + offset; + const InternalMetadataWithArena* metadata = + static_cast<const InternalMetadataWithArena*>(ptr); + if (metadata->have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + metadata->unknown_fields(), output); + } +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 6045b3aa..f6ce16a7 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -717,6 +717,11 @@ LIBPROTOBUF_EXPORT void AssignDescriptors( LIBPROTOBUF_EXPORT void RegisterAllTypes(const Metadata* file_level_metadata, int size); +// These cannot be in lite so we put them in the reflection. +LIBPROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag, + uint32 has_offset, + ::google::protobuf::io::CodedOutputStream* output); + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/generated_message_table_driven.cc b/src/google/protobuf/generated_message_table_driven.cc index f8fda9c6..29af1ef6 100644 --- a/src/google/protobuf/generated_message_table_driven.cc +++ b/src/google/protobuf/generated_message_table_driven.cc @@ -32,643 +32,70 @@ #include <google/protobuf/stubs/type_traits.h> +#include <google/protobuf/generated_message_table_driven_lite.h> #include <google/protobuf/io/zero_copy_stream_impl_lite.h> -#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/metadata.h> #include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format.h> #include <google/protobuf/wire_format_lite.h> #include <google/protobuf/wire_format_lite_inl.h> - namespace google { namespace protobuf { namespace internal { - namespace { -enum StringType { - StringType_STRING = 0, - StringType_CORD = 1, - StringType_STRING_PIECE = 2 -}; - -template <typename Type> -inline Type* Raw(MessageLite* msg, int64 offset) { - return reinterpret_cast<Type*>(reinterpret_cast<uint8*>(msg) + offset); +UnknownFieldSet* MutableUnknownFields(MessageLite* msg, int64 arena_offset) { + return Raw<InternalMetadataWithArena>(msg, arena_offset) + ->mutable_unknown_fields(); } -template <typename Type> -inline const Type* Raw(const MessageLite* msg, int64 offset) { - return reinterpret_cast<const Type*>(reinterpret_cast<const uint8*>(msg) + - offset); -} +struct UnknownFieldHandler { + static bool Skip(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input, + int tag) { + GOOGLE_DCHECK(table.unknown_field_set); -inline Arena* GetArena(MessageLite* msg, int64 arena_offset) { - if (GOOGLE_PREDICT_FALSE(arena_offset == -1)) { - return NULL; + return WireFormat::SkipField(input, tag, + MutableUnknownFields(msg, table.arena_offset)); } - return Raw<InternalMetadataWithArenaLite>(msg, arena_offset)->arena(); -} - -template <typename Type> -inline Type* AddField(MessageLite* msg, int64 offset) { -#if LANG_CXX11 - static_assert(google::protobuf::internal::has_trivial_copy<Type>::value, - "Do not assign"); -#endif - - google::protobuf::RepeatedField<Type>* repeated = - Raw<google::protobuf::RepeatedField<Type> >(msg, offset); - return repeated->Add(); -} + static void Varint(MessageLite* msg, const ParseTable& table, + int tag, int value) { + GOOGLE_DCHECK(table.unknown_field_set); -template <> -inline string* AddField<string>(MessageLite* msg, int64 offset) { - google::protobuf::RepeatedPtrField<string>* repeated = - Raw<google::protobuf::RepeatedPtrField<string> >(msg, offset); - return repeated->Add(); -} - - -template <typename Type> -inline void AddField(MessageLite* msg, int64 offset, Type value) { -#if LANG_CXX11 - static_assert(google::protobuf::internal::has_trivial_copy<Type>::value, - "Do not assign"); -#endif - *AddField<Type>(msg, offset) = value; -} - -inline void SetBit(uint32* has_bits, uint32 has_bit_index) { - GOOGLE_DCHECK(has_bits != NULL); - - uint32 mask = static_cast<uint32>(1u) << (has_bit_index % 32); - has_bits[has_bit_index / 32u] |= mask; -} - -template <typename Type> -inline Type* MutableField(MessageLite* msg, uint32* has_bits, - uint32 has_bit_index, int64 offset) { - SetBit(has_bits, has_bit_index); - return Raw<Type>(msg, offset); -} - -template <typename Type> -inline void SetField(MessageLite* msg, uint32* has_bits, uint32 has_bit_index, - int64 offset, Type value) { -#if LANG_CXX11 - static_assert(google::protobuf::internal::has_trivial_copy<Type>::value, - "Do not assign"); -#endif - *MutableField<Type>(msg, has_bits, has_bit_index, offset) = value; -} - -template <bool repeated, bool validate, StringType ctype> -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<string>(msg, offset); - GOOGLE_DCHECK(value != NULL); - } else { - // TODO(ckennelly): Is this optimal? - value = MutableField<ArenaStringPtr>(msg, has_bits, has_bit_index, offset) - ->Mutable(static_cast<const string*>(default_ptr), arena); - GOOGLE_DCHECK(value != NULL); - } + MutableUnknownFields(msg, table.arena_offset)->AddVarint( + WireFormatLite::GetTagFieldNumber(tag), value); + } - if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) { + static bool ParseExtension( + MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input, int tag) { + ExtensionSet* extensions = GetExtensionSet(msg, table.extension_offset); + if (extensions == NULL) { 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; -} + const Message* prototype = down_cast<const Message*>( + table.default_instance()); -string* MutableUnknownFields(MessageLite* msg, int64 arena_offset) { - return Raw<InternalMetadataWithArenaLite>(msg, arena_offset) - ->mutable_unknown_fields(); -} + GOOGLE_DCHECK(prototype != NULL); + GOOGLE_DCHECK(table.unknown_field_set); + UnknownFieldSet* unknown_fields = + MutableUnknownFields(msg, table.arena_offset); -// 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; - } + return extensions->ParseField(tag, input, prototype, unknown_fields); } }; -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<io::CodedInputStream::Limit, int> 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<RepeatedMessageTypeHandler>( - const_cast<MessageLite*>(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<uint32>(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<unsigned char>(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<CPPTYPE>* values = \ - Raw<google::protobuf::RepeatedField<CPPTYPE> >(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<false, false, StringType_STRING>( - 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<true, false, StringType_STRING>( - 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<false, true, StringType_STRING>( - 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<true, true, StringType_STRING>( - 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<MessageLite*>(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<RepeatedPtrFieldBase>(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<MessageLite*>(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<RepeatedPtrFieldBase>(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<unsigned char>(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<WireFormatLite::FieldType>( - processing_type ^ kRepeatedMask)) { -#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ - case WireFormatLite::TYPE_##TYPE: { \ - google::protobuf::RepeatedField<CPPTYPE>* values = \ - Raw<google::protobuf::RepeatedField<CPPTYPE> >(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<int>* values = - Raw<google::protobuf::RepeatedField<int> >(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; - } - } - } +bool MergePartialFromCodedStream( + MessageLite* msg, const ParseTable& table, io::CodedInputStream* input) { + return MergePartialFromCodedStreamImpl<UnknownFieldHandler, + InternalMetadataWithArena>(msg, table, + input); } } // namespace internal diff --git a/src/google/protobuf/generated_message_table_driven.h b/src/google/protobuf/generated_message_table_driven.h index 557c57d3..5eb63dbd 100644 --- a/src/google/protobuf/generated_message_table_driven.h +++ b/src/google/protobuf/generated_message_table_driven.h @@ -31,7 +31,11 @@ #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__ #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__ +#include <google/protobuf/map.h> +#include <google/protobuf/map_entry_lite.h> #include <google/protobuf/message_lite.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/wire_format_lite_inl.h> #if LANG_CXX11 #define PROTOBUF_CONSTEXPR constexpr @@ -54,10 +58,14 @@ namespace google { namespace protobuf { namespace internal { +// Processing-type masks. static PROTOBUF_CONSTEXPR const unsigned char kOneofMask = 0x40; static PROTOBUF_CONSTEXPR const unsigned char kRepeatedMask = 0x20; -// Check this against types. +// Mask for the raw type: either a WireFormatLite::FieldType or one of the +// ProcessingTypes below, without the oneof or repeated flag. +static PROTOBUF_CONSTEXPR const unsigned char kTypeMask = 0x1f; +// Wire type masks. static PROTOBUF_CONSTEXPR const unsigned char kNotPackedMask = 0x10; static PROTOBUF_CONSTEXPR const unsigned char kInvalidMask = 0x20; @@ -66,10 +74,11 @@ enum ProcessingTypes { TYPE_STRING_STRING_PIECE = 20, TYPE_BYTES_CORD = 21, TYPE_BYTES_STRING_PIECE = 22, + TYPE_MAP = 23, }; #if LANG_CXX11 -static_assert(TYPE_BYTES_STRING_PIECE < kRepeatedMask, "Invalid enum"); +static_assert(TYPE_MAP < kRepeatedMask, "Invalid enum"); #endif // TODO(ckennelly): Add a static assertion to ensure that these masks do not @@ -81,7 +90,9 @@ static_assert(TYPE_BYTES_STRING_PIECE < kRepeatedMask, "Invalid enum"); // AuxillaryParseTableField. struct ParseTableField { uint32 offset; - uint32 has_bit_index; + // The presence_index ordinarily represents a has_bit index, but for fields + // inside a oneof it represents the index in _oneof_case_. + uint32 presence_index; unsigned char normal_wiretype; unsigned char packed_wiretype; @@ -100,7 +111,6 @@ union AuxillaryParseTableField { // Enums struct enum_aux { EnumValidator validator; - const char* name; }; enum_aux enums; // Group, messages @@ -119,11 +129,14 @@ union AuxillaryParseTableField { struct string_aux { const void* default_ptr; const char* field_name; - bool strict_utf8; - const char* name; }; string_aux strings; + struct map_aux { + bool (*parse_map)(io::CodedInputStream*, void*); + }; + map_aux maps; + #if LANG_CXX11 AuxillaryParseTableField() = default; #else @@ -135,6 +148,9 @@ union AuxillaryParseTableField { AuxillaryParseTableField::message_aux m) : messages(m) {} PROTOBUF_CONSTEXPR AuxillaryParseTableField( AuxillaryParseTableField::string_aux s) : strings(s) {} + PROTOBUF_CONSTEXPR AuxillaryParseTableField( + AuxillaryParseTableField::map_aux m) + : maps(m) {} }; struct ParseTable { @@ -145,8 +161,19 @@ struct ParseTable { // TODO(ckennelly): Vet these for sign extension. int64 has_bits_offset; + int64 oneof_case_offset; + int64 extension_offset; int64 arena_offset; - int unknown_field_set; + + // ExplicitlyInitialized<T> -> 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_instance_void; + const MessageLite* default_instance() const { + return static_cast<const MessageLite*>(default_instance_void); + } + + bool unknown_field_set; }; // TODO(jhen): Remove the __NVCC__ check when we get a version of nvcc that @@ -163,8 +190,39 @@ static_assert(std::is_pod<AuxillaryParseTableField::string_aux>::value, ""); static_assert(std::is_pod<ParseTable>::value, ""); #endif +// TODO(ckennelly): Consolidate these implementations into a single one, using +// dynamic dispatch to the appropriate unknown field handler. bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table, io::CodedInputStream* input); +bool MergePartialFromCodedStreamLite(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input); + +template <typename MEntry> +struct MapEntryToMapField; + +template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +struct MapEntryToMapField<MapEntryLite<Key, Value, kKeyFieldType, + kValueFieldType, default_enum_value> > { + typedef MapFieldLite<MapEntryLite<Key, Value, kKeyFieldType, kValueFieldType, + default_enum_value>, + Key, Value, kKeyFieldType, kValueFieldType, + default_enum_value> + MapFieldType; +}; + +template <typename Entry> +bool ParseMap(io::CodedInputStream* input, void* map_field) { + typedef typename MapEntryToMapField<Entry>::MapFieldType MapFieldType; + typedef google::protobuf::Map<typename Entry::EntryKeyType, + typename Entry::EntryValueType> + MapType; + typedef typename Entry::template Parser<MapFieldType, MapType> ParserType; + + ParserType parser(static_cast<MapFieldType*>(map_field)); + return ::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(input, + &parser); +} } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/generated_message_table_driven_lite.cc b/src/google/protobuf/generated_message_table_driven_lite.cc new file mode 100644 index 00000000..90a50505 --- /dev/null +++ b/src/google/protobuf/generated_message_table_driven_lite.cc @@ -0,0 +1,109 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/generated_message_table_driven_lite.h> + +#include <google/protobuf/stubs/type_traits.h> + +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/wire_format_lite_inl.h> + +namespace google { +namespace protobuf { +namespace internal { + +namespace { + +string* MutableUnknownFields(MessageLite* msg, int64 arena_offset) { + return Raw<InternalMetadataWithArenaLite>(msg, arena_offset) + ->mutable_unknown_fields(); +} + +struct UnknownFieldHandlerLite { + static bool Skip(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input, + int tag) { + 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); + + return ::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream); + } + + static void Varint(MessageLite* msg, const ParseTable& table, + int tag, int value) { + 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); + } + + static bool ParseExtension( + MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input, int tag) { + ExtensionSet* extensions = GetExtensionSet(msg, table.extension_offset); + if (extensions == NULL) { + return false; + } + + const MessageLite* prototype = table.default_instance(); + + 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); + return extensions->ParseField( + tag, input, prototype, &unknown_fields_stream); + } +}; + +} // namespace + +bool MergePartialFromCodedStreamLite( + MessageLite* msg, const ParseTable& table, io::CodedInputStream* input) { + return MergePartialFromCodedStreamImpl<UnknownFieldHandlerLite, + InternalMetadataWithArenaLite>( + msg, table, input); +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/generated_message_table_driven_lite.h b/src/google/protobuf/generated_message_table_driven_lite.h new file mode 100644 index 00000000..20b4da21 --- /dev/null +++ b/src/google/protobuf/generated_message_table_driven_lite.h @@ -0,0 +1,823 @@ +// 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_LITE_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__ + +#include <google/protobuf/generated_message_table_driven.h> + +#include <google/protobuf/stubs/type_traits.h> + +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/wire_format_lite_inl.h> + + +namespace google { +namespace protobuf { +namespace internal { + + +enum StringType { + StringType_STRING = 0, + StringType_CORD = 1, + StringType_STRING_PIECE = 2 +}; + +// Logically a superset of StringType, consisting of all field types that +// require special initialization. +enum ProcessingType { + ProcessingType_STRING = 0, + ProcessingType_CORD = 1, + ProcessingType_STRING_PIECE = 2, + ProcessingType_MESSAGE = 3 +}; + +enum Cardinality { + Cardinality_SINGULAR = 0, + Cardinality_REPEATED = 1, + Cardinality_ONEOF = 3 +}; + +template <typename Type> +inline Type* Raw(MessageLite* msg, int64 offset) { + return reinterpret_cast<Type*>(reinterpret_cast<uint8*>(msg) + offset); +} + +template <typename Type> +inline const Type* Raw(const MessageLite* msg, int64 offset) { + return reinterpret_cast<const Type*>(reinterpret_cast<const uint8*>(msg) + + offset); +} + +template <typename InternalMetadata> +inline Arena* GetArena(MessageLite* msg, int64 arena_offset) { + if (GOOGLE_PREDICT_FALSE(arena_offset == -1)) { + return NULL; + } + + return Raw<InternalMetadata>(msg, arena_offset)->arena(); +} + +inline ExtensionSet* GetExtensionSet(MessageLite* msg, int64 extension_offset) { + if (extension_offset == -1) { + return NULL; + } + + return Raw<ExtensionSet>(msg, extension_offset); +} + +template <typename Type> +inline Type* AddField(MessageLite* msg, int64 offset) { +#if LANG_CXX11 + static_assert(has_trivial_copy<Type>::value, + "Do not assign"); +#endif + + google::protobuf::RepeatedField<Type>* repeated = + Raw<google::protobuf::RepeatedField<Type> >(msg, offset); + return repeated->Add(); +} + +template <> +inline string* AddField<string>(MessageLite* msg, int64 offset) { + google::protobuf::RepeatedPtrField<string>* repeated = + Raw<google::protobuf::RepeatedPtrField<string> >(msg, offset); + return repeated->Add(); +} + + +template <typename Type> +inline void AddField(MessageLite* msg, int64 offset, Type value) { +#if LANG_CXX11 + static_assert(has_trivial_copy<Type>::value, + "Do not assign"); +#endif + *AddField<Type>(msg, offset) = value; +} + +inline void SetBit(uint32* has_bits, uint32 has_bit_index) { + GOOGLE_DCHECK(has_bits != NULL); + + uint32 mask = static_cast<uint32>(1u) << (has_bit_index % 32); + has_bits[has_bit_index / 32u] |= mask; +} + +template <typename Type> +inline Type* MutableField(MessageLite* msg, uint32* has_bits, + uint32 has_bit_index, int64 offset) { + SetBit(has_bits, has_bit_index); + return Raw<Type>(msg, offset); +} + +template <typename Type> +inline void SetField(MessageLite* msg, uint32* has_bits, uint32 has_bit_index, + int64 offset, Type value) { +#if LANG_CXX11 + static_assert(has_trivial_copy<Type>::value, + "Do not assign"); +#endif + *MutableField<Type>(msg, has_bits, has_bit_index, offset) = value; +} + +template <typename Type> +inline void SetOneofField(MessageLite* msg, uint32* oneof_case, + uint32 oneof_case_index, int64 offset, + int field_number, Type value) { + oneof_case[oneof_case_index] = field_number; + *Raw<Type>(msg, offset) = value; +} + +// Clears a oneof field. The field argument should correspond to the particular +// field that is currently set in the oneof. +inline void ClearOneofField(const ParseTableField& field, Arena* arena, + MessageLite* msg) { + switch (field.processing_type & kTypeMask) { + case WireFormatLite::TYPE_MESSAGE: + if (arena == NULL) { + delete *Raw<MessageLite*>(msg, field.offset); + } + break; + + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + Raw<ArenaStringPtr>(msg, field.offset) + ->Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena); + break; + + default: + // No cleanup needed. + break; + } +} + +// Clears and reinitializes a oneof field as necessary, in preparation for +// parsing a new value with type field_type and field number field_number. +// +// Note: the oneof_case argument should point directly to the _oneof_case_ +// element corresponding to this particular oneof, not to the beginning of the +// _oneof_case_ array. +template <ProcessingType field_type> +inline void ResetOneofField(const ParseTable& table, int field_number, + Arena* arena, MessageLite* msg, uint32* oneof_case, + int64 offset, const void* default_ptr) { + if (*oneof_case == field_number) { + // The oneof is already set to the right type, so there is no need to clear + // it. + return; + } + + if (*oneof_case != 0) { + ClearOneofField(table.fields[*oneof_case], arena, msg); + } + *oneof_case = field_number; + + switch (field_type) { + case ProcessingType_STRING: + Raw<ArenaStringPtr>(msg, offset) + ->UnsafeSetDefault(static_cast<const string*>(default_ptr)); + break; + case ProcessingType_MESSAGE: + MessageLite** submessage = Raw<MessageLite*>(msg, offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + *submessage = prototype->New(arena); + break; + } +} + +template <Cardinality cardinality, bool validate, StringType ctype> +static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, + Arena* arena, uint32* has_bits, + uint32 has_bit_index, int64 offset, + const void* default_ptr, + const char* field_name) { +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + const char* sdata; + size_t size; +#endif + + string* value; + switch (cardinality) { + case Cardinality_SINGULAR: + // TODO(ckennelly): Is this optimal? + value = + MutableField<ArenaStringPtr>(msg, has_bits, has_bit_index, offset) + ->Mutable(static_cast<const string*>(default_ptr), arena); + break; + case Cardinality_REPEATED: + value = AddField<string>(msg, offset); + break; + case Cardinality_ONEOF: + value = Raw<ArenaStringPtr>(msg, offset) + ->Mutable(static_cast<const string*>(default_ptr), arena); + break; + } + 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) { + WireFormatLite::VerifyUtf8String(sdata, size, WireFormatLite::PARSE, + field_name); + } +#endif + + return true; +} + +template <typename UnknownFieldHandler, typename InternalMetadata, + Cardinality cardinality> +inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input, + MessageLite* msg, uint32* presence, + uint32 presence_index, int64 offset, uint32 tag, + int field_number) { + 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)) { + switch (cardinality) { + case Cardinality_SINGULAR: + SetField(msg, presence, presence_index, offset, value); + break; + case Cardinality_REPEATED: + AddField(msg, offset, value); + break; + case Cardinality_ONEOF: + ClearOneofField(table.fields[presence[presence_index]], + GetArena<InternalMetadata>(msg, table.arena_offset), + msg); + SetOneofField(msg, presence, presence_index, offset, field_number, + value); + break; + } + } else { + UnknownFieldHandler::Varint(msg, table, tag, value); + } + + return true; +} + +// 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) { + if (GOOGLE_PREDICT_FALSE(!input->IncrementRecursionDepth())) { + return false; + } + + if (GOOGLE_PREDICT_FALSE(!value->MergePartialFromCodedStream(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) { + int length; + if (GOOGLE_PREDICT_FALSE(!input->ReadVarintSizeAsInt(&length))) { + return false; + } + + std::pair<io::CodedInputStream::Limit, int> p = + input->IncrementRecursionDepthAndPushLimit(length); + if (GOOGLE_PREDICT_FALSE(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); +} + +class MergePartialFromCodedStreamHelper { + public: + static MessageLite* Add(RepeatedPtrFieldBase* field, + const MessageLite* prototype) { + return field->Add<RepeatedMessageTypeHandler>( + const_cast<MessageLite*>(prototype)); + } +}; + +template <typename UnknownFieldHandler, typename InternalMetadata> +bool MergePartialFromCodedStreamImpl(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<uint32>(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 (field_number > table.max_field_number) { + // check for possible extensions + if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) { + // successfully parsed + continue; + } + + if (GOOGLE_PREDICT_FALSE(!UnknownFieldHandler::Skip(msg, table, input, tag))) { + 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 presence_index = data->presence_index; + const int64 offset = data->offset; + const unsigned char processing_type = data->processing_type; + + if (data->normal_wiretype == static_cast<unsigned char>(wire_type)) { + // TODO(ckennelly): Use a computed goto on GCC/LLVM or otherwise eliminate + // the bounds check on processing_type. + + switch (processing_type) { +#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, presence_index, offset, value); \ + break; \ + } \ + case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: { \ + google::protobuf::RepeatedField<CPPTYPE>* values = \ + Raw<google::protobuf::RepeatedField<CPPTYPE> >(msg, offset); \ + if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>( \ + data->tag_size, tag, input, values)))) { \ + return false; \ + } \ + break; \ + } \ + case (WireFormatLite::TYPE_##TYPE) | kOneofMask: { \ + uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); \ + CPPTYPE value; \ + if (GOOGLE_PREDICT_FALSE( \ + (!WireFormatLite::ReadPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \ + return false; \ + } \ + ClearOneofField(table.fields[oneof_case[presence_index]], \ + GetArena<InternalMetadata>(msg, table.arena_offset), msg); \ + SetOneofField(msg, oneof_case, presence_index, offset, field_number, \ + value); \ + 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 + case WireFormatLite::TYPE_BYTES: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case WireFormatLite::TYPE_STRING: +#endif + { + Arena* const arena = + GetArena<InternalMetadata>(msg, table.arena_offset); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + + if (GOOGLE_PREDICT_FALSE(( + !HandleString<Cardinality_SINGULAR, false, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, NULL)))) { + return false; + } + break; + } + case WireFormatLite::TYPE_BYTES | kOneofMask: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case WireFormatLite::TYPE_STRING | kOneofMask: +#endif + { + Arena* const arena = + GetArena<InternalMetadata>(msg, table.arena_offset); + uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + + ResetOneofField<ProcessingType_STRING>( + table, field_number, arena, msg, oneof_case + presence_index, + offset, default_ptr); + + if (GOOGLE_PREDICT_FALSE( + (!HandleString<Cardinality_ONEOF, false, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, NULL)))) { + return false; + } + break; + } + case (WireFormatLite::TYPE_BYTES) | kRepeatedMask: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case (WireFormatLite::TYPE_STRING) | kRepeatedMask: +#endif + { + Arena* const arena = + GetArena<InternalMetadata>(msg, table.arena_offset); + const void* default_ptr = + table.aux[field_number].strings.default_ptr; + + if (GOOGLE_PREDICT_FALSE(( + !HandleString<Cardinality_REPEATED, false, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, NULL)))) { + return false; + } + break; + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case (WireFormatLite::TYPE_STRING): { + Arena* const arena = + GetArena<InternalMetadata>(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; + + if (GOOGLE_PREDICT_FALSE( + (!HandleString<Cardinality_SINGULAR, true, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, field_name)))) { + return false; + } + break; + } + case (WireFormatLite::TYPE_STRING) | kRepeatedMask: { + Arena* const arena = + GetArena<InternalMetadata>(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; + + if (GOOGLE_PREDICT_FALSE( + (!HandleString<Cardinality_REPEATED, true, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, field_name)))) { + return false; + } + break; + } + case (WireFormatLite::TYPE_STRING) | kOneofMask: { + Arena* const arena = + GetArena<InternalMetadata>(msg, table.arena_offset); + uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + const char* field_name = table.aux[field_number].strings.field_name; + + ResetOneofField<ProcessingType_STRING>( + table, field_number, arena, msg, oneof_case + presence_index, + offset, default_ptr); + + if (GOOGLE_PREDICT_FALSE( + (!HandleString<Cardinality_ONEOF, true, StringType_STRING>( + input, msg, arena, has_bits, presence_index, offset, + default_ptr, field_name)))) { + return false; + } + break; + } +#endif + case WireFormatLite::TYPE_ENUM: { + if (GOOGLE_PREDICT_FALSE((!HandleEnum<UnknownFieldHandler, InternalMetadata, + Cardinality_SINGULAR>( + table, input, msg, has_bits, presence_index, offset, tag, + field_number)))) { + return false; + } + break; + } + case WireFormatLite::TYPE_ENUM | kRepeatedMask: { + if (GOOGLE_PREDICT_FALSE((!HandleEnum<UnknownFieldHandler, InternalMetadata, + Cardinality_REPEATED>( + table, input, msg, has_bits, presence_index, offset, tag, + field_number)))) { + return false; + } + break; + } + case WireFormatLite::TYPE_ENUM | kOneofMask: { + uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); + if (GOOGLE_PREDICT_FALSE((!HandleEnum<UnknownFieldHandler, InternalMetadata, + Cardinality_ONEOF>( + table, input, msg, oneof_case, presence_index, offset, tag, + field_number)))) { + return false; + } + break; + } + case WireFormatLite::TYPE_GROUP: { + MessageLite** submsg_holder = + MutableField<MessageLite*>(msg, has_bits, presence_index, offset); + MessageLite* submsg = *submsg_holder; + + if (submsg == NULL) { + Arena* const arena = + GetArena<InternalMetadata>(msg, table.arena_offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + submsg = prototype->New(arena); + *submsg_holder = submsg; + } + + if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadGroup( + field_number, input, submsg))) { + return false; + } + + break; + } + case WireFormatLite::TYPE_GROUP | kRepeatedMask: { + RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + GOOGLE_DCHECK(prototype != NULL); + + MessageLite* submsg = + MergePartialFromCodedStreamHelper::Add(field, prototype); + + if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadGroup( + field_number, input, submsg))) { + return false; + } + + break; + } + case WireFormatLite::TYPE_MESSAGE: { + MessageLite** submsg_holder = + MutableField<MessageLite*>(msg, has_bits, presence_index, offset); + MessageLite* submsg = *submsg_holder; + + if (submsg == NULL) { + Arena* const arena = + GetArena<InternalMetadata>(msg, table.arena_offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + submsg = prototype->New(arena); + *submsg_holder = submsg; + } + + if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadMessage(input, submsg))) { + return false; + } + + break; + } + // TODO(ckennelly): Adapt ReadMessageNoVirtualNoRecursionDepth and + // manage input->IncrementRecursionDepth() here. + case WireFormatLite::TYPE_MESSAGE | kRepeatedMask: { + RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + GOOGLE_DCHECK(prototype != NULL); + + MessageLite* submsg = + MergePartialFromCodedStreamHelper::Add(field, prototype); + + if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadMessage(input, submsg))) { + return false; + } + + break; + } + case WireFormatLite::TYPE_MESSAGE | kOneofMask: { + Arena* const arena = + GetArena<InternalMetadata>(msg, table.arena_offset); + uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset); + MessageLite** submsg_holder = Raw<MessageLite*>(msg, offset); + ResetOneofField<ProcessingType_MESSAGE>( + table, field_number, arena, msg, oneof_case + presence_index, + offset, NULL); + MessageLite* submsg = *submsg_holder; + + if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadMessage(input, submsg))) { + return false; + } + + break; + } + case TYPE_MAP: { + if (GOOGLE_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)( + input, Raw<void>(msg, offset)))) { + return false; + } + break; + } + case 0: { + // Done. + return true; + } + default: + break; + } + } else if (data->packed_wiretype == static_cast<unsigned char>(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); + GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask); + + + + // TODO(ckennelly): Use a computed goto on GCC/LLVM. + // + // Mask out kRepeatedMask bit, allowing the jump table to be smaller. + switch (static_cast<WireFormatLite::FieldType>( + processing_type ^ kRepeatedMask)) { +#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case WireFormatLite::TYPE_##TYPE: { \ + google::protobuf::RepeatedField<CPPTYPE>* values = \ + Raw<google::protobuf::RepeatedField<CPPTYPE> >(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<int>* values = + Raw<google::protobuf::RepeatedField<int> >(msg, offset); + + 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 { + // TODO(ckennelly): Consider caching here. + UnknownFieldHandler::Varint(msg, table, tag, 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; + } + + // check for possible extensions + if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) { + // successfully parsed + continue; + } + + // process unknown field. + if (GOOGLE_PREDICT_FALSE(!UnknownFieldHandler::Skip(msg, table, input, tag))) { + return false; + } + } + } +} + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__ diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index 35d8156e..c9dfe61a 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -35,7 +35,17 @@ #include <google/protobuf/generated_message_util.h> #include <limits> +#include <vector> +#include <google/protobuf/io/coded_stream_inl.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/metadata_lite.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/wire_format_lite_inl.h> namespace google { namespace protobuf { @@ -51,7 +61,7 @@ double NaN() { ExplicitlyConstructed< ::std::string> fixed_address_empty_string; GOOGLE_PROTOBUF_DECLARE_ONCE(empty_string_once_init_); -void DeleteEmptyString() { fixed_address_empty_string.Shutdown(); } +void DeleteEmptyString() { fixed_address_empty_string.Destruct(); } void InitEmptyString() { fixed_address_empty_string.DefaultConstruct(); @@ -75,6 +85,616 @@ void InitProtobufDefaults() { GetEmptyString(); } +template <typename T> +const T& Get(const void* ptr) { + return *static_cast<const T*>(ptr); +} + +// PrimitiveTypeHelper is a wrapper around the interface of WireFormatLite. +// WireFormatLite has a very inconvenient interface with respect to template +// meta-programming. This class wraps the different named functions into +// a single Serialize / SerializeToArray interface. +template <int type> +struct PrimitiveTypeHelper; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_BOOL> { + typedef bool Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + WireFormatLite::WriteBoolNoTag(Get<bool>(ptr), output); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + return WireFormatLite::WriteBoolNoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT32> { + typedef int32 Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + WireFormatLite::WriteInt32NoTag(Get<int32>(ptr), output); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + return WireFormatLite::WriteInt32NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT32> { + typedef int32 Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + WireFormatLite::WriteSInt32NoTag(Get<int32>(ptr), output); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + return WireFormatLite::WriteSInt32NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT32> { + typedef uint32 Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + WireFormatLite::WriteUInt32NoTag(Get<uint32>(ptr), output); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + return WireFormatLite::WriteUInt32NoTagToArray(Get<Type>(ptr), buffer); + } +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT64> { + typedef int64 Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + WireFormatLite::WriteInt64NoTag(Get<int64>(ptr), output); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + return WireFormatLite::WriteInt64NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT64> { + typedef int64 Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + WireFormatLite::WriteSInt64NoTag(Get<int64>(ptr), output); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + return WireFormatLite::WriteSInt64NoTagToArray(Get<Type>(ptr), buffer); + } +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT64> { + typedef uint64 Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + WireFormatLite::WriteUInt64NoTag(Get<uint64>(ptr), output); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + return WireFormatLite::WriteUInt64NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> { + typedef uint32 Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + WireFormatLite::WriteFixed32NoTag(Get<uint32>(ptr), output); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + return WireFormatLite::WriteFixed32NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> { + typedef uint64 Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + WireFormatLite::WriteFixed64NoTag(Get<uint64>(ptr), output); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + return WireFormatLite::WriteFixed64NoTagToArray(Get<Type>(ptr), buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_ENUM> + : PrimitiveTypeHelper<WireFormatLite::TYPE_INT32> {}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_SFIXED32> + : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> { + typedef int32 Type; +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_SFIXED64> + : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> { + typedef int64 Type; +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_FLOAT> + : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> { + typedef float Type; +}; +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_DOUBLE> + : PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> { + typedef double Type; +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> { + typedef string Type; + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + const Type& value = *static_cast<const Type*>(ptr); + output->WriteVarint32(value.size()); + output->WriteRawMaybeAliased(value.data(), value.size()); + } + static uint8* SerializeToArray(const void* ptr, uint8* buffer) { + const Type& value = *static_cast<const Type*>(ptr); + return io::CodedOutputStream::WriteStringWithSizeToArray(value, buffer); + } +}; + +template <> +struct PrimitiveTypeHelper<WireFormatLite::TYPE_BYTES> + : PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {}; + + +// We want to serialize to both CodedOutputStream and directly into byte arrays +// without duplicating the code. In fact we might want extra output channels in +// the future. +template <typename O, int type> +struct OutputHelper; + +template <int type, typename O> +void SerializeTo(const void* ptr, O* output) { + OutputHelper<O, type>::Serialize(ptr, output); +} + +template <typename O> +void WriteTagTo(uint32 tag, O* output) { + SerializeTo<WireFormatLite::TYPE_UINT32>(&tag, output); +} + +template <typename O> +void WriteLengthTo(uint32 length, O* output) { + SerializeTo<WireFormatLite::TYPE_UINT32>(&length, output); +} + +// Specialization for coded output stream +template <int type> +struct OutputHelper< ::google::protobuf::io::CodedOutputStream, type> { + static void Serialize(const void* ptr, + ::google::protobuf::io::CodedOutputStream* output) { + PrimitiveTypeHelper<type>::Serialize(ptr, output); + } +}; + +// Specialization for writing into a plain array +struct ArrayOutput { + uint8* ptr; + bool is_deterministic; +}; + +template <int type> +struct OutputHelper<ArrayOutput, type> { + static void Serialize(const void* ptr, ArrayOutput* output) { + output->ptr = PrimitiveTypeHelper<type>::SerializeToArray(ptr, output->ptr); + } +}; + +void SerializeMessageNoTable(const MessageLite* msg, + ::google::protobuf::io::CodedOutputStream* output) { + msg->SerializeWithCachedSizes(output); +} + +void SerializeMessageNoTable(const MessageLite* msg, ArrayOutput* output) { + output->ptr = msg->InternalSerializeWithCachedSizesToArray( + output->is_deterministic, output->ptr); +} + +// Helper to branch to fast path if possible +void SerializeMessageDispatch(const ::google::protobuf::MessageLite& msg, + const FieldMetadata* field_table, int num_fields, + int32 cached_size, + ::google::protobuf::io::CodedOutputStream* output) { + const uint8* base = reinterpret_cast<const uint8*>(&msg); + // Try the fast path + uint8* ptr = output->GetDirectBufferForNBytesAndAdvance(cached_size); + if (ptr) { + // We use virtual dispatch to enable dedicated generated code for the + // fast path. + msg.InternalSerializeWithCachedSizesToArray( + output->IsSerializationDeterministic(), ptr); + return; + } + SerializeInternal(base, field_table, num_fields, output); +} + +// Helper to branch to fast path if possible +void SerializeMessageDispatch(const ::google::protobuf::MessageLite& msg, + const FieldMetadata* field_table, int num_fields, + int32 cached_size, ArrayOutput* output) { + const uint8* base = reinterpret_cast<const uint8*>(&msg); + output->ptr = SerializeInternalToArray(base, field_table, num_fields, + output->is_deterministic, output->ptr); +} + +// Serializing messages is special as it's not a primitive type and needs an +// explicit overload for each output type. +template <typename O> +void SerializeMessageTo(const MessageLite* msg, const void* table_ptr, + O* output) { + const SerializationTable* table = + static_cast<const SerializationTable*>(table_ptr); + if (!table) { + // Proto1 + WriteLengthTo(msg->GetCachedSize(), output); + SerializeMessageNoTable(msg, output); + return; + } + const FieldMetadata* field_table = table->field_table; + const uint8* base = reinterpret_cast<const uint8*>(msg); + int cached_size = *reinterpret_cast<const int32*>(base + field_table->offset); + WriteLengthTo(cached_size, output); + int num_fields = table->num_fields - 1; + SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size, + output); +} + +// Almost the same as above only it doesn't output the length field. +template <typename O> +void SerializeGroupTo(const MessageLite* msg, const void* table_ptr, + O* output) { + const SerializationTable* table = + static_cast<const SerializationTable*>(table_ptr); + if (!table) { + // Proto1 + SerializeMessageNoTable(msg, output); + return; + } + const FieldMetadata* field_table = table->field_table; + const uint8* base = reinterpret_cast<const uint8*>(msg); + int cached_size = *reinterpret_cast<const int32*>(base + field_table->offset); + int num_fields = table->num_fields - 1; + SerializeMessageDispatch(*msg, field_table + 1, num_fields, cached_size, + output); +} + +template <int type> +struct SingularFieldHelper { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeTo<type>(field, output); + } +}; + +template <> +struct SingularFieldHelper<WireFormatLite::TYPE_STRING> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeTo<WireFormatLite::TYPE_STRING>(&Get<ArenaStringPtr>(field).Get(), + output); + } +}; + +template <> +struct SingularFieldHelper<WireFormatLite::TYPE_BYTES> + : SingularFieldHelper<WireFormatLite::TYPE_STRING> {}; + +template <> +struct SingularFieldHelper<WireFormatLite::TYPE_GROUP> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeGroupTo(Get<const MessageLite*>(field), + static_cast<const SerializationTable*>(md.ptr), output); + WriteTagTo(md.tag + 1, output); + } +}; + +template <> +struct SingularFieldHelper<WireFormatLite::TYPE_MESSAGE> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + WriteTagTo(md.tag, output); + SerializeMessageTo(Get<const MessageLite*>(field), + static_cast<const SerializationTable*>(md.ptr), output); + } +}; + +template <int type> +struct RepeatedFieldHelper { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + typedef typename PrimitiveTypeHelper<type>::Type T; + const RepeatedField<T>& array = Get<RepeatedField<T> >(field); + for (int i = 0; i < array.size(); i++) { + WriteTagTo(md.tag, output); + SerializeTo<type>(&array[i], output); + } + } +}; + +// We need to use a helper class to get access to the private members +class AccessorHelper { + public: + static int Size(const RepeatedPtrFieldBase& x) { return x.size(); } + static void const* Get(const RepeatedPtrFieldBase& x, int idx) { + return x.raw_data()[idx]; + } +}; + +template <> +struct RepeatedFieldHelper<WireFormatLite::TYPE_STRING> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + const internal::RepeatedPtrFieldBase& array = + Get<internal::RepeatedPtrFieldBase>(field); + for (int i = 0; i < AccessorHelper::Size(array); i++) { + WriteTagTo(md.tag, output); + SerializeTo<WireFormatLite::TYPE_STRING>(AccessorHelper::Get(array, i), + output); + } + } +}; + +template <> +struct RepeatedFieldHelper<WireFormatLite::TYPE_BYTES> + : RepeatedFieldHelper<WireFormatLite::TYPE_STRING> {}; + +template <> +struct RepeatedFieldHelper<WireFormatLite::TYPE_GROUP> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + const internal::RepeatedPtrFieldBase& array = + Get<internal::RepeatedPtrFieldBase>(field); + for (int i = 0; i < AccessorHelper::Size(array); i++) { + WriteTagTo(md.tag, output); + SerializeGroupTo( + static_cast<const MessageLite*>(AccessorHelper::Get(array, i)), + static_cast<const SerializationTable*>(md.ptr), output); + WriteTagTo(md.tag + 1, output); + } + } +}; + +template <> +struct RepeatedFieldHelper<WireFormatLite::TYPE_MESSAGE> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + const internal::RepeatedPtrFieldBase& array = + Get<internal::RepeatedPtrFieldBase>(field); + for (int i = 0; i < AccessorHelper::Size(array); i++) { + WriteTagTo(md.tag, output); + SerializeMessageTo( + static_cast<const MessageLite*>(AccessorHelper::Get(array, i)), md.ptr, + output); + } + } +}; + + +template <int type> +struct PackedFieldHelper { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + typedef typename PrimitiveTypeHelper<type>::Type T; + const RepeatedField<T>& array = Get<RepeatedField<T> >(field); + if (array.empty()) return; + WriteTagTo(md.tag, output); + int cached_size = + Get<int>(static_cast<const uint8*>(field) + sizeof(RepeatedField<T>)); + WriteLengthTo(cached_size, output); + for (int i = 0; i < array.size(); i++) { + SerializeTo<type>(&array[i], output); + } + } +}; + +template <> +struct PackedFieldHelper<WireFormatLite::TYPE_STRING> { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + GOOGLE_LOG(FATAL) << "Not implemented field number " << md.tag << " with type " + << md.type; + } +}; + +template <> +struct PackedFieldHelper<WireFormatLite::TYPE_BYTES> + : PackedFieldHelper<WireFormatLite::TYPE_STRING> {}; +template <> +struct PackedFieldHelper<WireFormatLite::TYPE_GROUP> + : PackedFieldHelper<WireFormatLite::TYPE_STRING> {}; +template <> +struct PackedFieldHelper<WireFormatLite::TYPE_MESSAGE> + : PackedFieldHelper<WireFormatLite::TYPE_STRING> {}; + +template <int type> +struct OneOfFieldHelper { + template <typename O> + static void Serialize(const void* field, const FieldMetadata& md, O* output) { + SingularFieldHelper<type>::Serialize(field, md, output); + } +}; + + +void SerializeNotImplemented(int field) { + GOOGLE_LOG(FATAL) << "Not implemented field number " << field; +} + +// When switching to c++11 we should make these constexpr functions +#define SERIALIZE_TABLE_OP(type, type_class) \ + ((type - 1) + static_cast<int>(type_class) * FieldMetadata::kNumTypes) + +int FieldMetadata::CalculateType(int type, + FieldMetadata::FieldTypeClass type_class) { + return SERIALIZE_TABLE_OP(type, type_class); +} + +template <int type> +bool IsNull(const void* ptr) { + return *static_cast<const typename PrimitiveTypeHelper<type>::Type*>(ptr) == + 0; +} + +template <> +bool IsNull<WireFormatLite::TYPE_STRING>(const void* ptr) { + return static_cast<const ArenaStringPtr*>(ptr)->Get().size() == 0; +} + +template <> +bool IsNull<WireFormatLite::TYPE_BYTES>(const void* ptr) { + return static_cast<const ArenaStringPtr*>(ptr)->Get().size() == 0; +} + +template <> +bool IsNull<WireFormatLite::TYPE_GROUP>(const void* ptr) { + return Get<const MessageLite*>(ptr) == NULL; +} + +template <> +bool IsNull<WireFormatLite::TYPE_MESSAGE>(const void* ptr) { + return Get<const MessageLite*>(ptr) == NULL; +} + + +#define SERIALIZERS_FOR_TYPE(type) \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kPresence): \ + if (!IsPresent(base, field_metadata.has_offset)) continue; \ + SingularFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break; \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kNoPresence): \ + if (IsNull<type>(ptr)) continue; \ + SingularFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break; \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kRepeated): \ + RepeatedFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break; \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kPacked): \ + PackedFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break; \ + case SERIALIZE_TABLE_OP(type, FieldMetadata::kOneOf): \ + if (!IsOneofPresent(base, field_metadata.has_offset, field_metadata.tag)) \ + continue; \ + OneOfFieldHelper<type>::Serialize(ptr, field_metadata, output); \ + break + +void SerializeInternal(const uint8* base, + const FieldMetadata* field_metadata_table, + int32 num_fields, + ::google::protobuf::io::CodedOutputStream* output) { + for (int i = 0; i < num_fields; i++) { + const FieldMetadata& field_metadata = field_metadata_table[i]; + const uint8* ptr = base + field_metadata.offset; + switch (field_metadata.type) { + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BOOL); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_STRING); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_GROUP); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_MESSAGE); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BYTES); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_ENUM); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); + + // Special cases + case FieldMetadata::kSpecial: + reinterpret_cast<SpecialSerializer>( + const_cast<void*>(field_metadata.ptr))( + base, field_metadata.offset, field_metadata.tag, + field_metadata.has_offset, output); + break; + default: + // __builtin_unreachable() + SerializeNotImplemented(field_metadata.type); + } + } +} + +uint8* SerializeInternalToArray(const uint8* base, + const FieldMetadata* field_metadata_table, + int32 num_fields, bool is_deterministic, + uint8* buffer) { + ArrayOutput array_output = {buffer, is_deterministic}; + ArrayOutput* output = &array_output; + for (int i = 0; i < num_fields; i++) { + const FieldMetadata& field_metadata = field_metadata_table[i]; + const uint8* ptr = base + field_metadata.offset; + switch (field_metadata.type) { + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_DOUBLE); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FLOAT); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_INT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_FIXED32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BOOL); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_STRING); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_GROUP); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_MESSAGE); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_BYTES); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_UINT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_ENUM); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); + SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); + // Special cases + case FieldMetadata::kSpecial: { + io::ArrayOutputStream array_stream(array_output.ptr, INT_MAX); + io::CodedOutputStream output(&array_stream); + output.SetSerializationDeterministic(is_deterministic); + reinterpret_cast<SpecialSerializer>( + const_cast<void*>(field_metadata.ptr))( + base, field_metadata.offset, field_metadata.tag, + field_metadata.has_offset, &output); + array_output.ptr += output.ByteCount(); + } break; + default: + // __builtin_unreachable() + SerializeNotImplemented(field_metadata.type); + } + } + return array_output.ptr; +} +#undef SERIALIZERS_FOR_TYPE + +void ExtensionSerializer(const uint8* ptr, uint32 offset, uint32 tag, + uint32 has_offset, + ::google::protobuf::io::CodedOutputStream* output) { + reinterpret_cast<const ExtensionSet*>(ptr + offset) + ->SerializeWithCachedSizes(tag, has_offset, output); +} + +void UnknownFieldSerializerLite(const uint8* ptr, uint32 offset, uint32 tag, + uint32 has_offset, + ::google::protobuf::io::CodedOutputStream* output) { + output->WriteString( + reinterpret_cast<const InternalMetadataWithArenaLite*>(ptr + offset) + ->unknown_fields()); +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index c16bd728..096a84cd 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -41,25 +41,22 @@ #include <assert.h> #include <climits> #include <string> +#include <vector> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/once.h> #include <google/protobuf/has_bits.h> - -#ifndef PROTOBUF_FINAL -#if LANG_CXX11 && !defined(__NVCC__) -#define PROTOBUF_FINAL final -#else -#define PROTOBUF_FINAL -#endif -#endif // !PROTOBUF_FINAL +#include <google/protobuf/map_entry_lite.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/wire_format_lite.h> namespace google { namespace protobuf { class Arena; + namespace io { class CodedInputStream; } namespace internal { @@ -106,80 +103,10 @@ namespace internal { reinterpret_cast<const char*>(16)) #endif -#define GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \ - static_cast< ::google::protobuf::uint32>( \ - reinterpret_cast<const char*>(&(ONEOF->FIELD)) \ - - reinterpret_cast<const char*>(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(); -// This type is used to define a global variable, without it's constructor -// and destructor run on start and end of the program lifetime. This circumvents -// the initial construction order fiasco, while keeping the address of the -// empty string a compile time constant. -template <typename T> -class ExplicitlyConstructed { - public: - void DefaultConstruct() { - new (&union_) T(); - init_ = true; - } - - bool IsInitialized() { return init_; } - void Shutdown() { - if (init_) { - init_ = false; - get_mutable()->~T(); - } - } - -#if LANG_CXX11 - constexpr -#endif - const T& - get() const { - return reinterpret_cast<const T&>(union_); - } - T* get_mutable() { return reinterpret_cast<T*>(&union_); } - - private: - // Prefer c++14 aligned_storage, but for compatibility this will do. - union AlignedUnion { - char space[sizeof(T)]; - int64 align_to_int64; - void* align_to_ptr; - } union_; - bool init_; // false by linker -}; - -// TODO(jieluo): Change to template. We have tried to use template, -// but it causes net/rpc/python:rpcutil_test fail (the empty string will -// init twice). It may related to swig. Change to template after we -// found the solution. - -// 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; -LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_; -LIBPROTOBUF_EXPORT void InitEmptyString(); - - -LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() { - return fixed_address_empty_string.get(); -} - -LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() { - ::google::protobuf::GoogleOnceInit(&empty_string_once_init_, &InitEmptyString); - return GetEmptyStringAlreadyInited(); -} - -LIBPROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const string& str); - // True if IsInitialized() is true for all elements of t. Type is expected // to be a RepeatedPtrField<some message type>. It's useful to have this @@ -195,32 +122,156 @@ template <class Type> bool AllAreInitialized(const Type& t) { 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. 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<int>(size); +struct LIBPROTOBUF_EXPORT FieldMetadata { + uint32 offset; // offset of this field in the struct + uint32 tag; // field * 8 + wire_type + // byte offset * 8 + bit_offset; + // if the high bit is set then this is the byte offset of the oneof_case + // for this field. + uint32 has_offset; + uint32 type; // the type of this field. + const void* ptr; // auxiliary data + + // From the serializer point of view each fundamental type can occur in + // 4 different ways. For simplicity we treat all combinations as a cartesion + // product although not all combinations are allowed. + enum FieldTypeClass { + kPresence, + kNoPresence, + kRepeated, + kPacked, + kOneOf, + kNumTypeClasses // must be last enum + }; + // C++ protobuf has 20 fundamental types, were we added Cord and StringPiece + // and also distinquish the same types if they have different wire format. + enum { + kCordType = 19, + kStringPieceType = 20, + kNumTypes = 20, + kSpecial = kNumTypes * kNumTypeClasses, + }; + + static int CalculateType(int fundamental_type, FieldTypeClass type_class); +}; + +inline bool IsPresent(const void* base, uint32 hasbit) { + const uint32* has_bits_array = static_cast<const uint32*>(base); + return has_bits_array[hasbit / 32] & (1u << (hasbit & 31)); +} + +inline bool IsOneofPresent(const void* base, uint32 offset, uint32 tag) { + const uint32* oneof = + reinterpret_cast<const uint32*>(static_cast<const uint8*>(base) + offset); + return *oneof == tag >> 3; +} + +typedef void (*SpecialSerializer)(const uint8* base, uint32 offset, uint32 tag, + uint32 has_offset, + ::google::protobuf::io::CodedOutputStream* output); + +LIBPROTOBUF_EXPORT void ExtensionSerializer(const uint8* base, uint32 offset, uint32 tag, + uint32 has_offset, + ::google::protobuf::io::CodedOutputStream* output); +LIBPROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8* base, uint32 offset, uint32 tag, + uint32 has_offset, + ::google::protobuf::io::CodedOutputStream* output); + +struct SerializationTable { + int num_fields; + const FieldMetadata* field_table; +}; + +LIBPROTOBUF_EXPORT void SerializeInternal(const uint8* base, const FieldMetadata* table, + int num_fields, ::google::protobuf::io::CodedOutputStream* output); + +inline void TableSerialize(const ::google::protobuf::MessageLite& msg, + const SerializationTable* table, + ::google::protobuf::io::CodedOutputStream* output) { + const FieldMetadata* field_table = table->field_table; + int num_fields = table->num_fields - 1; + const uint8* base = reinterpret_cast<const uint8*>(&msg); + // TODO(gerbens) This skips the first test if we could use the fast + // array serialization path, we should make this + // int cached_size = + // *reinterpret_cast<const int32*>(base + field_table->offset); + // SerializeWithCachedSize(msg, field_table + 1, num_fields, cached_size, ...) + // But we keep conformance with the old way for now. + SerializeInternal(base, field_table + 1, num_fields, output); } -// 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<size_t>(INT_MAX)); - return static_cast<int>(size); +uint8* SerializeInternalToArray(const uint8* base, const FieldMetadata* table, + int num_fields, bool is_deterministic, + uint8* buffer); + +inline uint8* TableSerializeToArray(const ::google::protobuf::MessageLite& msg, + const SerializationTable* table, + bool is_deterministic, uint8* buffer) { + const uint8* base = reinterpret_cast<const uint8*>(&msg); + const FieldMetadata* field_table = table->field_table + 1; + int num_fields = table->num_fields - 1; + return SerializeInternalToArray(base, field_table, num_fields, + is_deterministic, buffer); } -// 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 -// 64-bit platforms because it avoids making the compiler emit a sign extending -// instruction, which we don't want and don't want to pay for. -inline size_t FromIntSize(int size) { - // Convert to unsigned before widening so sign extension is not necessary. - return static_cast<unsigned int>(size); +template <typename T> +struct CompareHelper { + bool operator()(const T& a, const T& b) { return a < b; } +}; + +template <> +struct CompareHelper<ArenaStringPtr> { + bool operator()(const ArenaStringPtr& a, const ArenaStringPtr& b) { + return a.Get() < b.Get(); + } +}; + +struct CompareMapKey { + template <typename T> + bool operator()(const MapEntryHelper<T>& a, const MapEntryHelper<T>& b) { + return Compare(a.key_, b.key_); + } + template <typename T> + bool Compare(const T& a, const T& b) { + return CompareHelper<T>()(a, b); + } +}; + +template <typename MapFieldType, const SerializationTable* table> +void MapFieldSerializer(const uint8* base, uint32 offset, uint32 tag, + uint32 has_offset, + ::google::protobuf::io::CodedOutputStream* output) { + typedef MapEntryHelper<typename MapFieldType::EntryTypeTrait> Entry; + typedef typename MapFieldType::MapType::const_iterator Iter; + + const MapFieldType& map_field = + *reinterpret_cast<const MapFieldType*>(base + offset); + const SerializationTable* t = + table + + has_offset; // has_offset is overloaded for maps to mean table offset + if (!output->IsSerializationDeterministic()) { + for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end(); + ++it) { + Entry map_entry(*it); + output->WriteVarint32(tag); + output->WriteVarint32(map_entry._cached_size_); + SerializeInternal(reinterpret_cast<const uint8*>(&map_entry), + t->field_table, t->num_fields, output); + } + } else { + std::vector<Entry> v; + for (Iter it = map_field.GetMap().begin(); it != map_field.GetMap().end(); + ++it) { + v.push_back(Entry(*it)); + } + std::sort(v.begin(), v.end(), CompareMapKey()); + for (int i = 0; i < v.size(); i++) { + output->WriteVarint32(tag); + output->WriteVarint32(v[i]._cached_size_); + SerializeInternal(reinterpret_cast<const uint8*>(&v[i]), t->field_table, + t->num_fields, output); + } + } } } // namespace internal diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index df4250e5..17eb0ffa 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -197,17 +197,7 @@ void CodedInputStream::PrintTotalBytesLimitError() { "in google/protobuf/io/coded_stream.h."; } -bool CodedInputStream::Skip(int count) { - if (count < 0) return false; // security: count is often user-supplied - - const int original_buffer_size = BufferSize(); - - if (count <= original_buffer_size) { - // Just skipping within the current buffer. Easy. - Advance(count); - return true; - } - +bool CodedInputStream::SkipFallback(int count, int original_buffer_size) { if (buffer_size_after_limit_ > 0) { // We hit a limit inside this buffer. Advance to the limit and fail. Advance(original_buffer_size); diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index 9f1cf88c..6d2599fb 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -184,7 +184,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Skips a number of bytes. Returns false if an underlying read error // occurs. - bool Skip(int count); + inline bool Skip(int count); // Sets *data to point directly at the unread part of the CodedInputStream's // underlying buffer, and *size to the size of that buffer, but does not @@ -261,7 +261,10 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Always inline because this is only called in one place per parse loop // but it is called for every iteration of said loop, so it should be fast. // GCC doesn't want to inline this by default. - GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTag(); + GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTag() { + return last_tag_ = ReadTagNoLastTag(); + } + GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTagNoLastTag(); @@ -274,7 +277,12 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // because that can arise in several ways, and for best performance we want // to avoid an extra "is tag == 0?" check here.) GOOGLE_ATTRIBUTE_ALWAYS_INLINE std::pair<uint32, bool> ReadTagWithCutoff( - uint32 cutoff); + uint32 cutoff) { + std::pair<uint32, bool> result = ReadTagWithCutoffNoLastTag(cutoff); + last_tag_ = result.first; + return result; + } + GOOGLE_ATTRIBUTE_ALWAYS_INLINE std::pair<uint32, bool> ReadTagWithCutoffNoLastTag( uint32 cutoff); @@ -316,6 +324,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // tag to make sure it had the right number, so it calls LastTagWas() on // return from the embedded parser to check. bool LastTagWas(uint32 expected); + void SetLastTag(uint32 tag) { last_tag_ = tag; } // When parsing message (but NOT a group), this method must be called // immediately after MergeFromCodedStream() returns (if it returns true) @@ -584,6 +593,9 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Private member functions. + // Fallback when Skip() goes past the end of the current buffer. + bool SkipFallback(int count, int original_buffer_size); + // Advance the buffer by a given number of bytes. void Advance(int amount); @@ -621,12 +633,6 @@ class LIBPROTOBUF_EXPORT CodedInputStream { bool ReadLittleEndian32Fallback(uint32* value); bool ReadLittleEndian64Fallback(uint64* value); - template<bool update_last_tag> - GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTagImplementation(); - template<bool update_last_tag> - GOOGLE_ATTRIBUTE_ALWAYS_INLINE - std::pair<uint32, bool> ReadTagWithCutoffImplementation(uint32 cutoff); - // Fallback/slow methods for reading tags. These do not update last_tag_, // but will set legitimate_message_end_ if we are at the end of the input // stream. @@ -1018,48 +1024,21 @@ inline bool CodedInputStream::ReadLittleEndian64(uint64* value) { #endif } -inline uint32 CodedInputStream::ReadTag() { - return ReadTagImplementation<true>(); -} - inline uint32 CodedInputStream::ReadTagNoLastTag() { - return ReadTagImplementation<false>(); -} - -template<bool update_last_tag> -inline uint32 CodedInputStream::ReadTagImplementation() { uint32 v = 0; if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { v = *buffer_; if (v < 0x80) { - if (update_last_tag) { - last_tag_ = v; - } Advance(1); return v; } } v = ReadTagFallback(v); - if (update_last_tag) { - last_tag_ = v; - } return v; } -inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff( - uint32 cutoff) { - return ReadTagWithCutoffImplementation<true>(cutoff); -} - inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoffNoLastTag( uint32 cutoff) { - return ReadTagWithCutoffImplementation<false>(cutoff); -} - -template<bool update_last_tag> -inline std::pair<uint32, bool> -CodedInputStream::ReadTagWithCutoffImplementation( - uint32 cutoff) { // In performance-sensitive code we can expect cutoff to be a compile-time // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at // compile time. @@ -1072,9 +1051,6 @@ CodedInputStream::ReadTagWithCutoffImplementation( if (static_cast<int8>(buffer_[0]) > 0) { const uint32 kMax1ByteVarint = 0x7f; uint32 tag = buffer_[0]; - if (update_last_tag) { - last_tag_ = tag; - } Advance(1); return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff); } @@ -1086,9 +1062,6 @@ CodedInputStream::ReadTagWithCutoffImplementation( GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) { const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f; uint32 tag = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80); - if (update_last_tag) { - last_tag_ = tag; - } Advance(2); // It might make sense to test for tag == 0 now, but it is so rare that // that we don't bother. A varint-encoded 0 should be one byte unless @@ -1102,9 +1075,6 @@ CodedInputStream::ReadTagWithCutoffImplementation( } // Slow path const uint32 tag = ReadTagFallback(first_byte_or_zero); - if (update_last_tag) { - last_tag_ = tag; - } return std::make_pair(tag, static_cast<uint32>(tag - 1) < cutoff); } @@ -1430,6 +1400,20 @@ inline bool CodedInputStream::IsFlat() const { return input_ == NULL; } +inline bool CodedInputStream::Skip(int count) { + if (count < 0) return false; // security: count is often user-supplied + + const int original_buffer_size = BufferSize(); + + if (count <= original_buffer_size) { + // Just skipping within the current buffer. Easy. + Advance(count); + return true; + } + + return SkipFallback(count, original_buffer_size); +} + } // namespace io } // namespace protobuf diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc index 99e895f5..8493268d 100644 --- a/src/google/protobuf/io/printer.cc +++ b/src/google/protobuf/io/printer.cc @@ -111,6 +111,7 @@ void Printer::Print(const std::map<string, string>& variables, int size = strlen(text); int pos = 0; // The number of bytes we've written so far. substitutions_.clear(); + line_start_variables_.clear(); for (int i = 0; i < size; i++) { if (text[i] == '\n') { @@ -122,6 +123,7 @@ void Printer::Print(const std::map<string, string>& variables, // Setting this true will cause the next WriteRaw() to insert an indent // first. at_start_of_line_ = true; + line_start_variables_.clear(); } else if (text[i] == variable_delimiter_) { // Saw the start of a variable name. @@ -148,12 +150,15 @@ void Printer::Print(const std::map<string, string>& variables, if (iter == variables.end()) { GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname; } else { - size_t begin = offset_; + if (at_start_of_line_ && iter->second.empty()) { + line_start_variables_.push_back(varname); + } WriteRaw(iter->second.data(), iter->second.size()); std::pair<std::map<string, std::pair<size_t, size_t> >::iterator, bool> - inserted = substitutions_.insert( - std::make_pair(varname, std::make_pair(begin, offset_))); + inserted = substitutions_.insert(std::make_pair( + varname, + std::make_pair(offset_ - iter->second.size(), offset_))); if (!inserted.second) { // This variable was used multiple times. Make its span have // negative length so we can detect it if it gets used in an @@ -319,10 +324,29 @@ void Printer::WriteRaw(const char* data, int size) { if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) { // Insert an indent. at_start_of_line_ = false; - WriteRaw(indent_.data(), indent_.size()); + CopyToBuffer(indent_.data(), indent_.size()); if (failed_) return; + // Fix up empty variables (e.g., "{") that should be annotated as + // coming after the indent. + for (std::vector<string>::iterator i = line_start_variables_.begin(); + i != line_start_variables_.end(); ++i) { + substitutions_[*i].first += indent_.size(); + substitutions_[*i].second += indent_.size(); + } } + // If we're going to write any data, clear line_start_variables_, since + // we've either updated them in the block above or they no longer refer to + // the current line. + line_start_variables_.clear(); + + CopyToBuffer(data, size); +} + +void Printer::CopyToBuffer(const char* data, int size) { + if (failed_) return; + if (size == 0) return; + while (size > buffer_size_) { // Data exceeds space in the buffer. Copy what we can and request a // new buffer. diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h index e666445b..d11745ce 100644 --- a/src/google/protobuf/io/printer.h +++ b/src/google/protobuf/io/printer.h @@ -157,7 +157,7 @@ class AnnotationProtoCollector : public AnnotationCollector { // vars["function"] = "call"; // vars["mark"] = ""; // printer.Print(vars, "$function$($foo$,$foo$)$mark$"); -// printer.Annotate("function", "rmark", call_); +// printer.Annotate("function", "mark", call_); // // This code associates the span covering "call(bar,bar)" in the output with the // call_ descriptor. @@ -311,6 +311,9 @@ class LIBPROTOBUF_EXPORT Printer { void Annotate(const char* begin_varname, const char* end_varname, const string& file_path, const std::vector<int>& path); + // Copy size worth of bytes from data to buffer_. + void CopyToBuffer(const char* data, int size); + const char variable_delimiter_; ZeroCopyOutputStream* const output_; @@ -334,6 +337,11 @@ class LIBPROTOBUF_EXPORT Printer { // length of the substituted string). std::map<string, std::pair<size_t, size_t> > substitutions_; + // Keeps track of the keys in substitutions_ that need to be updated when + // indents are inserted. These are keys that refer to the beginning of the + // current line. + std::vector<string> line_start_variables_; + // Returns true and sets range to the substitution range in the output for // varname if varname was used once in the last call to Print. If varname // was not used, or if it was used multiple times, returns false (and diff --git a/src/google/protobuf/io/printer_unittest.cc b/src/google/protobuf/io/printer_unittest.cc index 0435228a..d0a0ebee 100644 --- a/src/google/protobuf/io/printer_unittest.cc +++ b/src/google/protobuf/io/printer_unittest.cc @@ -360,6 +360,83 @@ TEST(Printer, AnnotateDespiteUnrelatedMultipleUses) { EXPECT_EQ(7, bar->end()); } +TEST(Printer, AnnotateIndent) { + char buffer[8192]; + ArrayOutputStream output(buffer, sizeof(buffer)); + GeneratedCodeInfo info; + AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info); + { + Printer printer(&output, '$', &info_collector); + printer.Print("0\n"); + printer.Indent(); + printer.Print("$foo$", "foo", "4"); + std::vector<int> path; + path.push_back(44); + MockDescriptor descriptor("path", path); + printer.Annotate("foo", &descriptor); + printer.Print(",\n"); + printer.Print("$bar$", "bar", "9"); + path[0] = 99; + MockDescriptor descriptor_two("path", path); + printer.Annotate("bar", &descriptor_two); + printer.Print("\n${$$D$$}$\n", "{", "", "}", "", "D", "d"); + path[0] = 1313; + MockDescriptor descriptor_three("path", path); + printer.Annotate("{", "}", &descriptor_three); + printer.Outdent(); + printer.Print("\n"); + } + buffer[output.ByteCount()] = '\0'; + EXPECT_STREQ("0\n 4,\n 9\n d\n\n", buffer); + ASSERT_EQ(3, info.annotation_size()); + const GeneratedCodeInfo::Annotation* foo = &info.annotation(0); + ASSERT_EQ(1, foo->path_size()); + EXPECT_EQ(44, foo->path(0)); + EXPECT_EQ("path", foo->source_file()); + EXPECT_EQ(4, foo->begin()); + EXPECT_EQ(5, foo->end()); + const GeneratedCodeInfo::Annotation* bar = &info.annotation(1); + ASSERT_EQ(1, bar->path_size()); + EXPECT_EQ(99, bar->path(0)); + EXPECT_EQ("path", bar->source_file()); + EXPECT_EQ(9, bar->begin()); + EXPECT_EQ(10, bar->end()); + const GeneratedCodeInfo::Annotation* braces = &info.annotation(2); + ASSERT_EQ(1, braces->path_size()); + EXPECT_EQ(1313, braces->path(0)); + EXPECT_EQ("path", braces->source_file()); + EXPECT_EQ(13, braces->begin()); + EXPECT_EQ(14, braces->end()); +} + +TEST(Printer, AnnotateIndentNewline) { + char buffer[8192]; + ArrayOutputStream output(buffer, sizeof(buffer)); + GeneratedCodeInfo info; + AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info); + { + Printer printer(&output, '$', &info_collector); + printer.Indent(); + printer.Print("$A$$N$$B$C\n", "A", "", "N", "\nz", "B", ""); + std::vector<int> path; + path.push_back(0); + MockDescriptor descriptor("path", path); + printer.Annotate("A", "B", &descriptor); + printer.Outdent(); + printer.Print("\n"); + } + buffer[output.ByteCount()] = '\0'; + EXPECT_STREQ("\nz C\n\n", buffer); + ASSERT_EQ(1, info.annotation_size()); + const GeneratedCodeInfo::Annotation* ab = &info.annotation(0); + ASSERT_EQ(1, ab->path_size()); + EXPECT_EQ(0, ab->path(0)); + EXPECT_EQ("path", ab->source_file()); + EXPECT_EQ(0, ab->begin()); + EXPECT_EQ(4, ab->end()); +} + + TEST(Printer, Indenting) { char buffer[8192]; diff --git a/src/google/protobuf/io/zero_copy_stream.cc b/src/google/protobuf/io/zero_copy_stream.cc index 186de001..f81555e5 100644 --- a/src/google/protobuf/io/zero_copy_stream.cc +++ b/src/google/protobuf/io/zero_copy_stream.cc @@ -41,9 +41,6 @@ namespace google { namespace protobuf { namespace io { -ZeroCopyInputStream::~ZeroCopyInputStream() {} -ZeroCopyOutputStream::~ZeroCopyOutputStream() {} - bool ZeroCopyOutputStream::WriteAliasedRaw(const void* /* data */, int /* size */) { diff --git a/src/google/protobuf/io/zero_copy_stream.h b/src/google/protobuf/io/zero_copy_stream.h index 52650fc6..62ace7ae 100644 --- a/src/google/protobuf/io/zero_copy_stream.h +++ b/src/google/protobuf/io/zero_copy_stream.h @@ -123,8 +123,8 @@ class ZeroCopyOutputStream; // copying. class LIBPROTOBUF_EXPORT ZeroCopyInputStream { public: - inline ZeroCopyInputStream() {} - virtual ~ZeroCopyInputStream(); + ZeroCopyInputStream() {} + virtual ~ZeroCopyInputStream() {} // Obtains a chunk of data from the stream. // @@ -180,8 +180,8 @@ class LIBPROTOBUF_EXPORT ZeroCopyInputStream { // copying. class LIBPROTOBUF_EXPORT ZeroCopyOutputStream { public: - inline ZeroCopyOutputStream() {} - virtual ~ZeroCopyOutputStream(); + ZeroCopyOutputStream() {} + virtual ~ZeroCopyOutputStream() {} // Obtains a buffer into which data can be written. Any data written // into this buffer will eventually (maybe instantly, maybe later on) diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc index c7372ac2..81fb5033 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl.cc @@ -56,6 +56,9 @@ namespace io { // Win32 lseek is broken: If invoked on a non-seekable file descriptor, its // return value is undefined. We re-define it to always produce an error. #define lseek(fd, offset, origin) ((off_t)-1) +#endif + +#ifdef _MSC_VER // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. using google::protobuf::internal::win32::access; @@ -86,8 +89,6 @@ FileInputStream::FileInputStream(int file_descriptor, int block_size) impl_(©ing_input_, block_size) { } -FileInputStream::~FileInputStream() {} - bool FileInputStream::Close() { return copying_input_.Close(); } @@ -278,8 +279,6 @@ bool FileOutputStream::CopyingFileOutputStream::Write( IstreamInputStream::IstreamInputStream(std::istream* input, int block_size) : copying_input_(input), impl_(©ing_input_, block_size) {} -IstreamInputStream::~IstreamInputStream() {} - bool IstreamInputStream::Next(const void** data, int* size) { return impl_.Next(data, size); } @@ -353,9 +352,6 @@ ConcatenatingInputStream::ConcatenatingInputStream( : streams_(streams), stream_count_(count), bytes_retired_(0) { } -ConcatenatingInputStream::~ConcatenatingInputStream() { -} - bool ConcatenatingInputStream::Next(const void** data, int* size) { while (stream_count_ > 0) { if (streams_[0]->Next(data, size)) return true; diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h index 3365790e..ea978bfb 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.h +++ b/src/google/protobuf/io/zero_copy_stream_impl.h @@ -67,7 +67,6 @@ class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { // should be read and returned with each call to Next(). Otherwise, // a reasonable default is used. explicit FileInputStream(int file_descriptor, int block_size = -1); - ~FileInputStream(); // Flushes any buffers and closes the underlying file. Returns false if // an error occurs during the process; use GetErrno() to examine the error. @@ -219,7 +218,6 @@ class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream { // should be read and returned with each call to Next(). Otherwise, // a reasonable default is used. explicit IstreamInputStream(std::istream* stream, int block_size = -1); - ~IstreamInputStream(); // implements ZeroCopyInputStream ---------------------------------- bool Next(const void** data, int* size); @@ -306,7 +304,6 @@ class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream { // All streams passed in as well as the array itself must remain valid // until the ConcatenatingInputStream is destroyed. ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count); - ~ConcatenatingInputStream(); // implements ZeroCopyInputStream ---------------------------------- bool Next(const void** data, int* size); diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc index e6ca88c2..60c71c80 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -64,9 +64,6 @@ ArrayInputStream::ArrayInputStream(const void* data, int size, last_returned_size_(0) { } -ArrayInputStream::~ArrayInputStream() { -} - bool ArrayInputStream::Next(const void** data, int* size) { if (position_ < size_) { last_returned_size_ = std::min(block_size_, size_ - position_); @@ -117,9 +114,6 @@ ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size) last_returned_size_(0) { } -ArrayOutputStream::~ArrayOutputStream() { -} - bool ArrayOutputStream::Next(void** data, int* size) { if (position_ < size_) { last_returned_size_ = std::min(block_size_, size_ - position_); @@ -153,9 +147,6 @@ StringOutputStream::StringOutputStream(string* target) : target_(target) { } -StringOutputStream::~StringOutputStream() { -} - bool StringOutputStream::Next(void** data, int* size) { GOOGLE_CHECK(target_ != NULL); int old_size = target_->size(); @@ -212,9 +203,6 @@ LazyStringOutputStream::LazyStringOutputStream( string_is_set_(false) { } -LazyStringOutputStream::~LazyStringOutputStream() { -} - bool LazyStringOutputStream::Next(void** data, int* size) { if (!string_is_set_) { SetString(callback_->Run()); @@ -229,8 +217,6 @@ int64 LazyStringOutputStream::ByteCount() const { // =================================================================== -CopyingInputStream::~CopyingInputStream() {} - int CopyingInputStream::Skip(int count) { char junk[4096]; int skipped = 0; @@ -350,8 +336,6 @@ void CopyingInputStreamAdaptor::FreeBuffer() { // =================================================================== -CopyingOutputStream::~CopyingOutputStream() {} - CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor( CopyingOutputStream* copying_stream, int block_size) : copying_stream_(copying_stream), diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h index 6db1d695..a7bbc625 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -73,7 +73,6 @@ class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream { // useful for testing; in production you would probably never want to set // it. ArrayInputStream(const void* data, int size, int block_size = -1); - ~ArrayInputStream(); // implements ZeroCopyInputStream ---------------------------------- bool Next(const void** data, int* size); @@ -107,7 +106,6 @@ class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream { // useful for testing; in production you would probably never want to set // it. ArrayOutputStream(void* data, int size, int block_size = -1); - ~ArrayOutputStream(); // implements ZeroCopyOutputStream --------------------------------- bool Next(void** data, int* size); @@ -141,7 +139,6 @@ class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { // the first call to Next() will return at least n bytes of buffer // space. explicit StringOutputStream(string* target); - ~StringOutputStream(); // implements ZeroCopyOutputStream --------------------------------- bool Next(void** data, int* size); @@ -167,7 +164,6 @@ class LIBPROTOBUF_EXPORT LazyStringOutputStream : public StringOutputStream { // Callback should be permanent (non-self-deleting). Ownership is transferred // to the LazyStringOutputStream. explicit LazyStringOutputStream(ResultCallback<string*>* callback); - ~LazyStringOutputStream(); // implements ZeroCopyOutputStream, overriding StringOutputStream ----------- bool Next(void** data, int* size); @@ -199,7 +195,7 @@ class LIBPROTOBUF_EXPORT LazyStringOutputStream : public StringOutputStream { // in large blocks. class LIBPROTOBUF_EXPORT CopyingInputStream { public: - virtual ~CopyingInputStream(); + virtual ~CopyingInputStream() {} // Reads up to "size" bytes into the given buffer. Returns the number of // bytes read. Read() waits until at least one byte is available, or @@ -293,7 +289,7 @@ class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream // in large blocks. class LIBPROTOBUF_EXPORT CopyingOutputStream { public: - virtual ~CopyingOutputStream(); + virtual ~CopyingOutputStream() {} // Writes "size" bytes from the given buffer to the output. Returns true // if successful, false on a write error. diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc index f3754087..2bca6a90 100644 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -83,6 +83,9 @@ namespace { #ifdef _WIN32 #define pipe(fds) _pipe(fds, 4096, O_BINARY) +#endif + +#ifdef _MSC_VER // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. using google::protobuf::internal::win32::access; diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc index 2f5268af..6cf16629 100644 --- a/src/google/protobuf/lite_unittest.cc +++ b/src/google/protobuf/lite_unittest.cc @@ -48,6 +48,8 @@ #include <google/protobuf/stubs/strutil.h> +using std::string; + namespace { // Helper methods to test parsing merge behavior. void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) { @@ -71,7 +73,7 @@ void SetAllTypesInEmptyMessageUnknownFields( protobuf_unittest::TestAllTypesLite message; google::protobuf::TestUtilLite::ExpectClear(message); google::protobuf::TestUtilLite::SetAllFields(&message); - std::string data = message.SerializeAsString(); + string data = message.SerializeAsString(); empty_message->ParseFromString(data); } @@ -83,14 +85,14 @@ void SetSomeTypesInEmptyMessageUnknownFields( message.set_optional_int64(102); message.set_optional_uint32(103); message.set_optional_uint64(104); - std::string data = message.SerializeAsString(); + string data = message.SerializeAsString(); empty_message->ParseFromString(data); } } // namespace TEST(Lite, AllLite1) { - std::string data; + string data; { protobuf_unittest::TestAllTypesLite message, message2, message3; @@ -110,13 +112,13 @@ TEST(Lite, AllLite1) { } TEST(Lite, AllLite2) { - std::string data; + string data; { protobuf_unittest::TestAllExtensionsLite message, message2, message3; google::protobuf::TestUtilLite::ExpectExtensionsClear(message); google::protobuf::TestUtilLite::SetAllExtensions(&message); message2.CopyFrom(message); - std::string extensions_data = message.SerializeAsString(); + string extensions_data = message.SerializeAsString(); message3.ParseFromString(extensions_data); google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message); google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2); @@ -129,7 +131,7 @@ TEST(Lite, AllLite2) { } TEST(Lite, AllLite3) { - std::string data, packed_data; + string data, packed_data; { protobuf_unittest::TestPackedTypesLite message, message2, message3; @@ -152,7 +154,7 @@ TEST(Lite, AllLite3) { google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); google::protobuf::TestUtilLite::SetPackedExtensions(&message); message2.CopyFrom(message); - std::string packed_extensions_data = message.SerializeAsString(); + string packed_extensions_data = message.SerializeAsString(); EXPECT_EQ(packed_extensions_data, packed_data); message3.ParseFromString(packed_extensions_data); google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message); @@ -166,7 +168,7 @@ TEST(Lite, AllLite3) { } TEST(Lite, AllLite5) { - std::string data; + string data; { // Test that if an optional or required message/group field appears multiple @@ -200,7 +202,7 @@ TEST(Lite, AllLite5) { #undef ASSIGN_REPEATED_GROUP - std::string buffer; + string buffer; generator.SerializeToString(&buffer); google::protobuf::unittest::TestParsingMergeLite parsing_merge; parsing_merge.ParseFromString(buffer); @@ -223,7 +225,7 @@ TEST(Lite, AllLite5) { } TEST(Lite, AllLite6) { - std::string data; + string data; // Test unknown fields support for lite messages. { @@ -244,7 +246,7 @@ TEST(Lite, AllLite6) { } TEST(Lite, AllLite7) { - std::string data; + string data; { protobuf_unittest::TestAllExtensionsLite message, message2; @@ -264,7 +266,7 @@ TEST(Lite, AllLite7) { } TEST(Lite, AllLite8) { - std::string data; + string data; { protobuf_unittest::TestPackedTypesLite message, message2; @@ -284,7 +286,7 @@ TEST(Lite, AllLite8) { } TEST(Lite, AllLite9) { - std::string data; + string data; { protobuf_unittest::TestPackedExtensionsLite message, message2; @@ -304,7 +306,7 @@ TEST(Lite, AllLite9) { } TEST(Lite, AllLite10) { - std::string data; + string data; { // Test Unknown fields swap @@ -312,7 +314,7 @@ TEST(Lite, AllLite10) { SetAllTypesInEmptyMessageUnknownFields(&empty_message); SetSomeTypesInEmptyMessageUnknownFields(&empty_message2); data = empty_message.SerializeAsString(); - std::string data2 = empty_message2.SerializeAsString(); + string data2 = empty_message2.SerializeAsString(); empty_message.Swap(&empty_message2); EXPECT_EQ(data, empty_message2.SerializeAsString()); EXPECT_EQ(data2, empty_message.SerializeAsString()); @@ -320,7 +322,7 @@ TEST(Lite, AllLite10) { } TEST(Lite, AllLite11) { - std::string data; + string data; { // Test unknown fields swap with self @@ -333,7 +335,7 @@ TEST(Lite, AllLite11) { } TEST(Lite, AllLite12) { - std::string data; + string data; { // Test MergeFrom with unknown fields @@ -363,12 +365,12 @@ TEST(Lite, AllLite12) { } TEST(Lite, AllLite13) { - std::string data; + string data; { // Test unknown enum value protobuf_unittest::TestAllTypesLite message; - std::string buffer; + string buffer; { google::protobuf::io::StringOutputStream output_stream(&buffer); google::protobuf::io::CodedOutputStream coded_output(&output_stream); @@ -388,7 +390,7 @@ TEST(Lite, AllLite13) { } TEST(Lite, AllLite14) { - std::string data; + string data; { // Test Clear with unknown fields @@ -402,7 +404,7 @@ TEST(Lite, AllLite14) { // Tests for map lite ============================================= TEST(Lite, AllLite15) { - std::string data; + string data; { // Accessors @@ -417,7 +419,7 @@ TEST(Lite, AllLite15) { } TEST(Lite, AllLite16) { - std::string data; + string data; { // SetMapFieldsInitialized @@ -429,7 +431,7 @@ TEST(Lite, AllLite16) { } TEST(Lite, AllLite17) { - std::string data; + string data; { // Clear @@ -442,7 +444,7 @@ TEST(Lite, AllLite17) { } TEST(Lite, AllLite18) { - std::string data; + string data; { // ClearMessageMap @@ -455,7 +457,7 @@ TEST(Lite, AllLite18) { } TEST(Lite, AllLite19) { - std::string data; + string data; { // CopyFrom @@ -472,7 +474,7 @@ TEST(Lite, AllLite19) { } TEST(Lite, AllLite20) { - std::string data; + string data; { // CopyFromMessageMap @@ -490,7 +492,7 @@ TEST(Lite, AllLite20) { } TEST(Lite, AllLite21) { - std::string data; + string data; { // SwapWithEmpty @@ -507,7 +509,7 @@ TEST(Lite, AllLite21) { } TEST(Lite, AllLite22) { - std::string data; + string data; { // SwapWithSelf @@ -522,7 +524,7 @@ TEST(Lite, AllLite22) { } TEST(Lite, AllLite23) { - std::string data; + string data; { // SwapWithOther @@ -539,7 +541,7 @@ TEST(Lite, AllLite23) { } TEST(Lite, AllLite24) { - std::string data; + string data; { // CopyConstructor @@ -552,7 +554,7 @@ TEST(Lite, AllLite24) { } TEST(Lite, AllLite25) { - std::string data; + string data; { // CopyAssignmentOperator @@ -570,7 +572,7 @@ TEST(Lite, AllLite25) { } TEST(Lite, AllLite26) { - std::string data; + string data; { // NonEmptyMergeFrom @@ -592,7 +594,7 @@ TEST(Lite, AllLite26) { } TEST(Lite, AllLite27) { - std::string data; + string data; { // MergeFromMessageMap @@ -610,12 +612,12 @@ TEST(Lite, AllLite27) { } TEST(Lite, AllLite28) { - std::string data; + string data; { // Test the generated SerializeWithCachedSizesToArray() protobuf_unittest::TestMapLite message1, message2; - std::string data; + string data; google::protobuf::MapLiteTestUtil::SetMapFields(&message1); int size = message1.ByteSize(); data.resize(size); @@ -628,14 +630,14 @@ TEST(Lite, AllLite28) { } TEST(Lite, AllLite29) { - std::string data; + string data; { // Test the generated SerializeWithCachedSizes() protobuf_unittest::TestMapLite message1, message2; google::protobuf::MapLiteTestUtil::SetMapFields(&message1); int size = message1.ByteSize(); - std::string data; + string data; data.resize(size); { // Allow the output stream to buffer only one byte at a time. @@ -653,7 +655,7 @@ TEST(Lite, AllLite29) { TEST(Lite, AllLite32) { - std::string data; + string data; { // Proto2UnknownEnum @@ -662,7 +664,7 @@ TEST(Lite, AllLite32) { protobuf_unittest::E_PROTO2_MAP_ENUM_FOO_LITE; (*from.mutable_unknown_map_field())[0] = protobuf_unittest::E_PROTO2_MAP_ENUM_EXTRA_LITE; - std::string data; + string data; from.SerializeToString(&data); protobuf_unittest::TestEnumMapLite to; @@ -687,12 +689,12 @@ TEST(Lite, AllLite32) { } TEST(Lite, AllLite33) { - std::string data; + string data; { // StandardWireFormat protobuf_unittest::TestMapLite message; - std::string data = "\x0A\x04\x08\x01\x10\x01"; + string data = "\x0A\x04\x08\x01\x10\x01"; EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); @@ -701,14 +703,14 @@ TEST(Lite, AllLite33) { } TEST(Lite, AllLite34) { - std::string data; + string data; { // UnorderedWireFormat protobuf_unittest::TestMapLite message; // put value before key in wire format - std::string data = "\x0A\x04\x10\x01\x08\x02"; + string data = "\x0A\x04\x10\x01\x08\x02"; EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); @@ -717,14 +719,14 @@ TEST(Lite, AllLite34) { } TEST(Lite, AllLite35) { - std::string data; + string data; { // DuplicatedKeyWireFormat protobuf_unittest::TestMapLite message; // Two key fields in wire format - std::string data = "\x0A\x06\x08\x01\x08\x02\x10\x01"; + string data = "\x0A\x06\x08\x01\x08\x02\x10\x01"; EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); @@ -733,14 +735,14 @@ TEST(Lite, AllLite35) { } TEST(Lite, AllLite36) { - std::string data; + string data; { // DuplicatedValueWireFormat protobuf_unittest::TestMapLite message; // Two value fields in wire format - std::string data = "\x0A\x06\x08\x01\x10\x01\x10\x02"; + string data = "\x0A\x06\x08\x01\x10\x01\x10\x02"; EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); @@ -749,14 +751,14 @@ TEST(Lite, AllLite36) { } TEST(Lite, AllLite37) { - std::string data; + string data; { // MissedKeyWireFormat protobuf_unittest::TestMapLite message; // No key field in wire format - std::string data = "\x0A\x02\x10\x01"; + string data = "\x0A\x02\x10\x01"; EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); @@ -765,14 +767,14 @@ TEST(Lite, AllLite37) { } TEST(Lite, AllLite38) { - std::string data; + string data; { // MissedValueWireFormat protobuf_unittest::TestMapLite message; // No value field in wire format - std::string data = "\x0A\x02\x08\x01"; + string data = "\x0A\x02\x08\x01"; EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); @@ -781,14 +783,14 @@ TEST(Lite, AllLite38) { } TEST(Lite, AllLite39) { - std::string data; + string data; { // UnknownFieldWireFormat protobuf_unittest::TestMapLite message; // Unknown field in wire format - std::string data = "\x0A\x06\x08\x02\x10\x03\x18\x01"; + string data = "\x0A\x06\x08\x02\x10\x03\x18\x01"; EXPECT_TRUE(message.ParseFromString(data)); EXPECT_EQ(1, message.map_int32_int32().size()); @@ -797,21 +799,21 @@ TEST(Lite, AllLite39) { } TEST(Lite, AllLite40) { - std::string data; + string data; { // CorruptedWireFormat protobuf_unittest::TestMapLite message; // corrupted data in wire format - std::string data = "\x0A\x06\x08\x02\x11\x03"; + string data = "\x0A\x06\x08\x02\x11\x03"; EXPECT_FALSE(message.ParseFromString(data)); } } TEST(Lite, AllLite41) { - std::string data; + string data; { // IsInitialized @@ -830,7 +832,7 @@ TEST(Lite, AllLite41) { } TEST(Lite, AllLite42) { - std::string data; + string data; { // Check that adding more values to enum does not corrupt message @@ -839,7 +841,7 @@ TEST(Lite, AllLite42) { v2_message.set_int_field(800); // Set enum field to the value not understood by the old client. v2_message.set_enum_field(protobuf_unittest::V2_SECOND); - std::string v2_bytes = v2_message.SerializeAsString(); + string v2_bytes = v2_message.SerializeAsString(); protobuf_unittest::V1MessageLite v1_message; v1_message.ParseFromString(v2_bytes); @@ -850,7 +852,7 @@ TEST(Lite, AllLite42) { EXPECT_EQ(v1_message.enum_field(), protobuf_unittest::V1_FIRST); // However, when re-serialized, it should preserve enum value. - std::string v1_bytes = v1_message.SerializeAsString(); + string v1_bytes = v1_message.SerializeAsString(); protobuf_unittest::V2MessageLite same_v2_message; same_v2_message.ParseFromString(v1_bytes); @@ -858,6 +860,131 @@ TEST(Lite, AllLite42) { EXPECT_EQ(v2_message.int_field(), same_v2_message.int_field()); EXPECT_EQ(v2_message.enum_field(), same_v2_message.enum_field()); } +} + +// Test that when parsing a oneof, we can successfully clear whatever already +// happened to be stored in the oneof. +TEST(Lite, AllLite43) { + protobuf_unittest::TestOneofParsingLite message1; + + message1.set_oneof_int32(17); + string serialized; + EXPECT_TRUE(message1.SerializeToString(&serialized)); + + // Submessage + { + protobuf_unittest::TestOneofParsingLite message2; + message2.mutable_oneof_submessage(); + google::protobuf::io::CodedInputStream input_stream( + reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), serialized.size()); + EXPECT_TRUE(message2.MergeFromCodedStream(&input_stream)); + EXPECT_EQ(17, message2.oneof_int32()); + } + + // String + { + protobuf_unittest::TestOneofParsingLite message2; + message2.set_oneof_string("string"); + google::protobuf::io::CodedInputStream input_stream( + reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), serialized.size()); + EXPECT_TRUE(message2.MergeFromCodedStream(&input_stream)); + EXPECT_EQ(17, message2.oneof_int32()); + } + + // Bytes + { + protobuf_unittest::TestOneofParsingLite message2; + message2.set_oneof_bytes("bytes"); + google::protobuf::io::CodedInputStream input_stream( + reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), serialized.size()); + EXPECT_TRUE(message2.MergeFromCodedStream(&input_stream)); + EXPECT_EQ(17, message2.oneof_int32()); + } +} + +// Verify that we can successfully parse fields of various types within oneof +// fields. We also verify that we can parse the same data twice into the same +// message. +TEST(Lite, AllLite44) { + // Int32 + { + protobuf_unittest::TestOneofParsingLite original; + original.set_oneof_int32(17); + string serialized; + EXPECT_TRUE(original.SerializeToString(&serialized)); + protobuf_unittest::TestOneofParsingLite parsed; + for (int i = 0; i < 2; ++i) { + google::protobuf::io::CodedInputStream input_stream( + reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), + serialized.size()); + EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream)); + EXPECT_EQ(17, parsed.oneof_int32()); + } + } + + // Submessage + { + protobuf_unittest::TestOneofParsingLite original; + original.mutable_oneof_submessage()->set_optional_int32(5); + string serialized; + EXPECT_TRUE(original.SerializeToString(&serialized)); + protobuf_unittest::TestOneofParsingLite parsed; + for (int i = 0; i < 2; ++i) { + google::protobuf::io::CodedInputStream input_stream( + reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), + serialized.size()); + EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream)); + EXPECT_EQ(5, parsed.oneof_submessage().optional_int32()); + } + } + + // String + { + protobuf_unittest::TestOneofParsingLite original; + original.set_oneof_string("string"); + string serialized; + EXPECT_TRUE(original.SerializeToString(&serialized)); + protobuf_unittest::TestOneofParsingLite parsed; + for (int i = 0; i < 2; ++i) { + google::protobuf::io::CodedInputStream input_stream( + reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), + serialized.size()); + EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream)); + EXPECT_EQ("string", parsed.oneof_string()); + } + } + + // Bytes + { + protobuf_unittest::TestOneofParsingLite original; + original.set_oneof_bytes("bytes"); + string serialized; + EXPECT_TRUE(original.SerializeToString(&serialized)); + protobuf_unittest::TestOneofParsingLite parsed; + for (int i = 0; i < 2; ++i) { + google::protobuf::io::CodedInputStream input_stream( + reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), + serialized.size()); + EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream)); + EXPECT_EQ("bytes", parsed.oneof_bytes()); + } + } + + // Enum + { + protobuf_unittest::TestOneofParsingLite original; + original.set_oneof_enum(protobuf_unittest::V2_SECOND); + string serialized; + EXPECT_TRUE(original.SerializeToString(&serialized)); + protobuf_unittest::TestOneofParsingLite parsed; + for (int i = 0; i < 2; ++i) { + google::protobuf::io::CodedInputStream input_stream( + reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), + serialized.size()); + EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream)); + EXPECT_EQ(protobuf_unittest::V2_SECOND, parsed.oneof_enum()); + } + } std::cout << "PASS" << std::endl; } diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 6a88600c..6514a0cc 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -932,12 +932,16 @@ class Map { public: // Iterators - class const_iterator - : public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t, - const value_type*, const value_type&> { + class const_iterator { typedef typename InnerMap::const_iterator InnerIt; public: + typedef std::forward_iterator_tag iterator_category; + typedef typename Map::value_type value_type; + typedef ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + const_iterator() {} explicit const_iterator(const InnerIt& it) : it_(it) {} @@ -963,10 +967,16 @@ class Map { InnerIt it_; }; - class iterator : public std::iterator<std::forward_iterator_tag, value_type> { + class iterator { typedef typename InnerMap::iterator InnerIt; public: + typedef std::forward_iterator_tag iterator_category; + typedef typename Map::value_type value_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef value_type& reference; + iterator() {} explicit iterator(const InnerIt& it) : it_(it) {} diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 7c675568..afe809b2 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -98,11 +98,12 @@ class MapEntry offsets_, has_bits_, GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _has_bits_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, - _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _internal_metadata_), -1, -1, - sizeof(MapEntry)}; + sizeof(MapEntry), + -1, + }; const Reflection* reflection = new GeneratedMessageReflection( descriptor, schema, DescriptorPool::generated_pool(), MessageFactory::generated_factory()); @@ -147,6 +148,30 @@ template <typename Derived, typename Key, typename Value, uint32 MapEntry<Derived, Key, Value, kKeyFieldType, kValueFieldType, default_enum_value>::has_bits_[2] = {0, 1}; +// Specialization for the full runtime +template <typename Derived, typename Key, typename Value, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +struct MapEntryHelper<MapEntry<Derived, Key, Value, kKeyFieldType, + kValueFieldType, default_enum_value> > + : MapEntryHelper<MapEntryLite<Key, Value, kKeyFieldType, kValueFieldType, + default_enum_value> > { + explicit MapEntryHelper(const MapPair<Key, Value>& map_pair) + : MapEntryHelper<MapEntryLite<Key, Value, kKeyFieldType, kValueFieldType, + default_enum_value> >(map_pair) {} +}; + +template <typename Derived, typename K, typename V, + WireFormatLite::FieldType key, WireFormatLite::FieldType value, + int default_enum> +struct DeconstructMapEntry<MapEntry<Derived, K, V, key, value, default_enum> > { + typedef K Key; + typedef V Value; + static const WireFormatLite::FieldType kKeyFieldType = key; + static const WireFormatLite::FieldType kValueFieldType = value; + static const int default_enum_value = default_enum; +}; + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 15104490..0bccf4d2 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -34,6 +34,7 @@ #include <assert.h> #include <google/protobuf/arena.h> +#include <google/protobuf/map.h> #include <google/protobuf/map_type_handler.h> #include <google/protobuf/wire_format_lite_inl.h> @@ -553,6 +554,23 @@ class MapEntryLite default_enum_value>& other) { MergeFromInternal(other); } + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite); +}; +// The completely unprincipled and unwieldy use of template parameters in +// the map code necessitates wrappers to make the code a little bit more +// manageable. +template <typename Derived> +struct DeconstructMapEntry; + +template <typename K, typename V, WireFormatLite::FieldType key, + WireFormatLite::FieldType value, int default_enum> +struct DeconstructMapEntry<MapEntryLite<K, V, key, value, default_enum> > { + typedef K Key; + typedef V Value; + static const WireFormatLite::FieldType kKeyFieldType = key; + static const WireFormatLite::FieldType kValueFieldType = value; + static const int default_enum_value = default_enum; }; // Helpers for deterministic serialization ============================= @@ -581,6 +599,75 @@ template <typename T> struct CompareByDerefFirst { } }; +// Helper for table driven serialization + +template <WireFormatLite::FieldType FieldType> +struct FromHelper { + template <typename T> + static const T& From(const T& x) { + return x; + } +}; + +template <> +struct FromHelper<WireFormatLite::TYPE_STRING> { + static ArenaStringPtr From(const string& x) { + ArenaStringPtr res; + res.UnsafeArenaSetAllocated(NULL, const_cast<string*>(&x), NULL); + return res; + } +}; +template <> +struct FromHelper<WireFormatLite::TYPE_BYTES> { + static ArenaStringPtr From(const string& x) { + ArenaStringPtr res; + res.UnsafeArenaSetAllocated(NULL, const_cast<string*>(&x), NULL); + return res; + } +}; +template <> +struct FromHelper<WireFormatLite::TYPE_MESSAGE> { + template <typename T> + static T* From(const T& x) { + return const_cast<T*>(&x); + } +}; + +template <typename MapEntryType> +struct MapEntryHelper; + +template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +struct MapEntryHelper<MapEntryLite<Key, Value, kKeyFieldType, kValueFieldType, + default_enum_value> > { + // Provide utilities to parse/serialize key/value. Provide utilities to + // manipulate internal stored type. + typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler; + typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler; + + // Define internal memory layout. Strings and messages are stored as + // pointers, while other types are stored as values. + typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory; + typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory; + + explicit MapEntryHelper(const MapPair<Key, Value>& map_pair) + : _has_bits_(3), + _cached_size_(2 + KeyTypeHandler::GetCachedSize(map_pair.first) + + ValueTypeHandler::GetCachedSize(map_pair.second)), + key_(FromHelper<kKeyFieldType>::From(map_pair.first)), + value_(FromHelper<kValueFieldType>::From(map_pair.second)) {} + + // Purposely not folowing the style guide naming. These are the names + // the proto compiler would generate given the map entry descriptor. + // The proto compiler generates the offsets in this struct as if this was + // a regular message. This way the table driven code barely notices it's + // dealing with a map field. + uint32 _has_bits_; // NOLINT + uint32 _cached_size_; // NOLINT + KeyOnMemory key_; // NOLINT + ValueOnMemory value_; // NOLINT +}; + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 9d5a328e..bd478901 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -170,6 +170,7 @@ class LIBPROTOBUF_EXPORT MapFieldBase { // IncreaseIterator() is called by operator++() of MapIterator only. // It implements the ++ operator of MapIterator. virtual void IncreaseIterator(MapIterator* map_iter) const = 0; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldBase); }; // This class provides common Map Reflection implementations for generated @@ -199,6 +200,7 @@ class TypeDefinedMapFieldBase : public MapFieldBase { void IncreaseIterator(MapIterator* map_iter) const; virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase); }; // This class provides access to map field using generated api. It is used for @@ -231,6 +233,9 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> { typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType; public: + typedef typename Derived::SuperType EntryTypeTrait; + typedef Map<Key, T> MapType; + MapField() {} explicit MapField(Arena* arena) : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {} @@ -287,6 +292,15 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> { friend class ::google::protobuf::Arena; friend class MapFieldStateTest; // For testing, it needs raw access to impl_ + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapField); +}; + +template <typename MEntry> +struct MapEntryToMapField { + typedef DeconstructMapEntry<typename MEntry::SuperType> T; + typedef MapField<MEntry, typename T::Key, typename T::Value, T::kKeyFieldType, + T::kValueFieldType, T::default_enum_value> + MapFieldType; }; class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey, MapValueRef> { @@ -314,6 +328,7 @@ class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey, void SyncMapWithRepeatedFieldNoLock() const; size_t SpaceUsedExcludingSelfNoLock() const; void SetMapIteratorValue(MapIterator* map_iter) const; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField); }; } // namespace internal @@ -338,6 +353,10 @@ class LIBPROTOBUF_EXPORT MapKey { MapKey(const MapKey& other) : type_(0) { CopyFrom(other); } + MapKey& operator=(const MapKey& other) { + CopyFrom(other); + return *this; + } ~MapKey() { if (type_ == FieldDescriptor::CPPTYPE_STRING) { @@ -697,6 +716,7 @@ class LIBPROTOBUF_EXPORT MapValueRef { void* data_; // type_ is 0 or a valid FieldDescriptor::CppType. int type_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapValueRef); }; #undef TYPE_CHECK @@ -718,6 +738,11 @@ class LIBPROTOBUF_EXPORT MapIterator { ~MapIterator() { map_->DeleteIterator(this); } + MapIterator& operator=(const MapIterator& other) { + map_ = other.map_; + map_->CopyIterator(this, other); + return *this; + } friend bool operator==(const MapIterator& a, const MapIterator& b) { return a.map_->EqualIterator(a, b); } diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h index 91de9627..12d4e6ba 100644 --- a/src/google/protobuf/map_field_lite.h +++ b/src/google/protobuf/map_field_lite.h @@ -33,6 +33,7 @@ #include <google/protobuf/map.h> #include <google/protobuf/map_entry_lite.h> +#include <google/protobuf/wire_format_lite.h> namespace google { namespace protobuf { @@ -49,6 +50,9 @@ class MapFieldLite { typedef Derived EntryType; public: + typedef Map<Key, T> MapType; + typedef EntryType EntryTypeTrait; + MapFieldLite() : arena_(NULL) { SetDefaultEnumValue(); } explicit MapFieldLite(Arena* arena) : arena_(arena), map_(arena) { @@ -104,7 +108,6 @@ class MapFieldLite { friend class ::google::protobuf::Arena; }; - // 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 // protobuf compiler from ever having to emit loops in IsInitialized() methods. diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index a06b432a..960589ce 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -236,6 +236,13 @@ TEST_F(MapImplTest, UsageErrors) { #endif // PROTOBUF_HAS_DEATH_TEST +TEST_F(MapImplTest, MapKeyAssignment) { + MapKey from, to; + from.SetStringValue("abc"); + to = from; + EXPECT_EQ("abc", to.GetStringValue()); +} + TEST_F(MapImplTest, CountNonExist) { EXPECT_EQ(0, map_.count(0)); } @@ -954,6 +961,17 @@ TEST_F(MapImplTest, SwapArena) { testing::Pair(9398, 41999))); } +TEST_F(MapImplTest, CopyAssignMapIterator) { + TestMap message; + MapReflectionTester reflection_tester( + unittest::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaMapReflection(&message); + MapIterator it1 = reflection_tester.MapBegin(&message, "map_int32_int32"); + MapIterator it2 = reflection_tester.MapEnd(&message, "map_int32_int32"); + it2 = it1; + EXPECT_EQ(it1.GetKey().GetInt32Value(), it2.GetKey().GetInt32Value()); +} + // Map Field Reflection Test ======================================== static int Func(int i, int j) { diff --git a/src/google/protobuf/map_test_util.cc b/src/google/protobuf/map_test_util.cc index 4d3ad609..31ac1736 100644 --- a/src/google/protobuf/map_test_util.cc +++ b/src/google/protobuf/map_test_util.cc @@ -760,6 +760,18 @@ Message* MapReflectionTester::GetMapEntryViaReflection(Message* message, return reflection->MutableRepeatedMessage(message, F(field_name), index); } +MapIterator MapReflectionTester::MapBegin(Message* message, + const string& field_name) { + const Reflection* reflection = message->GetReflection(); + return reflection->MapBegin(message, F(field_name)); +} + +MapIterator MapReflectionTester::MapEnd(Message* message, + const string& field_name) { + const Reflection* reflection = message->GetReflection(); + return reflection->MapEnd(message, F(field_name)); +} + 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 15c6c289..dd397619 100644 --- a/src/google/protobuf/map_test_util.h +++ b/src/google/protobuf/map_test_util.h @@ -111,6 +111,8 @@ class MapReflectionTester { const MapKey& map_key, MapValueRef* map_val); Message* GetMapEntryViaReflection(Message* message, const string& field_name, int index); + MapIterator MapBegin(Message* message, const string& field_name); + MapIterator MapEnd(Message* message, const string& field_name); private: const FieldDescriptor* F(const string& name); diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index aa365991..423c98f1 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -32,7 +32,6 @@ #define GOOGLE_PROTOBUF_TYPE_HANDLER_H__ #include <google/protobuf/arena.h> -#include <google/protobuf/generated_message_util.h> #include <google/protobuf/wire_format_lite_inl.h> namespace google { diff --git a/src/google/protobuf/map_unittest.proto b/src/google/protobuf/map_unittest.proto index c6154f04..836dc10b 100644 --- a/src/google/protobuf/map_unittest.proto +++ b/src/google/protobuf/map_unittest.proto @@ -60,6 +60,7 @@ message TestMap { map<int32 , MapEnum > map_int32_enum = 16; map<int32 , ForeignMessage> map_int32_foreign_message = 17; map<string , ForeignMessage> map_string_foreign_message = 18; + map<int32 , TestAllTypes> map_int32_all_types = 19; } message TestMapSubmessage { diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 2134f95f..c01d1974 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -143,7 +143,13 @@ bool Message::ParsePartialFromIstream(std::istream* input) { void Message::SerializeWithCachedSizes( io::CodedOutputStream* output) const { - WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output); + const internal::SerializationTable* table = + static_cast<const internal::SerializationTable*>(InternalGetTable()); + if (table == 0) { + WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output); + } else { + internal::TableSerialize(*this, table, output); + } } size_t Message::ByteSizeLong() const { @@ -191,6 +197,10 @@ bool Message::SerializePartialToOstream(std::ostream* output) const { Reflection::~Reflection() {} +void Reflection::AddAllocatedMessage(Message* /* message */, + const FieldDescriptor* /*field */, + Message* /* new_entry */) const {} + #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \ template<> \ const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \ diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index c155cbd6..44fe0fde 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -254,6 +254,7 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // fields defined for the proto. virtual size_t SpaceUsedLong() const; + PROTOBUF_RUNTIME_DEPRECATED("Please use SpaceUsedLong() instead") int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); } // Debugging & Testing---------------------------------------------- @@ -428,6 +429,7 @@ class LIBPROTOBUF_EXPORT Reflection { // Estimate the amount of memory used by the message object. virtual size_t SpaceUsedLong(const Message& message) const = 0; + PROTOBUF_RUNTIME_DEPRECATED("Please use SpaceUsedLong() instead") int SpaceUsed(const Message& message) const { return internal::ToIntSize(SpaceUsedLong(message)); } @@ -752,9 +754,9 @@ class LIBPROTOBUF_EXPORT Reflection { // specifyed by 'field' passing ownership to the message. // TODO(tmarek): Make virtual after all subclasses have been // updated. - virtual void AddAllocatedMessage(Message* /* message */, - const FieldDescriptor* /* field */, - Message* /* new_entry */) const {} + virtual void AddAllocatedMessage(Message* message, + const FieldDescriptor* field, + Message* new_entry) const; // Get a RepeatedFieldRef object that can be used to read the underlying diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index fda84b51..83a92d5a 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -227,19 +227,6 @@ uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const { io::CodedOutputStream::IsDefaultSerializationDeterministic(), target); } -uint8* MessageLite::InternalSerializeWithCachedSizesToArray( - bool deterministic, uint8* target) const { - // We only optimize this when using optimize_for = SPEED. In other cases - // we just use the CodedOutputStream path. - int size = GetCachedSize(); - io::ArrayOutputStream out(target, size); - io::CodedOutputStream coded_out(&out); - coded_out.SetSerializationDeterministic(deterministic); - SerializeWithCachedSizes(&coded_out); - GOOGLE_CHECK(!coded_out.HadError()); - return target + size; -} - bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const { GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); return SerializePartialToCodedStream(output); @@ -357,6 +344,36 @@ string MessageLite::SerializePartialAsString() const { return output; } +void MessageLite::SerializeWithCachedSizes(io::CodedOutputStream* output) const + { + GOOGLE_DCHECK(InternalGetTable()); + internal::TableSerialize(*this, static_cast<const internal::SerializationTable*>(InternalGetTable()), output); +} + +// The table driven code optimizes the case that the CodedOutputStream buffer +// is large enough to serialize into it directly. +// If the proto is optimized for speed, this method will be overridden by +// generated code for maximum speed. If the proto is optimized for size or +// is lite, then we need to specialize this to avoid infinite recursion. +uint8* MessageLite::InternalSerializeWithCachedSizesToArray(bool deterministic, + uint8* target) const { + const internal::SerializationTable* table = + static_cast<const internal::SerializationTable*>(InternalGetTable()); + if (table == NULL) { + // We only optimize this when using optimize_for = SPEED. In other cases + // we just use the CodedOutputStream path. + int size = GetCachedSize(); + io::ArrayOutputStream out(target, size); + io::CodedOutputStream coded_out(&out); + coded_out.SetSerializationDeterministic(deterministic); + SerializeWithCachedSizes(&coded_out); + GOOGLE_CHECK(!coded_out.HadError()); + return target + size; + } else { + return internal::TableSerializeToArray(*this, table, deterministic, target); + } +} + namespace internal { template<> MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype( @@ -373,6 +390,13 @@ void GenericTypeHandler<string>::Merge(const string& from, string* to) { *to = from; } + +bool proto3_preserve_unknown_ = false; +void SetProto3PreserveUnknownsDefault(bool preserve) { + proto3_preserve_unknown_ = preserve; +} + + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 046a736d..2075f4b6 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -42,22 +42,130 @@ #include <climits> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/logging.h> -#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/stubs/once.h> +#if LANG_CXX11 && !defined(__NVCC__) +#define PROTOBUF_CXX11 1 +#else +#define PROTOBUF_CXX11 0 +#endif + +#if PROTOBUF_CXX11 +#define PROTOBUF_FINAL final +#else +#define PROTOBUF_FINAL +#endif + +#ifndef LIBPROTOBUF_EXPORT +#define LIBPROTOBUF_EXPORT +#endif + +#define PROTOBUF_RUNTIME_DEPRECATED(message) + namespace google { namespace protobuf { - class Arena; +class Arena; namespace io { - class CodedInputStream; - class CodedOutputStream; - class ZeroCopyInputStream; - class ZeroCopyOutputStream; +class CodedInputStream; +class CodedOutputStream; +class ZeroCopyInputStream; +class ZeroCopyOutputStream; } namespace internal { - class WireFormatLite; + +class WireFormatLite; + +#ifndef SWIG +// 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. 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<int>(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 64-bit platforms because it avoids making the compiler emit a +// sign extending instruction, which we don't want and don't want to pay for. +inline size_t FromIntSize(int size) { + // Convert to unsigned before widening so sign extension is not necessary. + return static_cast<unsigned int>(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<size_t>(INT_MAX)); + return static_cast<int>(size); } +// This type wraps a variable whose constructor and destructor are explicitly +// called. It is particularly useful for a global variable, without its +// constructor and destructor run on start and end of the program lifetime. +// This circumvents the initial construction order fiasco, while keeping +// the address of the empty string a compile time constant. +// +// Pay special attention to the initialization state of the object. +// 1. The object is "uninitialized" to begin with. +// 2. Call DefaultConstruct() only if the object is uninitialized. +// After the call, the object becomes "initialized". +// 3. Call get() and get_mutable() only if the object is initialized. +// 4. Call Destruct() only if the object is initialized. +// After the call, the object becomes uninitialized. +template <typename T> +class ExplicitlyConstructed { + public: + void DefaultConstruct() { + new (&union_) T(); + } + + void Destruct() { + get_mutable()->~T(); + } + +#if LANG_CXX11 + constexpr +#endif + const T& + get() const { + return reinterpret_cast<const T&>(union_); + } + T* get_mutable() { return reinterpret_cast<T*>(&union_); } + + private: + // Prefer c++14 aligned_storage, but for compatibility this will do. + union AlignedUnion { + char space[sizeof(T)]; + int64 align_to_int64; + void* align_to_ptr; + } union_; +}; + +// Default empty string object. Don't use this directly. Instead, call +// GetEmptyString() to get the reference. +extern ExplicitlyConstructed< ::std::string> fixed_address_empty_string; +LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_; +LIBPROTOBUF_EXPORT void InitEmptyString(); + + +LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() { + return fixed_address_empty_string.get(); +} + +LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() { + ::google::protobuf::GoogleOnceInit(&empty_string_once_init_, &InitEmptyString); + return GetEmptyStringAlreadyInited(); +} + +LIBPROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const string& str); +#endif // SWIG +} // namespace internal + // Interface to light weight protocol messages. // // This interface is implemented by all protocol message objects. Non-lite @@ -102,18 +210,19 @@ class LIBPROTOBUF_EXPORT MessageLite { // Get the arena, if any, associated with this message. Virtual method // required for generic operations but most arena-related operations should // use the GetArenaNoVirtual() generated-code method. Default implementation - // to reduce code size by avoiding the need for per-type implementations when - // types do not implement arena support. + // to reduce code size by avoiding the need for per-type implementations + // when types do not implement arena support. virtual ::google::protobuf::Arena* GetArena() const { return NULL; } - // Get a pointer that may be equal to this message's arena, or may not be. If - // the value returned by this method is equal to some arena pointer, then this - // message is on that arena; however, if this message is on some arena, this - // method may or may not return that arena's pointer. As a tradeoff, this - // method may be more efficient than GetArena(). The intent is to allow - // underlying representations that use e.g. tagged pointers to sometimes store - // the arena pointer directly, and sometimes in a more indirect way, and allow - // a fastpath comparison against the arena pointer when it's easy to obtain. + // Get a pointer that may be equal to this message's arena, or may not be. + // If the value returned by this method is equal to some arena pointer, then + // this message is on that arena; however, if this message is on some arena, + // this method may or may not return that arena's pointer. As a tradeoff, + // this method may be more efficient than GetArena(). The intent is to allow + // underlying representations that use e.g. tagged pointers to sometimes + // store the arena pointer directly, and sometimes in a more indirect way, + // and allow a fastpath comparison against the arena pointer when it's easy + // to obtain. virtual void* GetMaybeArenaPointer() const { return GetArena(); } // Clear all fields of the message and set them to their default values. @@ -131,19 +240,20 @@ class LIBPROTOBUF_EXPORT MessageLite { // for full messages. See message.h. virtual string InitializationErrorString() const; - // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, + // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, // results are undefined (probably crash). virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0; // Parsing --------------------------------------------------------- // Methods for parsing in protocol buffer format. Most of these are - // just simple wrappers around MergeFromCodedStream(). Clear() will be called - // before merging the input. - - // Fill the message with a protocol buffer parsed from the given input stream. - // Returns false on a read error or if the input is in the wrong format. A - // successful return does not indicate the entire input is consumed, ensure - // you call ConsumedEntireMessage() to check that if applicable. + // just simple wrappers around MergeFromCodedStream(). Clear() will be + // called before merging the input. + + // Fill the message with a protocol buffer parsed from the given input + // stream. Returns false on a read error or if the input is in the wrong + // format. A successful return does not indicate the entire input is + // consumed, ensure you call ConsumedEntireMessage() to check that if + // applicable. bool ParseFromCodedStream(io::CodedInputStream* input); // Like ParseFromCodedStream(), but accepts messages that are missing // required fields. @@ -249,13 +359,16 @@ class LIBPROTOBUF_EXPORT MessageLite { virtual size_t ByteSizeLong() const = 0; // Legacy ByteSize() API. - int ByteSize() const { return internal::ToIntSize(ByteSizeLong()); } + PROTOBUF_RUNTIME_DEPRECATED("Please use ByteSizeLong() instead") + 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 // ByteSize must be non-negative. Otherwise the results are undefined. virtual void SerializeWithCachedSizes( - io::CodedOutputStream* output) const = 0; + io::CodedOutputStream* output) const; // 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 @@ -286,11 +399,31 @@ class LIBPROTOBUF_EXPORT MessageLite { uint8* target) const; private: + // TODO(gerbens) make this a pure abstract function + virtual const void* InternalGetTable() const { return NULL; } + friend class internal::WireFormatLite; + friend class Message; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); }; +namespace internal { + +extern bool LIBPROTOBUF_EXPORT proto3_preserve_unknown_; + +// DO NOT USE: For migration only. Will be removed when Proto3 defaults to +// preserve unknowns. +inline bool GetProto3PreserveUnknownsDefault() { + return proto3_preserve_unknown_; +} + +// DO NOT USE: For migration only. Will be removed when Proto3 defaults to +// preserve unknowns. +void LIBPROTOBUF_EXPORT SetProto3PreserveUnknownsDefault(bool preserve); +} // namespace internal + + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc index cbf9051a..fe456677 100644 --- a/src/google/protobuf/message_unittest.cc +++ b/src/google/protobuf/message_unittest.cc @@ -49,6 +49,7 @@ #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/arena.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/generated_message_reflection.h> @@ -62,7 +63,7 @@ namespace google { namespace protobuf { -#if defined(_WIN32) +#if defined(_MSC_VER) // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. using google::protobuf::internal::win32::close; @@ -118,8 +119,9 @@ TEST(MessageTest, ParseFromFileDescriptor) { string filename = TestSourceDir() + "/google/protobuf/testdata/golden_message"; int file = open(filename.c_str(), O_RDONLY | O_BINARY); + ASSERT_GE(file, 0); - unittest::TestAllTypes message; + protobuf_unittest::TestAllTypes message; EXPECT_TRUE(message.ParseFromFileDescriptor(file)); TestUtil::ExpectAllFieldsSet(message); @@ -131,8 +133,9 @@ TEST(MessageTest, ParsePackedFromFileDescriptor) { TestSourceDir() + "/google/protobuf/testdata/golden_packed_fields_message"; int file = open(filename.c_str(), O_RDONLY | O_BINARY); + ASSERT_GE(file, 0); - unittest::TestPackedTypes message; + protobuf_unittest::TestPackedTypes message; EXPECT_TRUE(message.ParseFromFileDescriptor(file)); TestUtil::ExpectPackedFieldsSet(message); @@ -273,6 +276,8 @@ TEST(MessageTest, CheckOverflow) { } TEST(MessageTest, CheckBigOverflow) { + // Checking for 4GB buffers on 32 bit systems is problematic. + if (sizeof(void*) < 8) return; unittest::TestAllTypes message; // Create a message with size just over 4GB. We should be able to detect this // too, even though it will make a plain "int" wrap back to a positive number. @@ -428,6 +433,18 @@ TEST(MessageTest, MessageIsStillValidAfterParseFails) { EXPECT_FALSE(message.ParseFromString(invalid_data)); message.Clear(); EXPECT_EQ(0, message.optional_uint64()); + + // invalid data for field "optional_string". Length prefix is 1 but no + // payload. + string invalid_string_data = "\x72\x01"; + { + google::protobuf::Arena arena; + unittest::TestAllTypes* arena_message = + google::protobuf::Arena::CreateMessage<unittest::TestAllTypes>(&arena); + EXPECT_FALSE(arena_message->ParseFromString(invalid_string_data)); + arena_message->Clear(); + EXPECT_EQ("", arena_message->optional_string()); + } } namespace { diff --git a/src/google/protobuf/proto3_arena_unittest.cc b/src/google/protobuf/proto3_arena_unittest.cc index 2838e0fc..3a0fb804 100644 --- a/src/google/protobuf/proto3_arena_unittest.cc +++ b/src/google/protobuf/proto3_arena_unittest.cc @@ -129,7 +129,8 @@ TEST(Proto3ArenaTest, Parsing) { ExpectAllFieldsSet(*arena_message); } -TEST(Proto3ArenaTest, UnknownFields) { +TEST(Proto3ArenaTest, UnknownFieldsDefaultDrop) { + ::google::protobuf::internal::SetProto3PreserveUnknownsDefault(false); TestAllTypes original; SetAllFields(&original); @@ -150,6 +151,28 @@ TEST(Proto3ArenaTest, UnknownFields) { arena_message->GetReflection()->GetUnknownFields(*arena_message).empty()); } +TEST(Proto3ArenaTest, UnknownFieldsDefaultPreserve) { + ::google::protobuf::internal::SetProto3PreserveUnknownsDefault(true); + TestAllTypes original; + SetAllFields(&original); + + Arena arena; + TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena); + arena_message->ParseFromString(original.SerializeAsString()); + ExpectAllFieldsSet(*arena_message); + + // In proto3 we can still get a pointer to the UnknownFieldSet through + // reflection API. + UnknownFieldSet* unknown_fields = + arena_message->GetReflection()->MutableUnknownFields(arena_message); + // We can modify this UnknownFieldSet. + unknown_fields->AddVarint(1, 2); + // And the unknown fields should be changed. + ASSERT_NE(original.ByteSize(), arena_message->ByteSize()); + ASSERT_FALSE( + arena_message->GetReflection()->GetUnknownFields(*arena_message).empty()); +} + TEST(Proto3ArenaTest, Swap) { Arena arena1; Arena arena2; diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 02ee3cc9..d8003b8f 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -59,7 +59,6 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/type_traits.h> #include <google/protobuf/arena.h> -#include <google/protobuf/generated_message_util.h> #include <google/protobuf/message_lite.h> @@ -281,9 +280,6 @@ class RepeatedField PROTOBUF_FINAL { friend class Arena; typedef void InternalArenaConstructable_; - // Move the contents of |from| into |to|, possibly clobbering |from| in the - // process. For primitive types this is just a memcpy(), but it could be - // specialized for non-primitive types to, say, swap each element instead. void MoveArray(Element* to, Element* from, int size); // Copy the elements of |from| into |to|. @@ -597,6 +593,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { // Reserve() and MergeFrom() to reduce code size. |extend_amount| must be > 0. void** InternalExtend(int extend_amount); + friend class AccessorHelper; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase); }; @@ -609,8 +606,7 @@ class GenericTypeHandler { #endif static inline GenericType* New(Arena* arena) { - return ::google::protobuf::Arena::CreateMaybeMessage<Type>( - arena, static_cast<GenericType*>(0)); + return ::google::protobuf::Arena::CreateMaybeMessage<Type>(arena); } static inline GenericType* NewFromPrototype( const GenericType* prototype, ::google::protobuf::Arena* arena = NULL); @@ -2449,6 +2445,12 @@ template<typename T> class RepeatedPtrFieldBackInsertIterator *field_->Add() = *ptr_to_value; return *this; } +#if LANG_CXX11 + RepeatedPtrFieldBackInsertIterator<T>& operator=(T&& value) { + *field_->Add() = std::move(value); + return *this; + } +#endif RepeatedPtrFieldBackInsertIterator<T>& operator*() { return *this; } diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 043cc746..ae501465 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -1586,6 +1586,38 @@ TEST_F(RepeatedFieldInsertionIteratorsTest, EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString()); } +#if LANG_CXX11 +TEST_F(RepeatedFieldInsertionIteratorsTest, MoveStrings) { + std::vector<string> src = {"a", "b", "c", "d"}; + std::vector<string> copy = src; // copy since move leaves in undefined state + TestAllTypes testproto; + std::move(copy.begin(), copy.end(), + RepeatedFieldBackInserter(testproto.mutable_repeated_string())); + + ASSERT_THAT(testproto.repeated_string(), testing::ElementsAreArray(src)); +} + +TEST_F(RepeatedFieldInsertionIteratorsTest, MoveProtos) { + auto make_nested = [](int32 x) { + Nested ret; + ret.set_bb(x); + return ret; + }; + std::vector<Nested> src = {make_nested(3), make_nested(5), make_nested(7)}; + std::vector<Nested> copy = src; // copy since move leaves in undefined state + TestAllTypes testproto; + std::move( + copy.begin(), copy.end(), + RepeatedFieldBackInserter(testproto.mutable_repeated_nested_message())); + + ASSERT_EQ(src.size(), testproto.repeated_nested_message_size()); + for (int i = 0; i < src.size(); ++i) { + EXPECT_EQ(src[i].DebugString(), + testproto.repeated_nested_message(i).DebugString()); + } +} +#endif + } // namespace } // namespace protobuf diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index 9d394f70..a69739c4 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -19,7 +19,10 @@ namespace google { namespace protobuf { -class SourceContextDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<SourceContext> { +class SourceContextDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<SourceContext> + _instance; } _SourceContext_default_instance_; namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto { @@ -32,20 +35,20 @@ namespace { } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::google::protobuf::internal::AuxillaryParseTableField(), }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const - TableStruct::schema[] = { - { NULL, NULL, 0, -1, -1, false }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceContext, _internal_metadata_), ~0u, // no _extensions_ @@ -53,8 +56,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceContext, file_name_), }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(SourceContext)}, }; @@ -84,18 +86,13 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _SourceContext_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); - _SourceContext_default_instance_.DefaultConstruct(); -} + _SourceContext_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_SourceContext_default_instance_);} void InitDefaults() { static GOOGLE_PROTOBUF_DECLARE_ONCE(once); @@ -104,7 +101,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n$google/protobuf/source_context.proto\022\017" "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile" "_name\030\001 \001(\tB\225\001\n\023com.google.protobufB\022Sou" @@ -117,7 +114,6 @@ void AddDescriptorsImpl() { descriptor, 251); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/source_context.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -200,7 +196,12 @@ SourceContext* SourceContext::New(::google::protobuf::Arena* arena) const { void SourceContext::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceContext) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + file_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + _internal_metadata_.Clear(); } bool SourceContext::MergePartialFromCodedStream( @@ -216,7 +217,7 @@ bool SourceContext::MergePartialFromCodedStream( // string file_name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_file_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -231,12 +232,11 @@ bool SourceContext::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -266,6 +266,10 @@ void SourceContext::SerializeWithCachedSizes( 1, this->file_name(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.SourceContext) } @@ -287,6 +291,10 @@ void SourceContext::SerializeWithCachedSizes( 1, this->file_name(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceContext) return target; } @@ -295,6 +303,11 @@ size_t SourceContext::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceContext) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // string file_name = 1; if (this->file_name().size() > 0) { total_size += 1 + @@ -360,8 +373,10 @@ void SourceContext::Swap(SourceContext* other) { InternalSwap(other); } void SourceContext::InternalSwap(SourceContext* other) { + using std::swap; file_name_.Swap(&other->file_name_); - std::swap(_cached_size_, other->_cached_size_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata SourceContext::GetMetadata() const { diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index 66ee1886..b4617c57 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -48,8 +48,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -68,7 +69,21 @@ class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message /* @ CopyFrom(from); return *this; } + #if LANG_CXX11 + SourceContext(SourceContext&& from) noexcept + : SourceContext() { + *this = ::std::move(from); + } + inline SourceContext& operator=(SourceContext&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif static const ::google::protobuf::Descriptor* descriptor(); static const SourceContext& default_instance(); @@ -80,6 +95,9 @@ class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message /* @ 0; void Swap(SourceContext* other); + friend void swap(SourceContext& a, SourceContext& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -149,6 +167,10 @@ class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message /* @ // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // SourceContext // string file_name = 1; @@ -204,6 +226,9 @@ inline void SourceContext::set_allocated_file_name(::std::string* file_name) { // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceContext.file_name) } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // @@protoc_insertion_point(namespace_scope) diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index a7ce0040..02d9306e 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -19,12 +19,20 @@ namespace google { namespace protobuf { -class Struct_FieldsEntryDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Struct::Struct_FieldsEntry> { +class Struct_FieldsEntryDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Struct::Struct_FieldsEntry> + _instance; } _Struct_FieldsEntry_default_instance_; -class StructDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Struct> { +class StructDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Struct> + _instance; } _Struct_default_instance_; -class ValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Value> { - public: +class ValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Value> + _instance; int null_value_; double number_value_; ::google::protobuf::internal::ArenaStringPtr string_value_; @@ -32,7 +40,10 @@ class ValueDefaultTypeInternal : public ::google::protobuf::internal::Explicitly const ::google::protobuf::Struct* struct_value_; const ::google::protobuf::ListValue* list_value_; } _Value_default_instance_; -class ListValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<ListValue> { +class ListValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<ListValue> + _instance; } _ListValue_default_instance_; namespace protobuf_google_2fprotobuf_2fstruct_2eproto { @@ -46,23 +57,23 @@ const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[1]; } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::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 }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, _internal_metadata_), ~0u, // no _extensions_ @@ -74,12 +85,12 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _extensions_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _oneof_case_[0]), ~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_), + offsetof(ValueDefaultTypeInternal, null_value_), + offsetof(ValueDefaultTypeInternal, number_value_), + offsetof(ValueDefaultTypeInternal, string_value_), + offsetof(ValueDefaultTypeInternal, bool_value_), + offsetof(ValueDefaultTypeInternal, struct_value_), + offsetof(ValueDefaultTypeInternal, list_value_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, kind_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, _internal_metadata_), @@ -88,8 +99,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, values_), }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(Struct)}, { 6, -1, sizeof(Value)}, { 18, -1, sizeof(ListValue)}, @@ -110,7 +120,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()); +file_level_metadata[0].reflection = Struct::Struct_FieldsEntry::CreateReflection(file_level_metadata[0].descriptor, _Struct_FieldsEntry_default_instance_._instance.get_mutable()); } void protobuf_AssignDescriptorsOnce() { @@ -125,27 +135,20 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _Struct_default_instance_.Shutdown(); - delete file_level_metadata[1].reflection; - _Value_default_instance_.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() { 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(); + _Struct_FieldsEntry_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Struct_FieldsEntry_default_instance_);_Struct_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Struct_default_instance_);_Value_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Value_default_instance_);_ListValue_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_ListValue_default_instance_);_Struct_FieldsEntry_default_instance_._instance.get_mutable()->set_default_instance(_Struct_FieldsEntry_default_instance_._instance.get_mutable()); + _Struct_FieldsEntry_default_instance_._instance.get_mutable()->InitAsDefaultInstance(); _Value_default_instance_.null_value_ = 0; _Value_default_instance_.number_value_ = 0; _Value_default_instance_.string_value_.UnsafeSetDefault( @@ -164,7 +167,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\034google/protobuf/struct.proto\022\017google.p" "rotobuf\"\204\001\n\006Struct\0223\n\006fields\030\001 \003(\0132#.goo" "gle.protobuf.Struct.FieldsEntry\032E\n\013Field" @@ -187,7 +190,6 @@ void AddDescriptorsImpl() { descriptor, 641); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/struct.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -280,6 +282,7 @@ Struct::~Struct() { void Struct::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -313,7 +316,12 @@ Struct* Struct::New(::google::protobuf::Arena* arena) const { void Struct::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Struct) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + fields_.Clear(); + _internal_metadata_.Clear(); } bool Struct::MergePartialFromCodedStream( @@ -329,7 +337,7 @@ bool Struct::MergePartialFromCodedStream( // map<string, .google.protobuf.Value> fields = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { Struct_FieldsEntry::Parser< ::google::protobuf::internal::MapField< Struct_FieldsEntry, ::std::string, ::google::protobuf::Value, @@ -351,12 +359,11 @@ bool Struct::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -431,6 +438,10 @@ void Struct::SerializeWithCachedSizes( } } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Struct) } @@ -500,6 +511,10 @@ void Struct::SerializeWithCachedSizes( } } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Struct) return target; } @@ -508,6 +523,11 @@ size_t Struct::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Struct) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // map<string, .google.protobuf.Value> fields = 1; total_size += 1 * ::google::protobuf::internal::FromIntSize(this->fields_size()); @@ -598,8 +618,10 @@ void Struct::UnsafeArenaSwap(Struct* other) { InternalSwap(other); } void Struct::InternalSwap(Struct* other) { + using std::swap; fields_.Swap(&other->fields_); - std::swap(_cached_size_, other->_cached_size_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Struct::GetMetadata() const { @@ -707,6 +729,7 @@ Value::~Value() { void Value::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -783,7 +806,12 @@ void Value::clear_kind() { void Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Value) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + clear_kind(); + _internal_metadata_.Clear(); } bool Value::MergePartialFromCodedStream( @@ -799,7 +827,7 @@ bool Value::MergePartialFromCodedStream( // .google.protobuf.NullValue null_value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -814,7 +842,7 @@ bool Value::MergePartialFromCodedStream( // double number_value = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(17u)) { + static_cast< ::google::protobuf::uint8>(17u /* 17 & 0xFF */)) { clear_kind(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( @@ -829,7 +857,7 @@ bool Value::MergePartialFromCodedStream( // string string_value = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_string_value())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -845,7 +873,7 @@ bool Value::MergePartialFromCodedStream( // bool bool_value = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(32u)) { + static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) { clear_kind(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -860,7 +888,7 @@ bool Value::MergePartialFromCodedStream( // .google.protobuf.Struct struct_value = 5; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(42u)) { + static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_struct_value())); } else { @@ -872,7 +900,7 @@ bool Value::MergePartialFromCodedStream( // .google.protobuf.ListValue list_value = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(50u)) { + static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_list_value())); } else { @@ -883,12 +911,11 @@ bool Value::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -946,6 +973,10 @@ void Value::SerializeWithCachedSizes( 6, *kind_.list_value_, output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Value) } @@ -997,6 +1028,10 @@ void Value::SerializeWithCachedSizes( 6, *kind_.list_value_, deterministic, target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value) return target; } @@ -1005,6 +1040,11 @@ size_t Value::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Value) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } switch (kind_case()) { // .google.protobuf.NullValue null_value = 1; case kNullValue: { @@ -1145,9 +1185,11 @@ void Value::UnsafeArenaSwap(Value* other) { InternalSwap(other); } void Value::InternalSwap(Value* other) { - std::swap(kind_, other->kind_); - std::swap(_oneof_case_[0], other->_oneof_case_[0]); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(kind_, other->kind_); + swap(_oneof_case_[0], other->_oneof_case_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Value::GetMetadata() const { @@ -1247,6 +1289,19 @@ void Value::set_string_value(const ::std::string& value) { GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) } +#if LANG_CXX11 +void Value::set_string_value(::std::string&& value) { + // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Value.string_value) +} +#endif void Value::set_string_value(const char* value) { GOOGLE_DCHECK(value != NULL); if (!has_string_value()) { @@ -1585,6 +1640,7 @@ ListValue::~ListValue() { void ListValue::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -1618,7 +1674,12 @@ ListValue* ListValue::New(::google::protobuf::Arena* arena) const { void ListValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + values_.Clear(); + _internal_metadata_.Clear(); } bool ListValue::MergePartialFromCodedStream( @@ -1634,7 +1695,7 @@ bool ListValue::MergePartialFromCodedStream( // repeated .google.protobuf.Value values = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_values())); } else { @@ -1645,12 +1706,11 @@ bool ListValue::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1677,6 +1737,10 @@ void ListValue::SerializeWithCachedSizes( 1, this->values(static_cast<int>(i)), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.ListValue) } @@ -1695,6 +1759,10 @@ void ListValue::SerializeWithCachedSizes( 1, this->values(static_cast<int>(i)), deterministic, target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue) return target; } @@ -1703,6 +1771,11 @@ size_t ListValue::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.ListValue) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // repeated .google.protobuf.Value values = 1; { unsigned int count = static_cast<unsigned int>(this->values_size()); @@ -1784,8 +1857,10 @@ void ListValue::UnsafeArenaSwap(ListValue* other) { InternalSwap(other); } void ListValue::InternalSwap(ListValue* other) { + using std::swap; values_.InternalSwap(&other->values_); - std::swap(_cached_size_, other->_cached_size_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata ListValue::GetMetadata() const { diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index c70912cd..57ae7d90 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -29,6 +29,7 @@ #include <google/protobuf/repeated_field.h> // IWYU pragma: export #include <google/protobuf/extension_set.h> // IWYU pragma: export #include <google/protobuf/map.h> // IWYU pragma: export +#include <google/protobuf/map_entry.h> #include <google/protobuf/map_field_inl.h> #include <google/protobuf/generated_enum_reflection.h> #include <google/protobuf/unknown_field_set.h> @@ -60,8 +61,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -103,7 +105,21 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc CopyFrom(from); return *this; } + #if LANG_CXX11 + Struct(Struct&& from) noexcept + : Struct() { + *this = ::std::move(from); + } + inline Struct& operator=(Struct&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -122,6 +138,9 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc void UnsafeArenaSwap(Struct* other); void Swap(Struct* other); + friend void swap(Struct& a, Struct& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -182,7 +201,7 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; public: @@ -204,6 +223,7 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc static const Message* internal_default_instance() { return reinterpret_cast<const Message*>(&_Struct_FieldsEntry_default_instance_); } ::google::protobuf::Metadata GetMetadata() const; }; + private: ::google::protobuf::internal::MapField< Struct_FieldsEntry, ::std::string, ::google::protobuf::Value, @@ -227,7 +247,21 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_ CopyFrom(from); return *this; } + #if LANG_CXX11 + Value(Value&& from) noexcept + : Value() { + *this = ::std::move(from); + } + inline Value& operator=(Value&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -256,6 +290,9 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_ void UnsafeArenaSwap(Value* other); void Swap(Value* other); + friend void swap(Value& a, Value& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -328,6 +365,9 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_ static const int kStringValueFieldNumber = 3; const ::std::string& string_value() const; void set_string_value(const ::std::string& value); + #if LANG_CXX11 + void set_string_value(::std::string&& value); + #endif void set_string_value(const char* value); void set_string_value(const char* value, size_t size); ::std::string* mutable_string_value(); @@ -397,7 +437,7 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_ inline void clear_has_kind(); ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; union KindUnion { @@ -427,7 +467,21 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@pro CopyFrom(from); return *this; } + #if LANG_CXX11 + ListValue(ListValue&& from) noexcept + : ListValue() { + *this = ::std::move(from); + } + inline ListValue& operator=(ListValue&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -446,6 +500,9 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@pro void UnsafeArenaSwap(ListValue* other); void Swap(ListValue* other); + friend void swap(ListValue& a, ListValue& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -508,7 +565,7 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@pro private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value > values_; @@ -521,6 +578,10 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@pro // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // ------------------------------------------------------------------- // Struct @@ -636,6 +697,19 @@ inline void Value::set_string_value(const ::std::string& value) { GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) } +#if LANG_CXX11 +inline void Value::set_string_value(::std::string&& value) { + // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Value.string_value) +} +#endif inline void Value::set_string_value(const char* value) { GOOGLE_DCHECK(value != NULL); if (!has_string_value()) { @@ -963,6 +1037,9 @@ ListValue::values() const { return values_; } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // ------------------------------------------------------------------- @@ -977,7 +1054,6 @@ ListValue::values() const { } // namespace protobuf } // namespace google -#ifndef SWIG namespace google { namespace protobuf { @@ -989,7 +1065,6 @@ inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::NullValue>() } // namespace protobuf } // namespace google -#endif // SWIG // @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index 14655916..73822168 100644..100755 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc @@ -30,6 +30,7 @@ // Author: kenton@google.com (Kenton Varda) +#include <google/protobuf/message_lite.h> // TODO(gerbens) ideally remove this. #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/once.h> #include <google/protobuf/stubs/status.h> @@ -416,13 +417,30 @@ uint32 ghtonl(uint32 x) { namespace internal { typedef void OnShutdownFunc(); -vector<void (*)()>* shutdown_functions = NULL; -Mutex* shutdown_functions_mutex = NULL; +struct ShutdownData { + ~ShutdownData() { + for (int i = 0; i < functions.size(); i++) { + functions[i](); + } + for (int i = 0; i < strings.size(); i++) { + strings[i]->~string(); + } + for (int i = 0; i < messages.size(); i++) { + messages[i]->~MessageLite(); + } + } + + vector<void (*)()> functions; + vector<const std::string*> strings; + vector<const MessageLite*> messages; + Mutex mutex; +}; + +ShutdownData* shutdown_data = NULL; GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init); void InitShutdownFunctions() { - shutdown_functions = new vector<void (*)()>; - shutdown_functions_mutex = new Mutex; + shutdown_data = new ShutdownData; } inline void InitShutdownFunctionsOnce() { @@ -431,8 +449,20 @@ inline void InitShutdownFunctionsOnce() { void OnShutdown(void (*func)()) { InitShutdownFunctionsOnce(); - MutexLock lock(shutdown_functions_mutex); - shutdown_functions->push_back(func); + MutexLock lock(&shutdown_data->mutex); + shutdown_data->functions.push_back(func); +} + +void OnShutdownDestroyString(const std::string* ptr) { + InitShutdownFunctionsOnce(); + MutexLock lock(&shutdown_data->mutex); + shutdown_data->strings.push_back(ptr); +} + +void OnShutdownDestroyMessage(const void* ptr) { + InitShutdownFunctionsOnce(); + MutexLock lock(&shutdown_data->mutex); + shutdown_data->messages.push_back(static_cast<const MessageLite*>(ptr)); } } // namespace internal @@ -445,15 +475,10 @@ void ShutdownProtobufLibrary() { // called. // Make it safe to call this multiple times. - if (internal::shutdown_functions == NULL) return; + if (internal::shutdown_data == NULL) return; - for (int i = 0; i < internal::shutdown_functions->size(); i++) { - internal::shutdown_functions->at(i)(); - } - delete internal::shutdown_functions; - internal::shutdown_functions = NULL; - delete internal::shutdown_functions_mutex; - internal::shutdown_functions_mutex = NULL; + delete internal::shutdown_data; + internal::shutdown_data = NULL; } #if PROTOBUF_USE_EXCEPTIONS diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index a56f8e89..ff363482 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -101,27 +101,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 3003002 +#define GOOGLE_PROTOBUF_VERSION 3004000 // 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 3003000 +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3004000 // 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 = 3003000; +static const int kMinHeaderVersionForLibrary = 3004000; // The minimum protoc version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3003000 +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3004000 // The minimum header version which works with the current version of // protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 3003000; +static const int kMinHeaderVersionForProtoc = 3004000; // Verifies that the headers and libraries are compatible. Use the macro // below to call this. @@ -200,6 +200,10 @@ namespace internal { // Register a function to be called when ShutdownProtocolBuffers() is called. LIBPROTOBUF_EXPORT void OnShutdown(void (*func)()); +// Destroy the string (call string destructor) +LIBPROTOBUF_EXPORT void OnShutdownDestroyString(const std::string* ptr); +// Destroy (not delete) the message +LIBPROTOBUF_EXPORT void OnShutdownDestroyMessage(const void* ptr); } // namespace internal diff --git a/src/google/protobuf/stubs/io_win32.cc b/src/google/protobuf/stubs/io_win32.cc index 6f0295e1..b418986b 100644 --- a/src/google/protobuf/stubs/io_win32.cc +++ b/src/google/protobuf/stubs/io_win32.cc @@ -39,7 +39,7 @@ // // This file is only used on Windows, it's empty on other platforms. -#if defined(_WIN32) +#if defined(_MSC_VER) // Comment this out to fall back to using the ANSI versions (open, mkdir, ...) // instead of the Unicode ones (_wopen, _wmkdir, ...). Doing so can be useful to @@ -105,15 +105,15 @@ bool has_longpath_prefix(const char_type* path) { path[3] == '\\'; } -// Returns true if the path starts with a drive specifier (e.g. "c:\"). template <typename char_type> -bool is_path_absolute(const char_type* path) { - return has_drive_letter(path) && is_separator(path[2]); +bool is_separator(char_type c) { + return c == '/' || c == '\\'; } +// Returns true if the path starts with a drive specifier (e.g. "c:\"). template <typename char_type> -bool is_separator(char_type c) { - return c == '/' || c == '\\'; +bool is_path_absolute(const char_type* path) { + return has_drive_letter(path) && is_separator(path[2]); } template <typename char_type> @@ -358,5 +358,5 @@ wstring testonly_path_to_winpath(const string& path) { } // namespace protobuf } // namespace google -#endif // defined(_WIN32) +#endif // defined(_MSC_VER) diff --git a/src/google/protobuf/stubs/io_win32.h b/src/google/protobuf/stubs/io_win32.h index daccf16c..a20e64c7 100644 --- a/src/google/protobuf/stubs/io_win32.h +++ b/src/google/protobuf/stubs/io_win32.h @@ -48,30 +48,38 @@ #if defined(_WIN32) #include <string> +#include <google/protobuf/stubs/port.h> +// Compilers on Windows other than MSVC (e.g. Cygwin, MinGW32) define the +// following functions already, except for mkdir. +#ifdef _MSC_VER namespace google { namespace protobuf { namespace internal { namespace win32 { -FILE* fopen(const char* path, const char* mode); -int access(const char* path, int mode); -int chdir(const char* path); -int close(int fd); -int dup(int fd); -int dup2(int fd1, int fd2); -int mkdir(const char* path, int _mode); -int open(const char* path, int flags, int mode = 0); -int read(int fd, void* buffer, size_t size); -int setmode(int fd, int mode); -int stat(const char* path, struct _stat* buffer); -int write(int fd, const void* buffer, size_t size); -std::wstring testonly_path_to_winpath(const std::string& path); +LIBPROTOBUF_EXPORT FILE* fopen(const char* path, const char* mode); +LIBPROTOBUF_EXPORT int access(const char* path, int mode); +LIBPROTOBUF_EXPORT int chdir(const char* path); +LIBPROTOBUF_EXPORT int close(int fd); +LIBPROTOBUF_EXPORT int dup(int fd); +LIBPROTOBUF_EXPORT int dup2(int fd1, int fd2); +LIBPROTOBUF_EXPORT int mkdir(const char* path, int _mode); +LIBPROTOBUF_EXPORT int open(const char* path, int flags, int mode = 0); +LIBPROTOBUF_EXPORT int read(int fd, void* buffer, size_t size); +LIBPROTOBUF_EXPORT int setmode(int fd, int mode); +LIBPROTOBUF_EXPORT int stat(const char* path, struct _stat* buffer); +LIBPROTOBUF_EXPORT int write(int fd, const void* buffer, size_t size); +LIBPROTOBUF_EXPORT std::wstring testonly_path_to_winpath( + const std::string& path); } // namespace win32 } // namespace internal } // namespace protobuf } // namespace google +#else // _MSC_VER +#define mkdir(name, mode) mkdir(name) +#endif // !_MSC_VER #ifndef W_OK #define W_OK 02 // not defined by MSVC for whatever reason diff --git a/src/google/protobuf/stubs/mathlimits.h b/src/google/protobuf/stubs/mathlimits.h index 275d9539..2391ac4c 100644 --- a/src/google/protobuf/stubs/mathlimits.h +++ b/src/google/protobuf/stubs/mathlimits.h @@ -43,18 +43,23 @@ #ifndef UTIL_MATH_MATHLIMITS_H__ #define UTIL_MATH_MATHLIMITS_H__ -// GCC 4.9 has a bug that makes it impossible to use isinf and isnan when both -// <math.h> and <cmath> get pulled into the same translation unit. -// Unfortunately it is difficult to prevent this from happening, so to work -// around the problem we use std::isinf and std::isnan from <cmath> for C++11 -// builds and otherwise use the plain isinf and isnan functions from <math.h>. // Note that for Windows we do something different because it does not support // the plain isinf and isnan. #if __cplusplus >= 201103L +// GCC 4.9 has a bug that makes isinf and isnan ambigious when both <math.h> +// and <cmath> get pulled into the same translation unit. We use the ones in +// std:: namespace explicitly for C++11 #include <cmath> +#define GOOGLE_PROTOBUF_USE_STD_CMATH +#elif _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +// libstdc++ <cmath> header undefines the global macros and put functions in +// std:: namespace even before C++11. Use the ones in std:: instead too. +#include <cmath> +#define GOOGLE_PROTOBUF_USE_STD_CMATH #else #include <math.h> #endif + #include <string.h> #include <cfloat> @@ -229,7 +234,7 @@ DECL_UNSIGNED_INT_LIMITS(unsigned long long int) // For non-Windows builds we use the std:: versions of isinf and isnan if they // are available; see the comment about <cmath> at the top of this file for the // details on why we need to do this. -#if __cplusplus >= 201103L +#ifdef GOOGLE_PROTOBUF_USE_STD_CMATH #define ISINF std::isinf #define ISNAN std::isnan #else diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h index 7ef1cb69..174290f6 100644 --- a/src/google/protobuf/stubs/mutex.h +++ b/src/google/protobuf/stubs/mutex.h @@ -70,14 +70,6 @@ class LIBPROTOBUF_EXPORT Mutex { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); }; -// Undefine the macros to workaround the conflicts with Google internal -// MutexLock implementation. -// TODO(liujisi): Remove the undef once internal macros are removed. -#undef MutexLock -#undef ReaderMutexLock -#undef WriterMutexLock -#undef MutexLockMaybe - // MutexLock(mu) acquires mu when constructed and releases it when destroyed. class LIBPROTOBUF_EXPORT MutexLock { public: diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h index 83eaf31e..0f304c6b 100644 --- a/src/google/protobuf/stubs/port.h +++ b/src/google/protobuf/stubs/port.h @@ -470,6 +470,10 @@ class BigEndian { } }; +#ifndef GOOGLE_ATTRIBUTE_SECTION_VARIABLE +#define GOOGLE_ATTRIBUTE_SECTION_VARIABLE(name) +#endif + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc index a1850e44..f32222b7 100644 --- a/src/google/protobuf/testing/file.cc +++ b/src/google/protobuf/testing/file.cc @@ -55,6 +55,9 @@ namespace protobuf { #define lstat stat // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. +#endif + +#ifdef _MSC_VER using google::protobuf::internal::win32::access; using google::protobuf::internal::win32::chdir; using google::protobuf::internal::win32::fopen; diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc index c6fb00d4..33a75ed6 100644 --- a/src/google/protobuf/testing/googletest.cc +++ b/src/google/protobuf/testing/googletest.cc @@ -52,7 +52,7 @@ namespace google { namespace protobuf { -#ifdef _WIN32 +#ifdef _MSC_VER // DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import // them like we do below. using google::protobuf::internal::win32::close; diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h index bf8bf282..dc4401d0 100644 --- a/src/google/protobuf/testing/googletest.h +++ b/src/google/protobuf/testing/googletest.h @@ -37,7 +37,7 @@ #include <map> #include <vector> #include <google/protobuf/stubs/common.h> - +#include <gmock/gmock.h> // Disable death tests if we use exceptions in CHECK(). #if !PROTOBUF_USE_EXCEPTIONS && defined(GTEST_HAS_DEATH_TEST) #define PROTOBUF_HAS_DEATH_TEST diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 04c887e0..f1d2e8bc 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -42,20 +42,21 @@ #include <google/protobuf/text_format.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/dynamic_message.h> -#include <google/protobuf/repeated_field.h> -#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/any.h> #include <google/protobuf/io/strtod.h> #include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/tokenizer.h> #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/unknown_field_set.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/any.h> -#include <google/protobuf/stubs/stringprintf.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/wire_format_lite.h> #include <google/protobuf/stubs/strutil.h> + #include <google/protobuf/stubs/map_util.h> #include <google/protobuf/stubs/stl_util.h> @@ -364,7 +365,7 @@ class TextFormat::Parser::ParserImpl { const Descriptor* descriptor = message->GetDescriptor(); string field_name; - + bool reserved_field = false; const FieldDescriptor* field = NULL; int start_line = tokenizer_.current().line; int start_column = tokenizer_.current().column; @@ -426,6 +427,8 @@ class TextFormat::Parser::ParserImpl { if (allow_field_number_ && safe_strto32(field_name, &field_number)) { if (descriptor->IsExtensionNumber(field_number)) { field = reflection->FindKnownExtensionByNumber(field_number); + } else if (descriptor->IsReservedNumber(field_number)) { + reserved_field = true; } else { field = descriptor->FindFieldByNumber(field_number); } @@ -454,9 +457,13 @@ class TextFormat::Parser::ParserImpl { LowerString(&lower_field_name); field = descriptor->FindFieldByLowercaseName(lower_field_name); } + + if (field == NULL) { + reserved_field = descriptor->IsReservedName(field_name); + } } - if (field == NULL) { + if (field == NULL && !reserved_field) { if (!allow_unknown_field_) { ReportError("Message type \"" + descriptor->full_name() + "\" has no field named \"" + field_name + "\"."); @@ -468,9 +475,10 @@ class TextFormat::Parser::ParserImpl { } } - // Skips unknown field. + // Skips unknown or reserved fields. if (field == NULL) { - GOOGLE_CHECK(allow_unknown_field_); + GOOGLE_CHECK(allow_unknown_field_ || reserved_field); + // Try to guess the type of this field. // If this field is not a message, there should be a ":" between the // field name and the field value and also the field value should not @@ -1147,7 +1155,8 @@ label_skip_parsing: // =========================================================================== // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted // from the Printer found in //google/protobuf/io/printer.h -class TextFormat::Printer::TextGenerator { +class TextFormat::Printer::TextGenerator + : public TextFormat::BaseTextGenerator { public: explicit TextGenerator(io::ZeroCopyOutputStream* output, int initial_indent_level) @@ -1156,9 +1165,8 @@ class TextFormat::Printer::TextGenerator { buffer_size_(0), at_start_of_line_(true), failed_(false), - indent_(""), + indent_level_(initial_indent_level), initial_indent_level_(initial_indent_level) { - indent_.resize(initial_indent_level_ * 2, ' '); } ~TextGenerator() { @@ -1173,50 +1181,45 @@ class TextFormat::Printer::TextGenerator { // inserted at the beginning of each line of text. Indent() may be called // multiple times to produce deeper indents. void Indent() { - indent_ += " "; + ++indent_level_; } // Reduces the current indent level by two spaces, or crashes if the indent // level is zero. void Outdent() { - if (indent_.empty() || - indent_.size() < initial_indent_level_ * 2) { + if (indent_level_ == 0 || + indent_level_ < initial_indent_level_) { GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; return; } - indent_.resize(indent_.size() - 2); - } - - // Print text to the output stream. - void Print(const string& str) { - Print(str.data(), str.size()); - } - - // Print text to the output stream. - void Print(const char* text) { - Print(text, strlen(text)); + --indent_level_; } // Print text to the output stream. void Print(const char* text, size_t size) { - size_t pos = 0; // The number of bytes we've written so far. - - for (size_t i = 0; i < size; i++) { - if (text[i] == '\n') { - // Saw newline. If there is more text, we may need to insert an indent - // here. So, write what we have so far, including the '\n'. - Write(text + pos, i - pos + 1); - pos = i + 1; - - // Setting this true will cause the next Write() to insert an indent - // first. + if (indent_level_ > 0) { + size_t pos = 0; // The number of bytes we've written so far. + for (size_t i = 0; i < size; i++) { + if (text[i] == '\n') { + // Saw newline. If there is more text, we may need to insert an + // indent here. So, write what we have so far, including the '\n'. + Write(text + pos, i - pos + 1); + pos = i + 1; + + // Setting this true will cause the next Write() to insert an indent + // first. + at_start_of_line_ = true; + } + } + // Write the rest. + Write(text + pos, size - pos); + } else { + Write(text, size); + if (text[size - 1] == '\n') { at_start_of_line_ = true; } } - - // Write the rest. - Write(text + pos, size - pos); } // True if any write to the underlying stream failed. (We don't just @@ -1234,7 +1237,7 @@ class TextFormat::Printer::TextGenerator { if (at_start_of_line_) { // Insert an indent. at_start_of_line_ = false; - Write(indent_.data(), indent_.size()); + WriteIndent(); if (failed_) return; } @@ -1256,13 +1259,35 @@ class TextFormat::Printer::TextGenerator { buffer_size_ -= size; } + void WriteIndent() { + if (indent_level_ == 0) { return; } + GOOGLE_DCHECK(!failed_); + int size = 2 * indent_level_; + + while (size > buffer_size_) { + // Data exceeds space in the buffer. Write what we can and request a new + // buffer. + memset(buffer_, ' ', buffer_size_); + size -= buffer_size_; + void* void_buffer; + failed_ = !output_->Next(&void_buffer, &buffer_size_); + if (failed_) return; + buffer_ = reinterpret_cast<char*>(void_buffer); + } + + // Buffer is big enough to receive the data; copy it. + memset(buffer_, ' ', size); + buffer_ += size; + buffer_size_ -= size; + } + io::ZeroCopyOutputStream* const output_; char* buffer_; int buffer_size_; bool at_start_of_line_; bool failed_; - string indent_; + int indent_level_; int initial_indent_level_; }; @@ -1380,90 +1405,274 @@ bool TextFormat::Parser::ParseFieldValueFromString( // =========================================================================== -// The default implementation for FieldValuePrinter. The base class just -// does simple formatting. That way, deriving classes could decide to fallback -// to that behavior. +TextFormat::BaseTextGenerator::~BaseTextGenerator() {} + +namespace { + +// A BaseTextGenerator that writes to a string. +class StringBaseTextGenerator : public TextFormat::BaseTextGenerator { + public: + void Print(const char* text, size_t size) { output_.append(text, size); } + +// Some compilers do not support ref-qualifiers even in C++11 mode. +// Disable the optimization for now and revisit it later. +#if 0 // LANG_CXX11 + string Consume() && { return std::move(output_); } +#else // !LANG_CXX11 + const string& Get() { return output_; } +#endif // LANG_CXX11 + + private: + string output_; +}; + +} // namespace + +// The default implementation for FieldValuePrinter. We just delegate the +// implementation to the default FastFieldValuePrinter to avoid duplicating the +// logic. TextFormat::FieldValuePrinter::FieldValuePrinter() {} TextFormat::FieldValuePrinter::~FieldValuePrinter() {} + +#if 0 // LANG_CXX11 +#define FORWARD_IMPL(fn, ...) \ + StringBaseTextGenerator generator; \ + delegate_.fn(__VA_ARGS__, &generator); \ + return std::move(generator).Consume() +#else // !LANG_CXX11 +#define FORWARD_IMPL(fn, ...) \ + StringBaseTextGenerator generator; \ + delegate_.fn(__VA_ARGS__, &generator); \ + return generator.Get() +#endif // LANG_CXX11 + string TextFormat::FieldValuePrinter::PrintBool(bool val) const { - return val ? "true" : "false"; + FORWARD_IMPL(PrintBool, val); } string TextFormat::FieldValuePrinter::PrintInt32(int32 val) const { - return SimpleItoa(val); + FORWARD_IMPL(PrintInt32, val); } string TextFormat::FieldValuePrinter::PrintUInt32(uint32 val) const { - return SimpleItoa(val); + FORWARD_IMPL(PrintUInt32, val); } string TextFormat::FieldValuePrinter::PrintInt64(int64 val) const { - return SimpleItoa(val); + FORWARD_IMPL(PrintInt64, val); } string TextFormat::FieldValuePrinter::PrintUInt64(uint64 val) const { - return SimpleItoa(val); + FORWARD_IMPL(PrintUInt64, val); } string TextFormat::FieldValuePrinter::PrintFloat(float val) const { - return SimpleFtoa(val); + FORWARD_IMPL(PrintFloat, val); } string TextFormat::FieldValuePrinter::PrintDouble(double val) const { - return SimpleDtoa(val); + FORWARD_IMPL(PrintDouble, val); } string TextFormat::FieldValuePrinter::PrintString(const string& val) const { - string printed("\""); - CEscapeAndAppend(val, &printed); - printed.push_back('\"'); - return printed; + FORWARD_IMPL(PrintString, val); } string TextFormat::FieldValuePrinter::PrintBytes(const string& val) const { return PrintString(val); } string TextFormat::FieldValuePrinter::PrintEnum(int32 val, const string& name) const { - return name; + FORWARD_IMPL(PrintEnum, val, name); } string TextFormat::FieldValuePrinter::PrintFieldName( const Message& message, const Reflection* reflection, const FieldDescriptor* field) const { - if (field->is_extension()) { - // We special-case MessageSet elements for compatibility with proto1. - if (field->containing_type()->options().message_set_wire_format() - && field->type() == FieldDescriptor::TYPE_MESSAGE - && field->is_optional() - && field->extension_scope() == field->message_type()) { - return StrCat("[", field->message_type()->full_name(), "]"); - } else { - return StrCat("[", field->full_name(), "]"); - } - } else if (field->type() == FieldDescriptor::TYPE_GROUP) { - // Groups must be serialized with their original capitalization. - return field->message_type()->name(); - } else { - return field->name(); - } + FORWARD_IMPL(PrintFieldName, message, reflection, field); } string TextFormat::FieldValuePrinter::PrintMessageStart( const Message& message, int field_index, int field_count, bool single_line_mode) const { - return single_line_mode ? " { " : " {\n"; + FORWARD_IMPL(PrintMessageStart, message, field_index, field_count, + single_line_mode); } string TextFormat::FieldValuePrinter::PrintMessageEnd( const Message& message, int field_index, int field_count, bool single_line_mode) const { - return single_line_mode ? "} " : "}\n"; + FORWARD_IMPL(PrintMessageEnd, message, field_index, field_count, + single_line_mode); +} +#undef FORWARD_IMPL + +TextFormat::FastFieldValuePrinter::FastFieldValuePrinter() {} +TextFormat::FastFieldValuePrinter::~FastFieldValuePrinter() {} +void TextFormat::FastFieldValuePrinter::PrintBool( + bool val, BaseTextGenerator* generator) const { + if (val) { + generator->PrintLiteral("true"); + } else { + generator->PrintLiteral("false"); + } +} +void TextFormat::FastFieldValuePrinter::PrintInt32( + int32 val, BaseTextGenerator* generator) const { + generator->PrintString(SimpleItoa(val)); +} +void TextFormat::FastFieldValuePrinter::PrintUInt32( + uint32 val, BaseTextGenerator* generator) const { + generator->PrintString(SimpleItoa(val)); +} +void TextFormat::FastFieldValuePrinter::PrintInt64( + int64 val, BaseTextGenerator* generator) const { + generator->PrintString(SimpleItoa(val)); +} +void TextFormat::FastFieldValuePrinter::PrintUInt64( + uint64 val, BaseTextGenerator* generator) const { + generator->PrintString(SimpleItoa(val)); +} +void TextFormat::FastFieldValuePrinter::PrintFloat( + float val, BaseTextGenerator* generator) const { + generator->PrintString(SimpleFtoa(val)); +} +void TextFormat::FastFieldValuePrinter::PrintDouble( + double val, BaseTextGenerator* generator) const { + generator->PrintString(SimpleDtoa(val)); +} +void TextFormat::FastFieldValuePrinter::PrintEnum( + int32 val, const string& name, BaseTextGenerator* generator) const { + generator->PrintString(name); +} + +void TextFormat::FastFieldValuePrinter::PrintString( + const string& val, BaseTextGenerator* generator) const { + generator->PrintLiteral("\""); + generator->PrintString(CEscape(val)); + generator->PrintLiteral("\""); +} +void TextFormat::FastFieldValuePrinter::PrintBytes( + const string& val, BaseTextGenerator* generator) const { + PrintString(val, generator); +} +void TextFormat::FastFieldValuePrinter::PrintFieldName( + const Message& message, const Reflection* reflection, + const FieldDescriptor* field, BaseTextGenerator* generator) const { + if (field->is_extension()) { + generator->PrintLiteral("["); + // We special-case MessageSet elements for compatibility with proto1. + if (field->containing_type()->options().message_set_wire_format() && + field->type() == FieldDescriptor::TYPE_MESSAGE && + field->is_optional() && + field->extension_scope() == field->message_type()) { + generator->PrintString(field->message_type()->full_name()); + } else { + generator->PrintString(field->full_name()); + } + generator->PrintLiteral("]"); + } else if (field->type() == FieldDescriptor::TYPE_GROUP) { + // Groups must be serialized with their original capitalization. + generator->PrintString(field->message_type()->name()); + } else { + generator->PrintString(field->name()); + } +} +void TextFormat::FastFieldValuePrinter::PrintMessageStart( + const Message& message, int field_index, int field_count, + bool single_line_mode, BaseTextGenerator* generator) const { + if (single_line_mode) { + generator->PrintLiteral(" { "); + } else { + generator->PrintLiteral(" {\n"); + } +} +void TextFormat::FastFieldValuePrinter::PrintMessageEnd( + const Message& message, int field_index, int field_count, + bool single_line_mode, BaseTextGenerator* generator) const { + if (single_line_mode) { + generator->PrintLiteral("} "); + } else { + generator->PrintLiteral("}\n"); + } } namespace { + +// A legacy compatibility wrapper. Takes ownership of the delegate. +class FieldValuePrinterWrapper : public TextFormat::FastFieldValuePrinter { + public: + explicit FieldValuePrinterWrapper( + const TextFormat::FieldValuePrinter* delegate) + : delegate_(delegate) {} + + void SetDelegate(const TextFormat::FieldValuePrinter* delegate) { + delegate_.reset(delegate); + } + + void PrintBool(bool val, TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintBool(val)); + } + void PrintInt32(int32 val, TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintInt32(val)); + } + void PrintUInt32(uint32 val, TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintUInt32(val)); + } + void PrintInt64(int64 val, TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintInt64(val)); + } + void PrintUInt64(uint64 val, TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintUInt64(val)); + } + void PrintFloat(float val, TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintFloat(val)); + } + void PrintDouble(double val, TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintDouble(val)); + } + void PrintString(const string& val, + TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintString(val)); + } + void PrintBytes(const string& val, + TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintBytes(val)); + } + void PrintEnum(int32 val, const string& name, + TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintEnum(val, name)); + } + void PrintFieldName(const Message& message, const Reflection* reflection, + const FieldDescriptor* field, + TextFormat::BaseTextGenerator* generator) const { + generator->PrintString( + delegate_->PrintFieldName(message, reflection, field)); + } + void PrintMessageStart(const Message& message, int field_index, + int field_count, bool single_line_mode, + TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintMessageStart( + message, field_index, field_count, single_line_mode)); + } + void PrintMessageEnd(const Message& message, int field_index, int field_count, + bool single_line_mode, + TextFormat::BaseTextGenerator* generator) const { + generator->PrintString(delegate_->PrintMessageEnd( + message, field_index, field_count, single_line_mode)); + } + + private: + google::protobuf::scoped_ptr<const TextFormat::FieldValuePrinter> delegate_; +}; + // Our own specialization: for UTF8 escaped strings. -class FieldValuePrinterUtf8Escaping : public TextFormat::FieldValuePrinter { +class FastFieldValuePrinterUtf8Escaping + : public TextFormat::FastFieldValuePrinter { public: - virtual string PrintString(const string& val) const { - return StrCat("\"", strings::Utf8SafeCEscape(val), "\""); + void PrintString(const string& val, + TextFormat::BaseTextGenerator* generator) const { + generator->PrintLiteral("\""); + generator->PrintString(strings::Utf8SafeCEscape(val)); + generator->PrintLiteral("\""); } - virtual string PrintBytes(const string& val) const { - return TextFormat::FieldValuePrinter::PrintString(val); + void PrintBytes(const string& val, + TextFormat::BaseTextGenerator* generator) const { + return FastFieldValuePrinter::PrintString(val, generator); } }; @@ -1486,19 +1695,39 @@ TextFormat::Printer::~Printer() { } void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) { - SetDefaultFieldValuePrinter(as_utf8 - ? new FieldValuePrinterUtf8Escaping() - : new FieldValuePrinter()); + SetDefaultFieldValuePrinter(as_utf8 ? new FastFieldValuePrinterUtf8Escaping() + : new FastFieldValuePrinter()); } void TextFormat::Printer::SetDefaultFieldValuePrinter( const FieldValuePrinter* printer) { + default_field_value_printer_.reset(new FieldValuePrinterWrapper(printer)); +} + +void TextFormat::Printer::SetDefaultFieldValuePrinter( + const FastFieldValuePrinter* printer) { default_field_value_printer_.reset(printer); } bool TextFormat::Printer::RegisterFieldValuePrinter( const FieldDescriptor* field, const FieldValuePrinter* printer) { + if (field == NULL || printer == NULL) { + return false; + } + FieldValuePrinterWrapper* const wrapper = + new FieldValuePrinterWrapper(NULL); + if (custom_printers_.insert(std::make_pair(field, wrapper)).second) { + wrapper->SetDelegate(printer); + return true; + } else { + delete wrapper; + return false; + } +} + +bool TextFormat::Printer::RegisterFieldValuePrinter( + const FieldDescriptor* field, const FastFieldValuePrinter* printer) { return field != NULL && printer != NULL && custom_printers_.insert(std::make_pair(field, printer)).second; } @@ -1527,7 +1756,7 @@ bool TextFormat::Printer::Print(const Message& message, io::ZeroCopyOutputStream* output) const { TextGenerator generator(output, initial_indent_level_); - Print(message, generator); + Print(message, &generator); // Output false if the generator failed internally. return !generator.failed(); @@ -1538,7 +1767,7 @@ bool TextFormat::Printer::PrintUnknownFields( io::ZeroCopyOutputStream* output) const { TextGenerator generator(output, initial_indent_level_); - PrintUnknownFields(unknown_fields, generator); + PrintUnknownFields(unknown_fields, &generator); // Output false if the generator failed internally. return !generator.failed(); @@ -1556,7 +1785,7 @@ struct FieldIndexSorter { } // namespace bool TextFormat::Printer::PrintAny(const Message& message, - TextGenerator& generator) const { + TextGenerator* generator) const { const FieldDescriptor* type_url_field; const FieldDescriptor* value_field; if (!internal::GetAnyFieldDescriptors(message, &type_url_field, @@ -1589,20 +1818,21 @@ bool TextFormat::Printer::PrintAny(const Message& message, GOOGLE_LOG(WARNING) << type_url << ": failed to parse contents"; return false; } - generator.Print(StrCat("[", type_url, "]")); - const FieldValuePrinter* printer = FindWithDefault( + generator->PrintLiteral("["); + generator->PrintString(type_url); + generator->PrintLiteral("]"); + const FastFieldValuePrinter* printer = FindWithDefault( custom_printers_, value_field, default_field_value_printer_.get()); - generator.Print( - printer->PrintMessageStart(message, -1, 0, single_line_mode_)); - generator.Indent(); + printer->PrintMessageStart(message, -1, 0, single_line_mode_, generator); + generator->Indent(); Print(*value_message, generator); - generator.Outdent(); - generator.Print(printer->PrintMessageEnd(message, -1, 0, single_line_mode_)); + generator->Outdent(); + printer->PrintMessageEnd(message, -1, 0, single_line_mode_, generator); return true; } void TextFormat::Printer::Print(const Message& message, - TextGenerator& generator) const { + TextGenerator* generator) const { const Descriptor* descriptor = message.GetDescriptor(); const Reflection* reflection = message.GetReflection(); if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ && @@ -1634,13 +1864,13 @@ void TextFormat::Printer::PrintFieldValueToString( io::StringOutputStream output_stream(output); TextGenerator generator(&output_stream, initial_indent_level_); - PrintFieldValue(message, message.GetReflection(), field, index, generator); + PrintFieldValue(message, message.GetReflection(), field, index, &generator); } void TextFormat::Printer::PrintField(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator) const { + TextGenerator* generator) const { if (use_short_repeated_primitives_ && field->is_repeated() && field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && @@ -1669,92 +1899,88 @@ void TextFormat::Printer::PrintField(const Message& message, PrintFieldName(message, reflection, field, generator); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - const FieldValuePrinter* printer = FindWithDefault( + const FastFieldValuePrinter* printer = FindWithDefault( custom_printers_, field, default_field_value_printer_.get()); const Message& sub_message = field->is_repeated() ? (is_map ? *map_entries[j] : reflection->GetRepeatedMessage(message, field, j)) : reflection->GetMessage(message, field); - generator.Print( - printer->PrintMessageStart( - sub_message, field_index, count, single_line_mode_)); - generator.Indent(); + printer->PrintMessageStart(sub_message, field_index, count, + single_line_mode_, generator); + generator->Indent(); Print(sub_message, generator); - generator.Outdent(); - generator.Print( - printer->PrintMessageEnd( - sub_message, field_index, count, single_line_mode_)); + generator->Outdent(); + printer->PrintMessageEnd(sub_message, field_index, count, + single_line_mode_, generator); } else { - generator.Print(": "); + generator->PrintLiteral(": "); // Write the field value. PrintFieldValue(message, reflection, field, field_index, generator); if (single_line_mode_) { - generator.Print(" "); + generator->PrintLiteral(" "); } else { - generator.Print("\n"); + generator->PrintLiteral("\n"); } } } } void TextFormat::Printer::PrintShortRepeatedField( - const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator) const { + const Message& message, const Reflection* reflection, + const FieldDescriptor* field, TextGenerator* generator) const { // Print primitive repeated field in short form. PrintFieldName(message, reflection, field, generator); int size = reflection->FieldSize(message, field); - generator.Print(": ["); + generator->PrintLiteral(": ["); for (int i = 0; i < size; i++) { - if (i > 0) generator.Print(", "); + if (i > 0) generator->PrintLiteral(", "); PrintFieldValue(message, reflection, field, i, generator); } if (single_line_mode_) { - generator.Print("] "); + generator->PrintLiteral("] "); } else { - generator.Print("]\n"); + generator->PrintLiteral("]\n"); } } void TextFormat::Printer::PrintFieldName(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator) const { + TextGenerator* generator) const { // if use_field_number_ is true, prints field number instead // of field name. if (use_field_number_) { - generator.Print(SimpleItoa(field->number())); + generator->PrintString(SimpleItoa(field->number())); return; } - const FieldValuePrinter* printer = FindWithDefault( + const FastFieldValuePrinter* printer = FindWithDefault( custom_printers_, field, default_field_value_printer_.get()); - generator.Print(printer->PrintFieldName(message, reflection, field)); + printer->PrintFieldName(message, reflection, field, generator); } -void TextFormat::Printer::PrintFieldValue( - const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - int index, - TextGenerator& generator) const { +void TextFormat::Printer::PrintFieldValue(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + int index, + TextGenerator* generator) const { GOOGLE_DCHECK(field->is_repeated() || (index == -1)) << "Index must be -1 for non-repeated fields"; - const FieldValuePrinter* printer - = FindWithDefault(custom_printers_, field, - default_field_value_printer_.get()); + const FastFieldValuePrinter* printer = FindWithDefault( + custom_printers_, field, default_field_value_printer_.get()); switch (field->cpp_type()) { -#define OUTPUT_FIELD(CPPTYPE, METHOD) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - generator.Print(printer->Print##METHOD(field->is_repeated() \ - ? reflection->GetRepeated##METHOD(message, field, index) \ - : reflection->Get##METHOD(message, field))); \ - break +#define OUTPUT_FIELD(CPPTYPE, METHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: \ + printer->Print##METHOD( \ + field->is_repeated() \ + ? reflection->GetRepeated##METHOD(message, field, index) \ + : reflection->Get##METHOD(message, field), \ + generator); \ + break OUTPUT_FIELD( INT32, Int32); OUTPUT_FIELD( INT64, Int64); @@ -1780,10 +2006,10 @@ void TextFormat::Printer::PrintFieldValue( value_to_print = &truncated_value; } if (field->type() == FieldDescriptor::TYPE_STRING) { - generator.Print(printer->PrintString(*value_to_print)); + printer->PrintString(*value_to_print, generator); } else { GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES); - generator.Print(printer->PrintBytes(*value_to_print)); + printer->PrintBytes(*value_to_print, generator); } break; } @@ -1795,7 +2021,7 @@ void TextFormat::Printer::PrintFieldValue( const EnumValueDescriptor* enum_desc = field->enum_type()->FindValueByNumber(enum_value); if (enum_desc != NULL) { - generator.Print(printer->PrintEnum(enum_value, enum_desc->name())); + printer->PrintEnum(enum_value, enum_desc->name(), generator); } else { // Ordinarily, enum_desc should not be null, because proto2 has the // invariant that set enum field values must be in-range, but with the @@ -1803,8 +2029,8 @@ void TextFormat::Printer::PrintFieldValue( // it is possible for the user to force an unknown integer value. So we // simply use the integer value itself as the enum value name in this // case. - generator.Print(printer->PrintEnum(enum_value, - StringPrintf("%d", enum_value))); + printer->PrintEnum(enum_value, StringPrintf("%d", enum_value), + generator); } break; } @@ -1867,90 +2093,93 @@ static string PaddedHex(IntType value) { } void TextFormat::Printer::PrintUnknownFields( - const UnknownFieldSet& unknown_fields, TextGenerator& generator) const { + const UnknownFieldSet& unknown_fields, TextGenerator* generator) const { for (int i = 0; i < unknown_fields.field_count(); i++) { const UnknownField& field = unknown_fields.field(i); string field_number = SimpleItoa(field.number()); switch (field.type()) { case UnknownField::TYPE_VARINT: - generator.Print(field_number); - generator.Print(": "); - generator.Print(SimpleItoa(field.varint())); + generator->PrintString(field_number); + generator->PrintLiteral(": "); + generator->PrintString(SimpleItoa(field.varint())); if (single_line_mode_) { - generator.Print(" "); + generator->PrintLiteral(" "); } else { - generator.Print("\n"); + generator->PrintLiteral("\n"); } break; case UnknownField::TYPE_FIXED32: { - generator.Print(field_number); - generator.Print(": 0x"); - generator.Print( + generator->PrintString(field_number); + generator->PrintLiteral(": 0x"); + generator->PrintString( StrCat(strings::Hex(field.fixed32(), strings::ZERO_PAD_8))); if (single_line_mode_) { - generator.Print(" "); + generator->PrintLiteral(" "); } else { - generator.Print("\n"); + generator->PrintLiteral("\n"); } break; } case UnknownField::TYPE_FIXED64: { - generator.Print(field_number); - generator.Print(": 0x"); - generator.Print( + generator->PrintString(field_number); + generator->PrintLiteral(": 0x"); + generator->PrintString( StrCat(strings::Hex(field.fixed64(), strings::ZERO_PAD_16))); if (single_line_mode_) { - generator.Print(" "); + generator->PrintLiteral(" "); } else { - generator.Print("\n"); + generator->PrintLiteral("\n"); } break; } case UnknownField::TYPE_LENGTH_DELIMITED: { - generator.Print(field_number); + generator->PrintString(field_number); const string& value = field.length_delimited(); UnknownFieldSet embedded_unknown_fields; if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) { // This field is parseable as a Message. // So it is probably an embedded message. if (single_line_mode_) { - generator.Print(" { "); + generator->PrintLiteral(" { "); } else { - generator.Print(" {\n"); - generator.Indent(); + generator->PrintLiteral(" {\n"); + generator->Indent(); } PrintUnknownFields(embedded_unknown_fields, generator); if (single_line_mode_) { - generator.Print("} "); + generator->PrintLiteral("} "); } else { - generator.Outdent(); - generator.Print("}\n"); + generator->Outdent(); + generator->PrintLiteral("}\n"); } } else { // This field is not parseable as a Message. // So it is probably just a plain string. - string printed(": \""); - CEscapeAndAppend(value, &printed); - printed.append(single_line_mode_ ? "\" " : "\"\n"); - generator.Print(printed); + generator->PrintLiteral(": \""); + generator->PrintString(CEscape(value)); + if (single_line_mode_) { + generator->PrintLiteral("\" "); + } else { + generator->PrintLiteral("\"\n"); + } } break; } case UnknownField::TYPE_GROUP: - generator.Print(field_number); + generator->PrintString(field_number); if (single_line_mode_) { - generator.Print(" { "); + generator->PrintLiteral(" { "); } else { - generator.Print(" {\n"); - generator.Indent(); + generator->PrintLiteral(" {\n"); + generator->Indent(); } PrintUnknownFields(field.group(), generator); if (single_line_mode_) { - generator.Print("} "); + generator->PrintLiteral("} "); } else { - generator.Outdent(); - generator.Print("}\n"); + generator->Outdent(); + generator->PrintLiteral("}\n"); } break; } diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index 560fd391..cd0e307e 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -65,21 +65,22 @@ namespace io { class LIBPROTOBUF_EXPORT TextFormat { public: // Outputs a textual representation of the given message to the given - // output stream. + // output stream. Returns false if printing fails. static bool Print(const Message& message, io::ZeroCopyOutputStream* output); // Print the fields in an UnknownFieldSet. They are printed by tag number // only. Embedded messages are heuristically identified by attempting to - // parse them. + // parse them. Returns false if printing fails. static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, io::ZeroCopyOutputStream* output); // Like Print(), but outputs directly to a string. // Note: output will be cleared prior to printing, and will be left empty - // even if printing fails. + // even if printing fails. Returns false if printing fails. static bool PrintToString(const Message& message, string* output); - // Like PrintUnknownFields(), but outputs directly to a string. + // Like PrintUnknownFields(), but outputs directly to a string. Returns false + // if printing fails. static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, string* output); @@ -92,11 +93,57 @@ class LIBPROTOBUF_EXPORT TextFormat { int index, string* output); - // The default printer that converts scalar values from fields into - // their string representation. - // You can derive from this FieldValuePrinter if you want to have - // fields to be printed in a different way and register it at the - // Printer. + class LIBPROTOBUF_EXPORT BaseTextGenerator { + public: + virtual ~BaseTextGenerator(); + // Print text to the output stream. + virtual void Print(const char* text, size_t size) = 0; + + void PrintString(const string& str) { Print(str.data(), str.size()); } + + template <size_t n> + void PrintLiteral(const char (&text)[n]) { + Print(text, n - 1); // n includes the terminating zero character. + } + }; + + // The default printer that converts scalar values from fields into their + // string representation. + // You can derive from this FastFieldValuePrinter if you want to have fields + // to be printed in a different way and register it at the Printer. + class LIBPROTOBUF_EXPORT FastFieldValuePrinter { + public: + FastFieldValuePrinter(); + virtual ~FastFieldValuePrinter(); + virtual void PrintBool(bool val, BaseTextGenerator* generator) const; + virtual void PrintInt32(int32 val, BaseTextGenerator* generator) const; + virtual void PrintUInt32(uint32 val, BaseTextGenerator* generator) const; + virtual void PrintInt64(int64 val, BaseTextGenerator* generator) const; + virtual void PrintUInt64(uint64 val, BaseTextGenerator* generator) const; + virtual void PrintFloat(float val, BaseTextGenerator* generator) const; + virtual void PrintDouble(double val, BaseTextGenerator* generator) const; + virtual void PrintString(const string& val, + BaseTextGenerator* generator) const; + virtual void PrintBytes(const string& val, + BaseTextGenerator* generator) const; + virtual void PrintEnum(int32 val, const string& name, + BaseTextGenerator* generator) const; + virtual void PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + BaseTextGenerator* generator) const; + virtual void PrintMessageStart(const Message& message, int field_index, + int field_count, bool single_line_mode, + BaseTextGenerator* generator) const; + virtual void PrintMessageEnd(const Message& message, int field_index, + int field_count, bool single_line_mode, + BaseTextGenerator* generator) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastFieldValuePrinter); + }; + +// DEPRECATED: Please use FastFieldValuePrinter. class LIBPROTOBUF_EXPORT FieldValuePrinter { public: FieldValuePrinter(); @@ -124,6 +171,7 @@ class LIBPROTOBUF_EXPORT TextFormat { bool single_line_mode) const; private: + FastFieldValuePrinter delegate_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter); }; @@ -183,12 +231,13 @@ class LIBPROTOBUF_EXPORT TextFormat { // Set true to output UTF-8 instead of ASCII. The only difference // is that bytes >= 0x80 in string fields will not be escaped, // because they are assumed to be part of UTF-8 multi-byte - // sequences. This will change the default FieldValuePrinter. + // sequences. This will change the default FastFieldValuePrinter. void SetUseUtf8StringEscaping(bool as_utf8); - // Set the default FieldValuePrinter that is used for all fields that + // Set the default (Fast)FieldValuePrinter that is used for all fields that // don't have a field-specific printer registered. // Takes ownership of the printer. + void SetDefaultFieldValuePrinter(const FastFieldValuePrinter* printer); void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer); // Sets whether we want to hide unknown fields or not. @@ -233,13 +282,15 @@ class LIBPROTOBUF_EXPORT TextFormat { truncate_string_field_longer_than_ = truncate_string_field_longer_than; } - // Register a custom field-specific FieldValuePrinter for fields + // Register a custom field-specific (Fast)FieldValuePrinter for fields // with a particular FieldDescriptor. // Returns "true" if the registration succeeded, or "false", if there is // already a printer for that FieldDescriptor. // Takes ownership of the printer on successful registration. bool RegisterFieldValuePrinter(const FieldDescriptor* field, const FieldValuePrinter* printer); + bool RegisterFieldValuePrinter(const FieldDescriptor* field, + const FastFieldValuePrinter* printer); private: // Forward declaration of an internal class used to print the text @@ -248,43 +299,38 @@ class LIBPROTOBUF_EXPORT TextFormat { // Internal Print method, used for writing to the OutputStream via // the TextGenerator class. - void Print(const Message& message, - TextGenerator& generator) const; + void Print(const Message& message, TextGenerator* generator) const; // Print a single field. - void PrintField(const Message& message, - const Reflection* reflection, + void PrintField(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator) const; + TextGenerator* generator) const; // Print a repeated primitive field in short form. void PrintShortRepeatedField(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator) const; + TextGenerator* generator) const; // Print the name of a field -- i.e. everything that comes before the // ':' for a single name/value pair. - void PrintFieldName(const Message& message, - const Reflection* reflection, + void PrintFieldName(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator) const; + TextGenerator* generator) const; // Outputs a textual representation of the value of the field supplied on // the message supplied or the default value if not set. - void PrintFieldValue(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - int index, - TextGenerator& generator) const; + void PrintFieldValue(const Message& message, const Reflection* reflection, + const FieldDescriptor* field, int index, + TextGenerator* generator) const; // Print the fields in an UnknownFieldSet. They are printed by tag number // only. Embedded messages are heuristically identified by attempting to // parse them. void PrintUnknownFields(const UnknownFieldSet& unknown_fields, - TextGenerator& generator) const; + TextGenerator* generator) const; - bool PrintAny(const Message& message, TextGenerator& generator) const; + bool PrintAny(const Message& message, TextGenerator* generator) const; int initial_indent_level_; @@ -302,9 +348,9 @@ class LIBPROTOBUF_EXPORT TextFormat { int64 truncate_string_field_longer_than_; - google::protobuf::scoped_ptr<const FieldValuePrinter> default_field_value_printer_; - typedef std::map<const FieldDescriptor*, - const FieldValuePrinter*> CustomPrinterMap; + google::protobuf::scoped_ptr<const FastFieldValuePrinter> default_field_value_printer_; + typedef std::map<const FieldDescriptor*, const FastFieldValuePrinter*> + CustomPrinterMap; CustomPrinterMap custom_printers_; }; diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 422a86b4..f823bcb2 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -53,6 +53,7 @@ #include <google/protobuf/unittest_mset_wire_format.pb.h> #include <google/protobuf/io/tokenizer.h> #include <google/protobuf/io/zero_copy_stream_impl.h> + #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> #include <google/protobuf/testing/googletest.h> @@ -454,13 +455,29 @@ TEST_F(TextFormatTest, FieldSpecificCustomPrinter) { EXPECT_EQ("optional_int32: value-is(42)\nrepeated_int32: 42\n", text); } +TEST_F(TextFormatTest, FieldSpecificCustomPrinterRegisterSameFieldTwice) { + protobuf_unittest::TestAllTypes message; + TextFormat::Printer printer; + const FieldDescriptor* const field = + message.GetDescriptor()->FindFieldByName("optional_int32"); + ASSERT_TRUE(printer.RegisterFieldValuePrinter( + field, new CustomInt32FieldValuePrinter())); + const TextFormat::FieldValuePrinter* const rejected = + new CustomInt32FieldValuePrinter(); + ASSERT_FALSE(printer.RegisterFieldValuePrinter(field, rejected)); + delete rejected; +} + TEST_F(TextFormatTest, ErrorCasesRegisteringFieldValuePrinterShouldFail) { protobuf_unittest::TestAllTypes message; TextFormat::Printer printer; // NULL printer. EXPECT_FALSE(printer.RegisterFieldValuePrinter( message.GetDescriptor()->FindFieldByName("optional_int32"), - NULL)); + static_cast<const TextFormat::FieldValuePrinter*>(NULL))); + EXPECT_FALSE(printer.RegisterFieldValuePrinter( + message.GetDescriptor()->FindFieldByName("optional_int32"), + static_cast<const TextFormat::FastFieldValuePrinter*>(NULL))); // Because registration fails, the ownership of this printer is never taken. TextFormat::FieldValuePrinter my_field_printer; // NULL field diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index 7c9d396e..44ddc749 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -19,7 +19,10 @@ namespace google { namespace protobuf { -class TimestampDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Timestamp> { +class TimestampDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Timestamp> + _instance; } _Timestamp_default_instance_; namespace protobuf_google_2fprotobuf_2ftimestamp_2eproto { @@ -32,20 +35,20 @@ namespace { } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::google::protobuf::internal::AuxillaryParseTableField(), }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const - TableStruct::schema[] = { - { NULL, NULL, 0, -1, -1, false }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, _internal_metadata_), ~0u, // no _extensions_ @@ -54,8 +57,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, seconds_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, nanos_), }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(Timestamp)}, }; @@ -85,18 +87,13 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _Timestamp_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); - _Timestamp_default_instance_.DefaultConstruct(); -} + _Timestamp_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Timestamp_default_instance_);} void InitDefaults() { static GOOGLE_PROTOBUF_DECLARE_ONCE(once); @@ -105,7 +102,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\037google/protobuf/timestamp.proto\022\017googl" "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003" "\022\r\n\005nanos\030\002 \001(\005B~\n\023com.google.protobufB\016" @@ -117,7 +114,6 @@ void AddDescriptorsImpl() { descriptor, 231); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/timestamp.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -183,6 +179,7 @@ Timestamp::~Timestamp() { void Timestamp::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -216,9 +213,14 @@ Timestamp* Timestamp::New(::google::protobuf::Arena* arena) const { void Timestamp::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Timestamp) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + ::memset(&seconds_, 0, static_cast<size_t>( reinterpret_cast<char*>(&nanos_) - reinterpret_cast<char*>(&seconds_)) + sizeof(nanos_)); + _internal_metadata_.Clear(); } bool Timestamp::MergePartialFromCodedStream( @@ -234,7 +236,7 @@ bool Timestamp::MergePartialFromCodedStream( // int64 seconds = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( @@ -248,7 +250,7 @@ bool Timestamp::MergePartialFromCodedStream( // int32 nanos = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -261,12 +263,11 @@ bool Timestamp::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -296,6 +297,10 @@ void Timestamp::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->nanos(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Timestamp) } @@ -316,6 +321,10 @@ void Timestamp::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->nanos(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Timestamp) return target; } @@ -324,6 +333,11 @@ size_t Timestamp::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Timestamp) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // int64 seconds = 1; if (this->seconds() != 0) { total_size += 1 + @@ -413,9 +427,11 @@ void Timestamp::UnsafeArenaSwap(Timestamp* other) { InternalSwap(other); } void Timestamp::InternalSwap(Timestamp* other) { - std::swap(seconds_, other->seconds_); - std::swap(nanos_, other->nanos_); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(seconds_, other->seconds_); + swap(nanos_, other->nanos_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Timestamp::GetMetadata() const { diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index 9ce2c96a..61596ed4 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -48,8 +48,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -68,7 +69,21 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@pro CopyFrom(from); return *this; } + #if LANG_CXX11 + Timestamp(Timestamp&& from) noexcept + : Timestamp() { + *this = ::std::move(from); + } + inline Timestamp& operator=(Timestamp&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -87,6 +102,9 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@pro void UnsafeArenaSwap(Timestamp* other); void Swap(Timestamp* other); + friend void swap(Timestamp& a, Timestamp& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -149,7 +167,7 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@pro private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::int64 seconds_; @@ -163,6 +181,10 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@pro // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // Timestamp // int64 seconds = 1; @@ -193,6 +215,9 @@ inline void Timestamp::set_nanos(::google::protobuf::int32 value) { // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.nanos) } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // @@protoc_insertion_point(namespace_scope) diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index fe422087..abb52395 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -19,15 +19,30 @@ namespace google { namespace protobuf { -class TypeDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Type> { +class TypeDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Type> + _instance; } _Type_default_instance_; -class FieldDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Field> { +class FieldDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Field> + _instance; } _Field_default_instance_; -class EnumDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Enum> { +class EnumDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Enum> + _instance; } _Enum_default_instance_; -class EnumValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<EnumValue> { +class EnumValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<EnumValue> + _instance; } _EnumValue_default_instance_; -class OptionDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Option> { +class OptionDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Option> + _instance; } _Option_default_instance_; namespace protobuf_google_2fprotobuf_2ftype_2eproto { @@ -41,24 +56,24 @@ const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[3]; } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::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 }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _internal_metadata_), ~0u, // no _extensions_ @@ -111,8 +126,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, value_), }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(Type)}, { 11, -1, sizeof(Field)}, { 26, -1, sizeof(Enum)}, @@ -150,36 +164,27 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _Type_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; - _Field_default_instance_.Shutdown(); - delete file_level_metadata[1].reflection; - _Enum_default_instance_.Shutdown(); - delete file_level_metadata[2].reflection; - _EnumValue_default_instance_.Shutdown(); - delete file_level_metadata[3].reflection; - _Option_default_instance_.Shutdown(); - delete file_level_metadata[4].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); ::google::protobuf::protobuf_google_2fprotobuf_2fany_2eproto::InitDefaults(); ::google::protobuf::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::InitDefaults(); - _Type_default_instance_.DefaultConstruct(); - _Field_default_instance_.DefaultConstruct(); - _Enum_default_instance_.DefaultConstruct(); - _EnumValue_default_instance_.DefaultConstruct(); - _Option_default_instance_.DefaultConstruct(); - _Type_default_instance_.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>( + _Type_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Type_default_instance_);_Field_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Field_default_instance_);_Enum_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Enum_default_instance_);_EnumValue_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_EnumValue_default_instance_);_Option_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Option_default_instance_);_Type_default_instance_._instance.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>( ::google::protobuf::SourceContext::internal_default_instance()); - _Enum_default_instance_.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>( + _Enum_default_instance_._instance.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>( ::google::protobuf::SourceContext::internal_default_instance()); - _Option_default_instance_.get_mutable()->value_ = const_cast< ::google::protobuf::Any*>( + _Option_default_instance_._instance.get_mutable()->value_ = const_cast< ::google::protobuf::Any*>( ::google::protobuf::Any::internal_default_instance()); } @@ -190,7 +195,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\032google/protobuf/type.proto\022\017google.pro" "tobuf\032\031google/protobuf/any.proto\032$google" "/protobuf/source_context.proto\"\327\001\n\004Type\022" @@ -238,7 +243,6 @@ void AddDescriptorsImpl() { "google/protobuf/type.proto", &protobuf_RegisterTypes); ::google::protobuf::protobuf_google_2fprotobuf_2fany_2eproto::AddDescriptors(); ::google::protobuf::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::AddDescriptors(); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -450,14 +454,13 @@ Type::~Type() { void Type::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena); - if (this != internal_default_instance()) { - delete source_context_; - } + if (this != internal_default_instance()) delete source_context_; } void Type::ArenaDtor(void* object) { @@ -487,6 +490,10 @@ Type* Type::New(::google::protobuf::Arena* arena) const { void Type::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Type) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + fields_.Clear(); oneofs_.Clear(); options_.Clear(); @@ -496,6 +503,7 @@ void Type::Clear() { } source_context_ = NULL; syntax_ = 0; + _internal_metadata_.Clear(); } bool Type::MergePartialFromCodedStream( @@ -511,7 +519,7 @@ bool Type::MergePartialFromCodedStream( // string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -527,7 +535,7 @@ bool Type::MergePartialFromCodedStream( // repeated .google.protobuf.Field fields = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_fields())); } else { @@ -539,7 +547,7 @@ bool Type::MergePartialFromCodedStream( // repeated string oneofs = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->add_oneofs())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -556,7 +564,7 @@ bool Type::MergePartialFromCodedStream( // repeated .google.protobuf.Option options = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { @@ -568,7 +576,7 @@ bool Type::MergePartialFromCodedStream( // .google.protobuf.SourceContext source_context = 5; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(42u)) { + static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_source_context())); } else { @@ -580,7 +588,7 @@ bool Type::MergePartialFromCodedStream( // .google.protobuf.Syntax syntax = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(48u)) { + static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -594,12 +602,11 @@ bool Type::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -665,6 +672,10 @@ void Type::SerializeWithCachedSizes( 6, this->syntax(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Type) } @@ -725,6 +736,10 @@ void Type::SerializeWithCachedSizes( 6, this->syntax(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type) return target; } @@ -733,6 +748,11 @@ size_t Type::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Type) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // repeated .google.protobuf.Field fields = 2; { unsigned int count = static_cast<unsigned int>(this->fields_size()); @@ -864,13 +884,15 @@ void Type::UnsafeArenaSwap(Type* other) { InternalSwap(other); } void Type::InternalSwap(Type* other) { + using std::swap; 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_); - std::swap(_cached_size_, other->_cached_size_); + swap(source_context_, other->source_context_); + swap(syntax_, other->syntax_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Type::GetMetadata() const { @@ -894,6 +916,14 @@ void Type::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Type.name) } +#if LANG_CXX11 +void Type::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Type.name) +} +#endif void Type::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1086,9 +1116,10 @@ void Type::clear_source_context() { source_context_ = NULL; } const ::google::protobuf::SourceContext& Type::source_context() const { + const ::google::protobuf::SourceContext* p = source_context_; // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context) - return source_context_ != NULL ? *source_context_ - : *::google::protobuf::SourceContext::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::SourceContext*>( + &::google::protobuf::_SourceContext_default_instance_); } ::google::protobuf::SourceContext* Type::mutable_source_context() { @@ -1226,6 +1257,7 @@ Field::~Field() { void Field::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -1263,6 +1295,10 @@ Field* Field::New(::google::protobuf::Arena* arena) const { void Field::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Field) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + options_.Clear(); name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); type_url_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); @@ -1271,6 +1307,7 @@ void Field::Clear() { ::memset(&kind_, 0, static_cast<size_t>( reinterpret_cast<char*>(&packed_) - reinterpret_cast<char*>(&kind_)) + sizeof(packed_)); + _internal_metadata_.Clear(); } bool Field::MergePartialFromCodedStream( @@ -1286,7 +1323,7 @@ bool Field::MergePartialFromCodedStream( // .google.protobuf.Field.Kind kind = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -1301,7 +1338,7 @@ bool Field::MergePartialFromCodedStream( // .google.protobuf.Field.Cardinality cardinality = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -1316,7 +1353,7 @@ bool Field::MergePartialFromCodedStream( // int32 number = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { + static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -1330,7 +1367,7 @@ bool Field::MergePartialFromCodedStream( // string name = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1346,7 +1383,7 @@ bool Field::MergePartialFromCodedStream( // string type_url = 6; case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(50u)) { + static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_type_url())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1362,7 +1399,7 @@ bool Field::MergePartialFromCodedStream( // int32 oneof_index = 7; case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(56u)) { + static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -1376,7 +1413,7 @@ bool Field::MergePartialFromCodedStream( // bool packed = 8; case 8: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(64u)) { + static_cast< ::google::protobuf::uint8>(64u /* 64 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -1390,7 +1427,7 @@ bool Field::MergePartialFromCodedStream( // repeated .google.protobuf.Option options = 9; case 9: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(74u)) { + static_cast< ::google::protobuf::uint8>(74u /* 74 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { @@ -1402,7 +1439,7 @@ bool Field::MergePartialFromCodedStream( // string json_name = 10; case 10: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(82u)) { + static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_json_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1418,7 +1455,7 @@ bool Field::MergePartialFromCodedStream( // string default_value = 11; case 11: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(90u)) { + static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_default_value())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1433,12 +1470,11 @@ bool Field::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1532,6 +1568,10 @@ void Field::SerializeWithCachedSizes( 11, this->default_value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Field) } @@ -1621,6 +1661,10 @@ void Field::SerializeWithCachedSizes( 11, this->default_value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field) return target; } @@ -1629,6 +1673,11 @@ size_t Field::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Field) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // repeated .google.protobuf.Option options = 9; { unsigned int count = static_cast<unsigned int>(this->options_size()); @@ -1796,17 +1845,19 @@ void Field::UnsafeArenaSwap(Field* other) { InternalSwap(other); } void Field::InternalSwap(Field* other) { + using std::swap; options_.InternalSwap(&other->options_); name_.Swap(&other->name_); type_url_.Swap(&other->type_url_); json_name_.Swap(&other->json_name_); default_value_.Swap(&other->default_value_); - std::swap(kind_, other->kind_); - std::swap(cardinality_, other->cardinality_); - std::swap(number_, other->number_); - std::swap(oneof_index_, other->oneof_index_); - std::swap(packed_, other->packed_); - std::swap(_cached_size_, other->_cached_size_); + swap(kind_, other->kind_); + swap(cardinality_, other->cardinality_); + swap(number_, other->number_); + swap(oneof_index_, other->oneof_index_); + swap(packed_, other->packed_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Field::GetMetadata() const { @@ -1872,6 +1923,14 @@ void Field::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Field.name) } +#if LANG_CXX11 +void Field::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.name) +} +#endif void Field::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1939,6 +1998,14 @@ void Field::set_type_url(const ::std::string& value) { type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url) } +#if LANG_CXX11 +void Field::set_type_url(::std::string&& value) { + + type_url_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.type_url) +} +#endif void Field::set_type_url(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -2064,6 +2131,14 @@ void Field::set_json_name(const ::std::string& value) { json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name) } +#if LANG_CXX11 +void Field::set_json_name(::std::string&& value) { + + json_name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.json_name) +} +#endif void Field::set_json_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -2131,6 +2206,14 @@ void Field::set_default_value(const ::std::string& value) { default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value) } +#if LANG_CXX11 +void Field::set_default_value(::std::string&& value) { + + default_value_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.default_value) +} +#endif void Field::set_default_value(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -2284,14 +2367,13 @@ Enum::~Enum() { void Enum::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena); - if (this != internal_default_instance()) { - delete source_context_; - } + if (this != internal_default_instance()) delete source_context_; } void Enum::ArenaDtor(void* object) { @@ -2321,6 +2403,10 @@ Enum* Enum::New(::google::protobuf::Arena* arena) const { void Enum::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Enum) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + enumvalue_.Clear(); options_.Clear(); name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); @@ -2329,6 +2415,7 @@ void Enum::Clear() { } source_context_ = NULL; syntax_ = 0; + _internal_metadata_.Clear(); } bool Enum::MergePartialFromCodedStream( @@ -2344,7 +2431,7 @@ bool Enum::MergePartialFromCodedStream( // string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -2360,7 +2447,7 @@ bool Enum::MergePartialFromCodedStream( // repeated .google.protobuf.EnumValue enumvalue = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_enumvalue())); } else { @@ -2372,7 +2459,7 @@ bool Enum::MergePartialFromCodedStream( // repeated .google.protobuf.Option options = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { @@ -2384,7 +2471,7 @@ bool Enum::MergePartialFromCodedStream( // .google.protobuf.SourceContext source_context = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_source_context())); } else { @@ -2396,7 +2483,7 @@ bool Enum::MergePartialFromCodedStream( // .google.protobuf.Syntax syntax = 5; case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(40u)) { + static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( @@ -2410,12 +2497,11 @@ bool Enum::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -2471,6 +2557,10 @@ void Enum::SerializeWithCachedSizes( 5, this->syntax(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Enum) } @@ -2521,6 +2611,10 @@ void Enum::SerializeWithCachedSizes( 5, this->syntax(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum) return target; } @@ -2529,6 +2623,11 @@ size_t Enum::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Enum) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // repeated .google.protobuf.EnumValue enumvalue = 2; { unsigned int count = static_cast<unsigned int>(this->enumvalue_size()); @@ -2651,12 +2750,14 @@ void Enum::UnsafeArenaSwap(Enum* other) { InternalSwap(other); } void Enum::InternalSwap(Enum* other) { + using std::swap; enumvalue_.InternalSwap(&other->enumvalue_); options_.InternalSwap(&other->options_); name_.Swap(&other->name_); - std::swap(source_context_, other->source_context_); - std::swap(syntax_, other->syntax_); - std::swap(_cached_size_, other->_cached_size_); + swap(source_context_, other->source_context_); + swap(syntax_, other->syntax_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Enum::GetMetadata() const { @@ -2680,6 +2781,14 @@ void Enum::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Enum.name) } +#if LANG_CXX11 +void Enum::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Enum.name) +} +#endif void Enum::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -2803,9 +2912,10 @@ void Enum::clear_source_context() { source_context_ = NULL; } const ::google::protobuf::SourceContext& Enum::source_context() const { + const ::google::protobuf::SourceContext* p = source_context_; // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context) - return source_context_ != NULL ? *source_context_ - : *::google::protobuf::SourceContext::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::SourceContext*>( + &::google::protobuf::_SourceContext_default_instance_); } ::google::protobuf::SourceContext* Enum::mutable_source_context() { @@ -2914,6 +3024,7 @@ EnumValue::~EnumValue() { void EnumValue::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -2948,9 +3059,14 @@ EnumValue* EnumValue::New(::google::protobuf::Arena* arena) const { void EnumValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValue) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + options_.Clear(); name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); number_ = 0; + _internal_metadata_.Clear(); } bool EnumValue::MergePartialFromCodedStream( @@ -2966,7 +3082,7 @@ bool EnumValue::MergePartialFromCodedStream( // string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -2982,7 +3098,7 @@ bool EnumValue::MergePartialFromCodedStream( // int32 number = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -2996,7 +3112,7 @@ bool EnumValue::MergePartialFromCodedStream( // repeated .google.protobuf.Option options = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { @@ -3007,12 +3123,11 @@ bool EnumValue::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -3054,6 +3169,10 @@ void EnumValue::SerializeWithCachedSizes( 3, this->options(static_cast<int>(i)), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValue) } @@ -3088,6 +3207,10 @@ void EnumValue::SerializeWithCachedSizes( 3, this->options(static_cast<int>(i)), deterministic, target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue) return target; } @@ -3096,6 +3219,11 @@ size_t EnumValue::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValue) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // repeated .google.protobuf.Option options = 3; { unsigned int count = static_cast<unsigned int>(this->options_size()); @@ -3197,10 +3325,12 @@ void EnumValue::UnsafeArenaSwap(EnumValue* other) { InternalSwap(other); } void EnumValue::InternalSwap(EnumValue* other) { + using std::swap; options_.InternalSwap(&other->options_); name_.Swap(&other->name_); - std::swap(number_, other->number_); - std::swap(_cached_size_, other->_cached_size_); + swap(number_, other->number_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata EnumValue::GetMetadata() const { @@ -3224,6 +3354,14 @@ void EnumValue::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name) } +#if LANG_CXX11 +void EnumValue::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumValue.name) +} +#endif void EnumValue::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -3411,14 +3549,13 @@ Option::~Option() { void Option::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena); - if (this != internal_default_instance()) { - delete value_; - } + if (this != internal_default_instance()) delete value_; } void Option::ArenaDtor(void* object) { @@ -3448,11 +3585,16 @@ Option* Option::New(::google::protobuf::Arena* arena) const { void Option::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Option) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); if (GetArenaNoVirtual() == NULL && value_ != NULL) { delete value_; } value_ = NULL; + _internal_metadata_.Clear(); } bool Option::MergePartialFromCodedStream( @@ -3468,7 +3610,7 @@ bool Option::MergePartialFromCodedStream( // string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -3484,7 +3626,7 @@ bool Option::MergePartialFromCodedStream( // .google.protobuf.Any value = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_value())); } else { @@ -3495,12 +3637,11 @@ bool Option::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -3536,6 +3677,10 @@ void Option::SerializeWithCachedSizes( 2, *this->value_, output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Option) } @@ -3564,6 +3709,10 @@ void Option::SerializeWithCachedSizes( 2, *this->value_, deterministic, target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option) return target; } @@ -3572,6 +3721,11 @@ size_t Option::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Option) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // string name = 1; if (this->name().size() > 0) { total_size += 1 + @@ -3661,9 +3815,11 @@ void Option::UnsafeArenaSwap(Option* other) { InternalSwap(other); } void Option::InternalSwap(Option* other) { + using std::swap; name_.Swap(&other->name_); - std::swap(value_, other->value_); - std::swap(_cached_size_, other->_cached_size_); + swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Option::GetMetadata() const { @@ -3687,6 +3843,14 @@ void Option::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Option.name) } +#if LANG_CXX11 +void Option::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Option.name) +} +#endif void Option::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -3750,9 +3914,10 @@ void Option::clear_value() { value_ = NULL; } const ::google::protobuf::Any& Option::value() const { + const ::google::protobuf::Any* p = value_; // @@protoc_insertion_point(field_get:google.protobuf.Option.value) - return value_ != NULL ? *value_ - : *::google::protobuf::Any::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::Any*>( + &::google::protobuf::_Any_default_instance_); } ::google::protobuf::Any* Option::mutable_value() { diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index 1138988d..cc76cc97 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -63,8 +63,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -165,7 +166,21 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_i CopyFrom(from); return *this; } + #if LANG_CXX11 + Type(Type&& from) noexcept + : Type() { + *this = ::std::move(from); + } + inline Type& operator=(Type&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -184,6 +199,9 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_i void UnsafeArenaSwap(Type* other); void Swap(Type* other); + friend void swap(Type& a, Type& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -281,6 +299,9 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_i 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(); @@ -316,7 +337,7 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_i private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field > fields_; @@ -341,7 +362,21 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ CopyFrom(from); return *this; } + #if LANG_CXX11 + Field(Field&& from) noexcept + : Field() { + *this = ::std::move(from); + } + inline Field& operator=(Field&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -360,6 +395,9 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ void UnsafeArenaSwap(Field* other); void Swap(Field* other); + friend void swap(Field& a, Field& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -513,6 +551,9 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ static const int kNameFieldNumber = 4; 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(); @@ -527,6 +568,9 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ static const int kTypeUrlFieldNumber = 6; const ::std::string& type_url() const; void set_type_url(const ::std::string& value); + #if LANG_CXX11 + void set_type_url(::std::string&& value); + #endif void set_type_url(const char* value); void set_type_url(const char* value, size_t size); ::std::string* mutable_type_url(); @@ -541,6 +585,9 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ static const int kJsonNameFieldNumber = 10; const ::std::string& json_name() const; void set_json_name(const ::std::string& value); + #if LANG_CXX11 + void set_json_name(::std::string&& value); + #endif void set_json_name(const char* value); void set_json_name(const char* value, size_t size); ::std::string* mutable_json_name(); @@ -555,6 +602,9 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ static const int kDefaultValueFieldNumber = 11; const ::std::string& default_value() const; void set_default_value(const ::std::string& value); + #if LANG_CXX11 + void set_default_value(::std::string&& value); + #endif void set_default_value(const char* value); void set_default_value(const char* value, size_t size); ::std::string* mutable_default_value(); @@ -598,7 +648,7 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; @@ -627,7 +677,21 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_i CopyFrom(from); return *this; } + #if LANG_CXX11 + Enum(Enum&& from) noexcept + : Enum() { + *this = ::std::move(from); + } + inline Enum& operator=(Enum&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -646,6 +710,9 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_i void UnsafeArenaSwap(Enum* other); void Swap(Enum* other); + friend void swap(Enum& a, Enum& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -721,6 +788,9 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_i 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(); @@ -756,7 +826,7 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_i private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue > enumvalue_; @@ -780,7 +850,21 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@pro CopyFrom(from); return *this; } + #if LANG_CXX11 + EnumValue(EnumValue&& from) noexcept + : EnumValue() { + *this = ::std::move(from); + } + inline EnumValue& operator=(EnumValue&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -799,6 +883,9 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@pro void UnsafeArenaSwap(EnumValue* other); void Swap(EnumValue* other); + friend void swap(EnumValue& a, EnumValue& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -862,6 +949,9 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@pro 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(); @@ -881,7 +971,7 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@pro private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; @@ -903,7 +993,21 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc CopyFrom(from); return *this; } + #if LANG_CXX11 + Option(Option&& from) noexcept + : Option() { + *this = ::std::move(from); + } + inline Option& operator=(Option&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -922,6 +1026,9 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc void UnsafeArenaSwap(Option* other); void Swap(Option* other); + friend void swap(Option& a, Option& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -973,6 +1080,9 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc 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(); @@ -1002,7 +1112,7 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::internal::ArenaStringPtr name_; @@ -1016,6 +1126,10 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // Type // string name = 1; @@ -1031,6 +1145,14 @@ inline void Type::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Type.name) } +#if LANG_CXX11 +inline void Type::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Type.name) +} +#endif inline void Type::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1223,9 +1345,10 @@ inline void Type::clear_source_context() { source_context_ = NULL; } inline const ::google::protobuf::SourceContext& Type::source_context() const { + const ::google::protobuf::SourceContext* p = source_context_; // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context) - return source_context_ != NULL ? *source_context_ - : *::google::protobuf::SourceContext::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::SourceContext*>( + &::google::protobuf::_SourceContext_default_instance_); } inline ::google::protobuf::SourceContext* Type::mutable_source_context() { @@ -1338,6 +1461,14 @@ inline void Field::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Field.name) } +#if LANG_CXX11 +inline void Field::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.name) +} +#endif inline void Field::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1405,6 +1536,14 @@ inline void Field::set_type_url(const ::std::string& value) { type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url) } +#if LANG_CXX11 +inline void Field::set_type_url(::std::string&& value) { + + type_url_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.type_url) +} +#endif inline void Field::set_type_url(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1530,6 +1669,14 @@ inline void Field::set_json_name(const ::std::string& value) { json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name) } +#if LANG_CXX11 +inline void Field::set_json_name(::std::string&& value) { + + json_name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.json_name) +} +#endif inline void Field::set_json_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1597,6 +1744,14 @@ inline void Field::set_default_value(const ::std::string& value) { default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value) } +#if LANG_CXX11 +inline void Field::set_default_value(::std::string&& value) { + + default_value_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.default_value) +} +#endif inline void Field::set_default_value(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1668,6 +1823,14 @@ inline void Enum::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Enum.name) } +#if LANG_CXX11 +inline void Enum::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Enum.name) +} +#endif inline void Enum::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1791,9 +1954,10 @@ inline void Enum::clear_source_context() { source_context_ = NULL; } inline const ::google::protobuf::SourceContext& Enum::source_context() const { + const ::google::protobuf::SourceContext* p = source_context_; // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context) - return source_context_ != NULL ? *source_context_ - : *::google::protobuf::SourceContext::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::SourceContext*>( + &::google::protobuf::_SourceContext_default_instance_); } inline ::google::protobuf::SourceContext* Enum::mutable_source_context() { @@ -1864,6 +2028,14 @@ inline void EnumValue::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name) } +#if LANG_CXX11 +inline void EnumValue::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumValue.name) +} +#endif inline void EnumValue::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1979,6 +2151,14 @@ inline void Option::set_name(const ::std::string& value) { name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.Option.name) } +#if LANG_CXX11 +inline void Option::set_name(::std::string&& value) { + + name_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Option.name) +} +#endif inline void Option::set_name(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -2042,9 +2222,10 @@ inline void Option::clear_value() { value_ = NULL; } inline const ::google::protobuf::Any& Option::value() const { + const ::google::protobuf::Any* p = value_; // @@protoc_insertion_point(field_get:google.protobuf.Option.value) - return value_ != NULL ? *value_ - : *::google::protobuf::Any::internal_default_instance(); + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::Any*>( + &::google::protobuf::_Any_default_instance_); } inline ::google::protobuf::Any* Option::mutable_value() { @@ -2084,6 +2265,9 @@ inline void Option::set_allocated_value(::google::protobuf::Any* value) { // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.value) } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // ------------------------------------------------------------------- @@ -2100,7 +2284,6 @@ inline void Option::set_allocated_value(::google::protobuf::Any* value) { } // namespace protobuf } // namespace google -#ifndef SWIG namespace google { namespace protobuf { @@ -2122,7 +2305,6 @@ inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Syntax>() { } // namespace protobuf } // namespace google -#endif // SWIG // @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto index 2040487e..45a0edad 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto @@ -397,6 +397,12 @@ message TestRequiredForeign { optional int32 dummy = 3; } +message TestRequiredMessage { + optional TestRequired optional_message = 1; + repeated TestRequired repeated_message = 2; + required TestRequired required_message = 3; +} + // Test that we can use NestedMessage from outside TestAllTypes. message TestForeignNested { optional TestAllTypes.NestedMessage foreign_nested = 1; diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto index c39ac6b0..9a15bdaa 100644 --- a/src/google/protobuf/unittest_lite.proto +++ b/src/google/protobuf/unittest_lite.proto @@ -439,3 +439,18 @@ message TestHugeFieldNumbersLite { extend TestHugeFieldNumbersLite { optional TestAllTypesLite test_all_types_lite = 536860000; } + +message TestOneofParsingLite { + oneof oneof_field { + int32 oneof_int32 = 1; + TestAllTypesLite oneof_submessage = 2; + string oneof_string = 3; + bytes oneof_bytes = 4 [default = "default bytes"]; + string oneof_string_cord = 5 [ctype = CORD, default = "default Cord"]; + bytes oneof_bytes_cord = 6 [ctype = CORD]; + string oneof_string_string_piece = 7 [ctype = STRING_PIECE]; + bytes oneof_bytes_string_piece = 8 + [ctype = STRING_PIECE, default = "default StringPiece"]; + V2EnumLite oneof_enum = 9; + } +} diff --git a/src/google/protobuf/unittest_proto3.proto b/src/google/protobuf/unittest_proto3.proto index a27b1b26..84815d42 100644 --- a/src/google/protobuf/unittest_proto3.proto +++ b/src/google/protobuf/unittest_proto3.proto @@ -28,35 +28,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file we will use for unit testing. - syntax = "proto3"; -// 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; -option csharp_namespace = "Google.Protobuf.TestProtos"; - -import "google/protobuf/unittest_import_proto3.proto"; - -// We don't put this in a package within proto2 because we need to make sure -// that the generated code doesn't depend on being in the proto2 namespace. -// In test_util.h we do "using namespace unittest = protobuf_unittest". -package protobuf_unittest; - -// 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 = "UnittestProto"; +import "google/protobuf/unittest_import.proto"; + +package proto3_unittest; // This proto includes every type of field in both singular and repeated // forms. @@ -69,7 +47,7 @@ message TestAllTypes { } enum NestedEnum { - NESTED_ENUM_UNSPECIFIED = 0; + ZERO = 0; FOO = 1; BAR = 2; BAZ = 3; @@ -77,33 +55,49 @@ message TestAllTypes { } // Singular - int32 single_int32 = 1; - int64 single_int64 = 2; - uint32 single_uint32 = 3; - uint64 single_uint64 = 4; - sint32 single_sint32 = 5; - sint64 single_sint64 = 6; - fixed32 single_fixed32 = 7; - fixed64 single_fixed64 = 8; - sfixed32 single_sfixed32 = 9; - sfixed64 single_sfixed64 = 10; - float single_float = 11; - double single_double = 12; - bool single_bool = 13; - string single_string = 14; - bytes single_bytes = 15; - - NestedMessage single_nested_message = 18; - ForeignMessage single_foreign_message = 19; - protobuf_unittest_import.ImportMessage single_import_message = 20; - - NestedEnum single_nested_enum = 21; - ForeignEnum single_foreign_enum = 22; - protobuf_unittest_import.ImportEnum single_import_enum = 23; + int32 optional_int32 = 1; + int64 optional_int64 = 2; + uint32 optional_uint32 = 3; + uint64 optional_uint64 = 4; + sint32 optional_sint32 = 5; + sint64 optional_sint64 = 6; + fixed32 optional_fixed32 = 7; + fixed64 optional_fixed64 = 8; + sfixed32 optional_sfixed32 = 9; + sfixed64 optional_sfixed64 = 10; + float optional_float = 11; + double optional_double = 12; + bool optional_bool = 13; + string optional_string = 14; + bytes optional_bytes = 15; + + // Groups are not allowed in proto3. + // optional group OptionalGroup = 16 { + // optional int32 a = 17; + // } + + NestedMessage optional_nested_message = 18; + ForeignMessage optional_foreign_message = 19; + protobuf_unittest_import.ImportMessage optional_import_message = 20; + + NestedEnum optional_nested_enum = 21; + ForeignEnum optional_foreign_enum = 22; + + // Omitted (compared to unittest.proto) because proto2 enums are not allowed + // inside proto2 messages. + // + // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; + + string optional_string_piece = 24 [ctype=STRING_PIECE]; + string optional_cord = 25 [ctype=CORD]; // Defined in unittest_import_public.proto protobuf_unittest_import.PublicImportMessage - single_public_import_message = 26; + 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; @@ -122,18 +116,28 @@ message TestAllTypes { repeated string repeated_string = 44; repeated bytes repeated_bytes = 45; + // Groups are not allowed in proto3. + // repeated group RepeatedGroup = 46 { + // optional int32 a = 47; + // } + repeated NestedMessage repeated_nested_message = 48; repeated ForeignMessage repeated_foreign_message = 49; repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; repeated NestedEnum repeated_nested_enum = 51; repeated ForeignEnum repeated_foreign_enum = 52; - repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - // Defined in unittest_import_public.proto - repeated protobuf_unittest_import.PublicImportMessage - repeated_public_import_message = 54; - // For oneof test + // Omitted (compared to unittest.proto) because proto2 enums are not allowed + // inside proto2 messages. + // + // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; + + repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; + repeated string repeated_cord = 55 [ctype=CORD]; + + repeated NestedMessage repeated_lazy_message = 57 [lazy=true]; + oneof oneof_field { uint32 oneof_uint32 = 111; NestedMessage oneof_nested_message = 112; @@ -142,176 +146,6 @@ message TestAllTypes { } } -// This proto includes a recusively nested message. -message NestedTestAllTypes { - NestedTestAllTypes child = 1; - TestAllTypes payload = 2; - repeated NestedTestAllTypes repeated_child = 3; -} - -message TestDeprecatedFields { - int32 deprecated_int32 = 1 [deprecated=true]; -} - -// Define these after TestAllTypes to make sure the compiler can handle -// that. -message ForeignMessage { - int32 c = 1; -} - -enum ForeignEnum { - FOREIGN_UNSPECIFIED = 0; - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -message TestReservedFields { - reserved 2, 15, 9 to 11; - reserved "bar", "baz"; -} - - -// Test that we can use NestedMessage from outside TestAllTypes. -message TestForeignNested { - TestAllTypes.NestedMessage foreign_nested = 1; -} - -// Test that really large tag numbers don't break anything. -message TestReallyLargeTagNumber { - // The largest possible tag number is 2^28 - 1, since the wire format uses - // three bits to communicate wire type. - int32 a = 1; - int32 bb = 268435455; -} - -message TestRecursiveMessage { - TestRecursiveMessage a = 1; - int32 i = 2; -} - -// Test that mutual recursion works. -message TestMutualRecursionA { - TestMutualRecursionB bb = 1; -} - -message TestMutualRecursionB { - TestMutualRecursionA a = 1; - int32 optional_int32 = 2; -} - -message TestEnumAllowAlias { - TestEnumWithDupValue value = 1; -} - -// Test an enum that has multiple values with the same number. -enum TestEnumWithDupValue { - TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED = 0; - option allow_alias = true; - - FOO1 = 1; - BAR1 = 2; - BAZ = 3; - FOO2 = 1; - BAR2 = 2; -} - -// Test an enum with large, unordered values. -enum TestSparseEnum { - TEST_SPARSE_ENUM_UNSPECIFIED = 0; - SPARSE_A = 123; - SPARSE_B = 62374; - SPARSE_C = 12589234; - SPARSE_D = -15; - SPARSE_E = -53452; - // In proto3, value 0 must be the first one specified - // SPARSE_F = 0; - SPARSE_G = 2; -} - -// Test message with CamelCase field names. This violates Protocol Buffer -// standard style. -message TestCamelCaseFieldNames { - int32 PrimitiveField = 1; - string StringField = 2; - ForeignEnum EnumField = 3; - ForeignMessage MessageField = 4; - - repeated int32 RepeatedPrimitiveField = 7; - repeated string RepeatedStringField = 8; - repeated ForeignEnum RepeatedEnumField = 9; - repeated ForeignMessage RepeatedMessageField = 10; -} - - -// We list fields out of order, to ensure that we're using field number and not -// field index to determine serialization order. -message TestFieldOrderings { - string my_string = 11; - int64 my_int = 1; - float my_float = 101; - message NestedMessage { - int64 oo = 2; - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - int32 bb = 1; - } - - NestedMessage single_nested_message = 200; -} - -message SparseEnumMessage { - TestSparseEnum sparse_enum = 1; -} - -// Test String and Bytes: string is for valid UTF-8 strings -message OneString { - string data = 1; -} - -message MoreString { - repeated string data = 1; -} - -message OneBytes { - bytes data = 1; -} - -message MoreBytes { - bytes data = 1; -} - -// Test int32, uint32, int64, uint64, and bool are all compatible -message Int32Message { - int32 data = 1; -} - -message Uint32Message { - uint32 data = 1; -} - -message Int64Message { - int64 data = 1; -} - -message Uint64Message { - uint64 data = 1; -} - -message BoolMessage { - bool data = 1; -} - -// Test oneofs. -message TestOneof { - oneof foo { - int32 foo_int = 1; - string foo_string = 2; - TestAllTypes foo_message = 3; - } -} - // Test messages for packed fields message TestPackedTypes { @@ -331,61 +165,44 @@ message TestPackedTypes { repeated ForeignEnum packed_enum = 103 [packed = true]; } -// A message with the same fields as TestPackedTypes, but without packing. Used -// to test packed <-> unpacked wire compatibility. +// Explicitly set packed to false message TestUnpackedTypes { - repeated int32 unpacked_int32 = 90 [packed = false]; - repeated int64 unpacked_int64 = 91 [packed = false]; - repeated uint32 unpacked_uint32 = 92 [packed = false]; - repeated uint64 unpacked_uint64 = 93 [packed = false]; - repeated sint32 unpacked_sint32 = 94 [packed = false]; - repeated sint64 unpacked_sint64 = 95 [packed = false]; - repeated fixed32 unpacked_fixed32 = 96 [packed = false]; - repeated fixed64 unpacked_fixed64 = 97 [packed = false]; - repeated sfixed32 unpacked_sfixed32 = 98 [packed = false]; - repeated sfixed64 unpacked_sfixed64 = 99 [packed = false]; - repeated float unpacked_float = 100 [packed = false]; - repeated double unpacked_double = 101 [packed = false]; - repeated bool unpacked_bool = 102 [packed = false]; - repeated ForeignEnum unpacked_enum = 103 [packed = false]; + repeated int32 repeated_int32 = 1 [packed = false]; + repeated int64 repeated_int64 = 2 [packed = false]; + repeated uint32 repeated_uint32 = 3 [packed = false]; + repeated uint64 repeated_uint64 = 4 [packed = false]; + repeated sint32 repeated_sint32 = 5 [packed = false]; + repeated sint64 repeated_sint64 = 6 [packed = false]; + repeated fixed32 repeated_fixed32 = 7 [packed = false]; + repeated fixed64 repeated_fixed64 = 8 [packed = false]; + repeated sfixed32 repeated_sfixed32 = 9 [packed = false]; + repeated sfixed64 repeated_sfixed64 = 10 [packed = false]; + repeated float repeated_float = 11 [packed = false]; + repeated double repeated_double = 12 [packed = false]; + repeated bool repeated_bool = 13 [packed = false]; + repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false]; } -message TestRepeatedScalarDifferentTagSizes { - // Parsing repeated fixed size values used to fail. This message needs to be - // used in order to get a tag of the right size; all of the repeated fields - // in TestAllTypes didn't trigger the check. - repeated fixed32 repeated_fixed32 = 12; - // Check for a varint type, just for good measure. - repeated int32 repeated_int32 = 13; - - // These have two-byte tags. - repeated fixed64 repeated_fixed64 = 2046; - repeated int64 repeated_int64 = 2047; - - // Three byte tags. - repeated float repeated_float = 262142; - repeated uint64 repeated_uint64 = 262143; +// This proto includes a recusively nested message. +message NestedTestAllTypes { + NestedTestAllTypes child = 1; + TestAllTypes payload = 2; } -message TestCommentInjectionMessage { - // */ <- This should not close the generated doc comment - string a = 1; +// Define these after TestAllTypes to make sure the compiler can handle +// that. +message ForeignMessage { + int32 c = 1; } - -// Test that RPC services work. -message FooRequest {} -message FooResponse {} - -message FooClientMessage {} -message FooServerMessage{} - -service TestService { - rpc Foo(FooRequest) returns (FooResponse); - rpc Bar(BarRequest) returns (BarResponse); +enum ForeignEnum { + FOREIGN_ZERO = 0; + FOREIGN_FOO = 4; + FOREIGN_BAR = 5; + FOREIGN_BAZ = 6; } - -message BarRequest {} -message BarResponse {} +// TestEmptyMessage is used to test behavior of unknown fields. +message TestEmptyMessage { +} diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h index ad560ebc..26a7ba4d 100644 --- a/src/google/protobuf/util/field_comparator.h +++ b/src/google/protobuf/util/field_comparator.h @@ -237,7 +237,7 @@ class LIBPROTOBUF_EXPORT DefaultFieldComparator : public FieldComparator { // True iff default_tolerance_ has been explicitly set. // - // If false, then the default tolerance for flaots and doubles is that which + // If false, then the default tolerance for floats and doubles is that which // is used by MathUtil::AlmostEquals(). bool has_default_tolerance_; diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc index 85cecec5..982d6407 100644 --- a/src/google/protobuf/util/field_mask_util.cc +++ b/src/google/protobuf/util/field_mask_util.cc @@ -207,6 +207,18 @@ class FieldMaskTree { MergeMessage(&root_, source, options, destination); } + // Add required field path of the message to this tree based on current tree + // structure. If a message is present in the tree, add the path of its + // required field to the tree. This is to make sure that after trimming a + // message with required fields are set, check IsInitialized() will not fail. + void AddRequiredFieldPath(const Descriptor* descriptor) { + // Do nothing if the tree is empty. + if (root_.children.empty()) { + return; + } + AddRequiredFieldPath(&root_, descriptor); + } + // Trims all fields not specified by this tree from the given message. void TrimMessage(Message* message) { // Do nothing if the tree is empty. @@ -249,6 +261,12 @@ class FieldMaskTree { const FieldMaskUtil::MergeOptions& options, Message* destination); + // Add required field path of the message to this tree based on current tree + // structure. If a message is present in the tree, add the path of its + // required field to the tree. This is to make sure that after trimming a + // message with required fields are set, check IsInitialized() will not fail. + void AddRequiredFieldPath(Node* node, const Descriptor* descriptor); + // Trims all fields not specified by this sub-tree from the given message. void TrimMessage(const Node* node, Message* message); @@ -456,6 +474,41 @@ void FieldMaskTree::MergeMessage(const Node* node, const Message& source, } } +void FieldMaskTree::AddRequiredFieldPath( + Node* node, const Descriptor* descriptor) { + const int32 field_count = descriptor->field_count(); + for (int index = 0; index < field_count; ++index) { + const FieldDescriptor* field = descriptor->field(index); + if (field->is_required()) { + const string& node_name = field->name(); + Node*& child = node->children[node_name]; + if (child == NULL) { + // Add required field path to the tree + child = new Node(); + } else if (child->children.empty()){ + // If the required field is in the tree and does not have any children, + // do nothing. + continue; + } + // Add required field in the children to the tree if the field is message. + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + AddRequiredFieldPath(child, field->message_type()); + } + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + std::map<string, Node*>::const_iterator it = + node->children.find(field->name()); + if (it != node->children.end()) { + // Add required fields in the children to the + // tree if the field is a message and present in the tree. + Node* child = it->second; + if (!child->children.empty()) { + AddRequiredFieldPath(child, field->message_type()); + } + } + } + } +} + void FieldMaskTree::TrimMessage(const Node* node, Message* message) { GOOGLE_DCHECK(!node->children.empty()); const Reflection* reflection = message->GetReflection(); @@ -470,7 +523,7 @@ void FieldMaskTree::TrimMessage(const Node* node, Message* message) { } else { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { Node* child = it->second; - if (!child->children.empty()) { + if (!child->children.empty() && reflection->HasField(*message, field)) { TrimMessage(child, reflection->MutableMessage(message, field)); } } @@ -542,6 +595,20 @@ void FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* destination) { tree.TrimMessage(GOOGLE_CHECK_NOTNULL(destination)); } +void FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* destination, + const TrimOptions& options) { + // Build a FieldMaskTree and walk through the tree to merge all specified + // fields. + FieldMaskTree tree; + tree.MergeFromFieldMask(mask); + // If keep_required_fields is true, implicitely add required fields of + // a message present in the tree to prevent from trimming. + if (options.keep_required_fields()) { + tree.AddRequiredFieldPath(GOOGLE_CHECK_NOTNULL(destination->GetDescriptor())); + } + tree.TrimMessage(GOOGLE_CHECK_NOTNULL(destination)); +} + } // namespace util } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/util/field_mask_util.h b/src/google/protobuf/util/field_mask_util.h index ab1f2e94..71c68fec 100644 --- a/src/google/protobuf/util/field_mask_util.h +++ b/src/google/protobuf/util/field_mask_util.h @@ -124,10 +124,17 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil { static void MergeMessageTo(const Message& source, const FieldMask& mask, const MergeOptions& options, Message* destination); + class TrimOptions; // Removes from 'message' any field that is not represented in the given // FieldMask. If the FieldMask is empty, does nothing. static void TrimMessage(const FieldMask& mask, Message* message); + // Removes from 'message' any field that is not represented in the given + // FieldMask with customized TrimOptions. + // If the FieldMask is empty, does nothing. + static void TrimMessage(const FieldMask& mask, Message* message, + const TrimOptions& options); + private: friend class SnakeCaseCamelCaseTest; // Converts a field name from snake_case to camelCase: @@ -194,6 +201,23 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil::MergeOptions { bool replace_repeated_fields_; }; +class LIBPROTOBUF_EXPORT FieldMaskUtil::TrimOptions { + public: + TrimOptions() + : keep_required_fields_(false) {} + // When trimming message fields, the default behavior is to trim required + // fields of the present message if they are not specified in the field mask. + // If you instead want to keep required fields of the present message even + // they are not speicifed in the field mask, set this flag to true. + void set_keep_required_fields(bool value) { + keep_required_fields_ = value; + } + bool keep_required_fields() const { return keep_required_fields_; } + + private: + bool keep_required_fields_; +}; + } // namespace util } // namespace protobuf diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc index f952786f..24943ed1 100644 --- a/src/google/protobuf/util/field_mask_util_test.cc +++ b/src/google/protobuf/util/field_mask_util_test.cc @@ -114,6 +114,8 @@ TEST_F(SnakeCaseCamelCaseTest, RoundTripTest) { } using protobuf_unittest::TestAllTypes; +using protobuf_unittest::TestRequired; +using protobuf_unittest::TestRequiredMessage; using protobuf_unittest::NestedTestAllTypes; using google::protobuf::FieldMask; @@ -618,6 +620,84 @@ TEST(FieldMaskUtilTest, TrimMessage) { FieldMask empty_mask; FieldMaskUtil::TrimMessage(empty_mask, &trimmed_all_types); EXPECT_EQ(trimmed_all_types.DebugString(), all_types_msg.DebugString()); + + // Test trim required fields with keep_required_fields is set true. + FieldMaskUtil::TrimOptions options; + TestRequired required_msg_1; + required_msg_1.set_a(1234); + required_msg_1.set_b(3456); + required_msg_1.set_c(5678); + TestRequired trimmed_required_msg_1(required_msg_1); + FieldMaskUtil::FromString("dummy2", &mask); + options.set_keep_required_fields(true); + FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_1, options); + EXPECT_EQ(trimmed_required_msg_1.DebugString(), required_msg_1.DebugString()); + + // Test trim required fields with keep_required_fields is set false. + required_msg_1.clear_a(); + required_msg_1.clear_b(); + required_msg_1.clear_c(); + options.set_keep_required_fields(false); + FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_1, options); + EXPECT_EQ(trimmed_required_msg_1.DebugString(), required_msg_1.DebugString()); + + // Test trim required message with keep_required_fields is set true. + TestRequiredMessage required_msg_2; + required_msg_2.mutable_optional_message()->set_a(1234); + required_msg_2.mutable_optional_message()->set_b(3456); + required_msg_2.mutable_optional_message()->set_c(5678); + required_msg_2.mutable_required_message()->set_a(1234); + required_msg_2.mutable_required_message()->set_b(3456); + required_msg_2.mutable_required_message()->set_c(5678); + required_msg_2.mutable_required_message()->set_dummy2(7890); + TestRequired* repeated_msg = required_msg_2.add_repeated_message(); + repeated_msg->set_a(1234); + repeated_msg->set_b(3456); + repeated_msg->set_c(5678); + TestRequiredMessage trimmed_required_msg_2(required_msg_2); + FieldMaskUtil::FromString("optional_message.dummy2", &mask); + options.set_keep_required_fields(true); + required_msg_2.clear_repeated_message(); + required_msg_2.mutable_required_message()->clear_dummy2(); + FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options); + EXPECT_EQ(trimmed_required_msg_2.DebugString(), + required_msg_2.DebugString()); + + FieldMaskUtil::FromString("required_message", &mask); + required_msg_2.mutable_required_message()->set_dummy2(7890); + trimmed_required_msg_2.mutable_required_message()->set_dummy2(7890); + required_msg_2.clear_optional_message(); + FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options); + EXPECT_EQ(trimmed_required_msg_2.DebugString(), + required_msg_2.DebugString()); + + // Test trim required message with keep_required_fields is set false. + FieldMaskUtil::FromString("required_message.dummy2", &mask); + required_msg_2.mutable_required_message()->clear_a(); + required_msg_2.mutable_required_message()->clear_b(); + required_msg_2.mutable_required_message()->clear_c(); + options.set_keep_required_fields(false); + FieldMaskUtil::TrimMessage(mask, &trimmed_required_msg_2, options); + EXPECT_EQ(trimmed_required_msg_2.DebugString(), + required_msg_2.DebugString()); + + // Verify that trimming an empty message has no effect. In particular, fields + // mentioned in the field mask should not be created or changed. + TestAllTypes empty_msg; + FieldMaskUtil::FromString( + "optional_int32,optional_bytes,optional_nested_message.bb", &mask); + FieldMaskUtil::TrimMessage(mask, &empty_msg); + EXPECT_FALSE(empty_msg.has_optional_int32()); + EXPECT_FALSE(empty_msg.has_optional_bytes()); + EXPECT_FALSE(empty_msg.has_optional_nested_message()); + + // Verify trimming of oneof fields. This should work as expected even if + // multiple elements of the same oneof are included in the FieldMask. + TestAllTypes oneof_msg; + oneof_msg.set_oneof_uint32(11); + FieldMaskUtil::FromString("oneof_uint32,oneof_nested_message.bb", &mask); + FieldMaskUtil::TrimMessage(mask, &oneof_msg); + EXPECT_EQ(11, oneof_msg.oneof_uint32()); } diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index 5763d0c6..95b3a17d 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -637,6 +637,7 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, current_->AddChild(node.release()); } else { child->set_data(data); + child->set_is_placeholder(false); } } diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h index ef2cc981..09c6d23f 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.h +++ b/src/google/protobuf/util/internal/default_value_objectwriter.h @@ -172,7 +172,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // If this node is a leaf (has data), writes the current node to the // ObjectWriter; if not, then recursively writes the children to the // ObjectWriter. - void WriteTo(ObjectWriter* ow); + virtual void WriteTo(ObjectWriter* ow); // Accessors const string& name() const { return name_; } @@ -262,6 +262,10 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { static DataPiece CreateDefaultDataPieceForField( const google::protobuf::Field& field, const TypeInfo* typeinfo); + protected: + // Returns a pointer to current Node in tree. + Node* current() { return current_; } + private: // Populates children of "node" if it is an "any" Node and its real type has // been given. diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 025fbd40..02360a1a 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -125,6 +125,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( recursion_depth_(0), max_recursion_depth_(kDefaultMaxRecursionDepth), render_unknown_fields_(false), + render_unknown_enum_values_(true), add_trailing_zeros_for_timestamp_and_duration_(false) { GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL."; } @@ -142,6 +143,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( recursion_depth_(0), max_recursion_depth_(kDefaultMaxRecursionDepth), render_unknown_fields_(false), + render_unknown_enum_values_(true), add_trailing_zeros_for_timestamp_and_duration_(false) { GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL."; } @@ -866,12 +868,6 @@ Status ProtoStreamObjectSource::RenderNonMessageField( break; } - // No need to lookup enum type if we need to render int. - if (use_ints_for_enums_) { - ow->RenderInt32(field_name, buffer32); - break; - } - // Get the nested enum type for this field. // TODO(skarvaje): Avoid string manipulation. Find ways to speed this // up. @@ -883,14 +879,17 @@ Status ProtoStreamObjectSource::RenderNonMessageField( const google::protobuf::EnumValue* enum_value = FindEnumValueByNumber(*en, buffer32); if (enum_value != NULL) { - if (use_lower_camel_for_enums_) + if (use_ints_for_enums_) { + ow->RenderInt32(field_name, buffer32); + } else if (use_lower_camel_for_enums_) { ow->RenderString(field_name, ToCamelCase(enum_value->name())); - else + } else { ow->RenderString(field_name, enum_value->name()); - } else { + } + } else if (render_unknown_enum_values_) { ow->RenderInt32(field_name, buffer32); } - } else { + } else if (render_unknown_enum_values_) { ow->RenderInt32(field_name, buffer32); } break; diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h index 58d77c2c..b56efdf4 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.h +++ b/src/google/protobuf/util/internal/protostream_objectsource.h @@ -309,6 +309,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { // Whether to render unknown fields. bool render_unknown_fields_; + // Whether to render unknown enum values. + bool render_unknown_enum_values_; + // Whether to add trailing zeros for timestamp and duration. bool add_trailing_zeros_for_timestamp_and_duration_; diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc index 06c9bb6d..36bb1ba9 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc @@ -103,7 +103,8 @@ class ProtostreamObjectSourceTest ow_(&mock_), use_lower_camel_for_enums_(false), use_ints_for_enums_(false), - add_trailing_zeros_(false) { + add_trailing_zeros_(false), + render_unknown_enum_values_(true) { helper_.ResetTypeInfo(Book::descriptor(), Proto3Message::descriptor()); } @@ -276,6 +277,10 @@ class ProtostreamObjectSourceTest void AddTrailingZeros() { add_trailing_zeros_ = true; } + void SetRenderUnknownEnumValues(bool value) { + render_unknown_enum_values_ = value; + } + testing::TypeInfoTestHelper helper_; ::testing::NiceMock<MockObjectWriter> mock_; @@ -283,6 +288,7 @@ class ProtostreamObjectSourceTest bool use_lower_camel_for_enums_; bool use_ints_for_enums_; bool add_trailing_zeros_; + bool render_unknown_enum_values_; }; INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest, @@ -513,12 +519,27 @@ TEST_P(ProtostreamObjectSourceTest, UseIntsForEnumsTest) { DoTest(book, Book::descriptor()); } -TEST_P(ProtostreamObjectSourceTest, UnknownEnum) { +TEST_P(ProtostreamObjectSourceTest, + UnknownEnumAreDroppedWhenRenderUnknownEnumValuesIsUnset) { Proto3Message message; message.set_enum_value(static_cast<Proto3Message::NestedEnum>(1234)); - ow_.StartObject("") - ->RenderInt32("enumValue", 1234) - ->EndObject(); + + SetRenderUnknownEnumValues(false); + + // Unknown enum values are not output. + ow_.StartObject("")->EndObject(); + DoTest(message, Proto3Message::descriptor()); +} + +TEST_P(ProtostreamObjectSourceTest, + UnknownEnumAreOutputWhenRenderUnknownEnumValuesIsSet) { + Proto3Message message; + message.set_enum_value(static_cast<Proto3Message::NestedEnum>(1234)); + + SetRenderUnknownEnumValues(true); + + // Unknown enum values are output. + ow_.StartObject("")->RenderInt32("enumValue", 1234)->EndObject(); DoTest(message, Proto3Message::descriptor()); } diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index d4e15bca..97f96819 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -962,7 +962,7 @@ Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow, // conversions as much as possible. Because ToSnakeCase sometimes returns the // wrong value. google::protobuf::scoped_ptr<ResultCallback1<util::Status, StringPiece> > callback( - NewPermanentCallback(&RenderOneFieldPath, ow)); + ::google::protobuf::NewPermanentCallback(&RenderOneFieldPath, ow)); return DecodeCompactFieldMaskPaths(data.str(), callback.get()); } diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc index 8cf42e49..11780ee8 100644 --- a/src/google/protobuf/util/internal/utility.cc +++ b/src/google/protobuf/util/internal/utility.cc @@ -124,7 +124,10 @@ const StringPiece GetTypeWithoutUrl(StringPiece type_url) { return type_url.substr(kTypeUrlSize + 1); } else { size_t idx = type_url.rfind('/'); - return type_url.substr(idx + 1); + if (idx != type_url.npos) { + type_url.remove_prefix(idx + 1); + } + return type_url; } } diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 830850be..d62038ad 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -53,6 +53,7 @@ #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/dynamic_message.h> #include <google/protobuf/text_format.h> #include <google/protobuf/util/field_comparator.h> @@ -150,6 +151,32 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultipleFieldsMapKeyComparator); }; +MessageDifferencer::MapEntryKeyComparator::MapEntryKeyComparator( + MessageDifferencer* message_differencer) + : message_differencer_(message_differencer) {} + +bool MessageDifferencer::MapEntryKeyComparator::IsMatch( + const Message& message1, const Message& message2, + const std::vector<SpecificField>& parent_fields) const { + // Map entry has its key in the field with tag 1. See the comment for + // map_entry in MessageOptions. + const FieldDescriptor* key = message1.GetDescriptor()->FindFieldByNumber(1); + // If key is not present in message1 and we're doing partial comparison or if + // map key is explicitly ignored treat the field as set instead, + const bool treat_as_set = + (message_differencer_->scope() == PARTIAL && + !message1.GetReflection()->HasField(message1, key)) || + message_differencer_->IsIgnored(message1, message2, key, parent_fields); + + std::vector<SpecificField> current_parent_fields(parent_fields); + if (treat_as_set) { + return message_differencer_->Compare(message1, message2, + ¤t_parent_fields); + } + return message_differencer_->CompareFieldValueUsingParentFields( + message1, message2, key, -1, -1, ¤t_parent_fields); +} + bool MessageDifferencer::Equals(const Message& message1, const Message& message2) { MessageDifferencer differencer; @@ -191,8 +218,10 @@ MessageDifferencer::MessageDifferencer() message_field_comparison_(EQUAL), scope_(FULL), repeated_field_comparison_(AS_LIST), + map_entry_key_comparator_(this), report_matches_(false), - output_string_(NULL) { } + report_moves_(true), + output_string_(NULL) {} MessageDifferencer::~MessageDifferencer() { for (int i = 0; i < owned_key_comparators_.size(); ++i) { @@ -484,8 +513,22 @@ bool MessageDifferencer::Compare( std::vector<const FieldDescriptor*> message2_fields; message2_fields.reserve(1 + message2.GetDescriptor()->field_count()); - reflection1->ListFields(message1, &message1_fields); - reflection2->ListFields(message2, &message2_fields); + if (descriptor1->options().map_entry()) { + if (scope_ == PARTIAL) { + reflection1->ListFields(message1, &message1_fields); + } else { + // Map entry fields are always considered present. + for (int i = 0; i < descriptor1->field_count(); i++) { + message1_fields.push_back(descriptor1->field(i)); + } + } + for (int i = 0; i < descriptor1->field_count(); i++) { + message2_fields.push_back(descriptor1->field(i)); + } + } else { + reflection1->ListFields(message1, &message1_fields); + reflection2->ListFields(message2, &message2_fields); + } // Add sentinel values to deal with the // case where the number of the fields in @@ -783,6 +826,8 @@ bool MessageDifferencer::IsMatch( reflection2->GetRepeatedMessage(*message2, repeated_field, index2); SpecificField specific_field; specific_field.field = repeated_field; + specific_field.index = index1; + specific_field.new_index = index2; current_parent_fields.push_back(specific_field); match = key_comparator->IsMatch(m1, m2, current_parent_fields); } @@ -854,7 +899,7 @@ bool MessageDifferencer::CompareRepeatedField( fieldDifferent = true; } else if (reporter_ != NULL && specific_field.index != specific_field.new_index && - !specific_field.field->is_map()) { + !specific_field.field->is_map() && report_moves_) { parent_fields->push_back(specific_field); reporter_->ReportMoved(message1, message2, *parent_fields); parent_fields->pop_back(); @@ -945,6 +990,8 @@ bool MessageDifferencer::CompareFieldValueUsingParentFields( bool MessageDifferencer::CheckPathChanged( const std::vector<SpecificField>& field_path) { for (int i = 0; i < field_path.size(); ++i) { + // Don't check indexes for map entries -- maps are unordered. + if (field_path[i].field != NULL && field_path[i].field->is_map()) continue; if (field_path[i].index != field_path[i].new_index) return true; } return false; @@ -952,7 +999,6 @@ bool MessageDifferencer::CheckPathChanged( bool MessageDifferencer::IsTreatedAsSet(const FieldDescriptor* field) { if (!field->is_repeated()) return false; - if (field->is_map()) return true; if (repeated_field_comparison_ == AS_SET) return list_fields_.find(field) == list_fields_.end(); return (set_fields_.find(field) != set_fields_.end()); @@ -993,12 +1039,18 @@ bool MessageDifferencer::IsUnknownFieldIgnored( return false; } -const MessageDifferencer::MapKeyComparator* MessageDifferencer - ::GetMapKeyComparator(const FieldDescriptor* field) { +const MessageDifferencer::MapKeyComparator* +MessageDifferencer ::GetMapKeyComparator(const FieldDescriptor* field) const { if (!field->is_repeated()) return NULL; - if (map_field_key_comparator_.find(field) != - map_field_key_comparator_.end()) { - return map_field_key_comparator_[field]; + FieldKeyComparatorMap::const_iterator it = + map_field_key_comparator_.find(field); + if (it != map_field_key_comparator_.end()) { + return it->second; + } + if (field->is_map()) { + // field cannot already be treated as list or set since TreatAsList() and + // TreatAsSet() call GetMapKeyComparator() and fail if it returns non-NULL. + return &map_entry_key_comparator_; } return NULL; } @@ -1400,7 +1452,7 @@ bool MessageDifferencer::MatchRepeatedFieldIndices( // algorithm will fail to find a maximum matching. // Here we use the argumenting path algorithm. MaximumMatcher::NodeMatchCallback* callback = - NewPermanentCallback( + ::google::protobuf::NewPermanentCallback( this, &MessageDifferencer::IsMatch, repeated_field, key_comparator, &message1, &message2, parent_fields); @@ -1524,6 +1576,12 @@ void MessageDifferencer::StreamReporter::PrintPath( } } +void MessageDifferencer::StreamReporter::PrintPath( + const std::vector<SpecificField>& field_path, bool left_side, + const Message& message) { + PrintPath(field_path, left_side); +} + void MessageDifferencer:: StreamReporter::PrintValue(const Message& message, const std::vector<SpecificField>& field_path, @@ -1601,7 +1659,7 @@ void MessageDifferencer::StreamReporter::ReportAdded( const Message& message2, const std::vector<SpecificField>& field_path) { printer_->Print("added: "); - PrintPath(field_path, false); + PrintPath(field_path, false, message2); printer_->Print(": "); PrintValue(message2, field_path, false); printer_->Print("\n"); // Print for newlines. @@ -1612,7 +1670,7 @@ void MessageDifferencer::StreamReporter::ReportDeleted( const Message& message2, const std::vector<SpecificField>& field_path) { printer_->Print("deleted: "); - PrintPath(field_path, true); + PrintPath(field_path, true, message1); printer_->Print(": "); PrintValue(message1, field_path, true); printer_->Print("\n"); // Print for newlines @@ -1636,10 +1694,10 @@ void MessageDifferencer::StreamReporter::ReportModified( } printer_->Print("modified: "); - PrintPath(field_path, true); + PrintPath(field_path, true, message1); if (CheckPathChanged(field_path)) { printer_->Print(" -> "); - PrintPath(field_path, false); + PrintPath(field_path, false, message2); } printer_->Print(": "); PrintValue(message1, field_path, true); @@ -1653,9 +1711,9 @@ void MessageDifferencer::StreamReporter::ReportMoved( const Message& message2, const std::vector<SpecificField>& field_path) { printer_->Print("moved: "); - PrintPath(field_path, true); + PrintPath(field_path, true, message1); printer_->Print(" -> "); - PrintPath(field_path, false); + PrintPath(field_path, false, message2); printer_->Print(" : "); PrintValue(message1, field_path, true); printer_->Print("\n"); // Print for newlines. @@ -1666,10 +1724,10 @@ void MessageDifferencer::StreamReporter::ReportMatched( const Message& message2, const std::vector<SpecificField>& field_path) { printer_->Print("matched: "); - PrintPath(field_path, true); + PrintPath(field_path, true, message1); if (CheckPathChanged(field_path)) { printer_->Print(" -> "); - PrintPath(field_path, false); + PrintPath(field_path, false, message2); } printer_->Print(" : "); PrintValue(message1, field_path, true); @@ -1681,10 +1739,10 @@ void MessageDifferencer::StreamReporter::ReportIgnored( const Message& message2, const std::vector<SpecificField>& field_path) { printer_->Print("ignored: "); - PrintPath(field_path, true); + PrintPath(field_path, true, message1); if (CheckPathChanged(field_path)) { printer_->Print(" -> "); - PrintPath(field_path, false); + PrintPath(field_path, false, message2); } printer_->Print("\n"); // Print for newlines. } @@ -1693,10 +1751,10 @@ void MessageDifferencer::StreamReporter::ReportUnknownFieldIgnored( const Message& message1, const Message& message2, const std::vector<SpecificField>& field_path) { printer_->Print("ignored: "); - PrintPath(field_path, true); + PrintPath(field_path, true, message1); if (CheckPathChanged(field_path)) { printer_->Print(" -> "); - PrintPath(field_path, false); + PrintPath(field_path, false, message2); } printer_->Print("\n"); // Print for newlines. } diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index 192266b6..b7d4de00 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/src/google/protobuf/util/message_differencer.h @@ -518,6 +518,13 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { report_matches_ = report_matches; } + // Tells the differencer whether or not to report moves (in a set or map + // repeated field). This method must be called before Compare. The default for + // a new differencer is true. + void set_report_moves(bool report_moves) { + report_moves_ = report_moves; + } + // Sets the scope of the comparison (as defined in the Scope enumeration // above) that is used by this differencer when determining which fields to // compare between the messages. @@ -620,6 +627,11 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { const std::vector<SpecificField>& field_path); protected: + // Prints the specified path of fields to the buffer. message is used to + // print map keys. + virtual void PrintPath(const std::vector<SpecificField>& field_path, + bool left_side, const Message& message); + // Prints the specified path of fields to the buffer. virtual void PrintPath(const std::vector<SpecificField>& field_path, bool left_side); @@ -653,6 +665,18 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { // relies on some private methods of MessageDifferencer. That's why this // class is declared as a nested class of MessageDifferencer. class MultipleFieldsMapKeyComparator; + + // A MapKeyComparator for use with map_entries. + class LIBPROTOBUF_EXPORT MapEntryKeyComparator : public MapKeyComparator { + public: + explicit MapEntryKeyComparator(MessageDifferencer* message_differencer); + virtual bool IsMatch(const Message& message1, const Message& message2, + const std::vector<SpecificField>& parent_fields) const; + + private: + MessageDifferencer* message_differencer_; + }; + // Returns true if field1's number() is less than field2's. static bool FieldBefore(const FieldDescriptor* field1, const FieldDescriptor* field2); @@ -765,9 +789,10 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { const SpecificField& field, const std::vector<SpecificField>& parent_fields); - // Returns MapKeyComparator* when this field has been configured to - // be treated as a map. If not, returns NULL. - const MapKeyComparator* GetMapKeyComparator(const FieldDescriptor* field); + // Returns MapKeyComparator* when this field has been configured to be treated + // as a map or its is_map() return true. If not, returns NULL. + const MapKeyComparator* GetMapKeyComparator( + const FieldDescriptor* field) const; // Attempts to match indices of a repeated field, so that the contained values // match. Clears output vectors and sets their values to indices of paired @@ -817,11 +842,13 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { // MapKeyComparator is created for comparison purpose. std::vector<MapKeyComparator*> owned_key_comparators_; FieldKeyComparatorMap map_field_key_comparator_; + MapEntryKeyComparator map_entry_key_comparator_; std::vector<IgnoreCriteria*> ignore_criteria_; FieldSet ignored_fields_; bool report_matches_; + bool report_moves_; string* output_string_; diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc index 850b3977..75cffd9f 100755 --- a/src/google/protobuf/util/message_differencer_unittest.cc +++ b/src/google/protobuf/util/message_differencer_unittest.cc @@ -1558,6 +1558,43 @@ TEST(MessageDifferencerTest, RepeatedFieldMapTest_CustomMapKeyComparator) { EXPECT_EQ("ignored: item[0].ra\n", output); } +// Compares fields by their index offset by one, so index 0 matches with 1, etc. +class OffsetByOneMapKeyComparator + : public util::MessageDifferencer::MapKeyComparator { + public: + typedef util::MessageDifferencer::SpecificField SpecificField; + virtual bool IsMatch(const Message& message1, const Message& message2, + const std::vector<SpecificField>& parent_fields) const { + return parent_fields.back().index + 1 == parent_fields.back().new_index; + } +}; + +TEST(MessageDifferencerTest, RepeatedFieldMapTest_CustomIndexMapKeyComparator) { + protobuf_unittest::TestDiffMessage msg1; + protobuf_unittest::TestDiffMessage msg2; + // Treat "item" as Map, using custom key comparator to determine if two + // elements have the same key. + protobuf_unittest::TestDiffMessage::Item* item = msg1.add_item(); + item->set_b("one"); + item = msg2.add_item(); + item->set_b("zero"); + item = msg2.add_item(); + item->set_b("one"); + util::MessageDifferencer differencer; + OffsetByOneMapKeyComparator key_comparator; + differencer.TreatAsMapUsingKeyComparator(GetFieldDescriptor(msg1, "item"), + &key_comparator); + string output; + differencer.ReportDifferencesToString(&output); + // With the offset by one comparator msg1.item[0] should be compared to + // msg2.item[1] and thus be moved, msg2.item[0] should be marked as added. + EXPECT_FALSE(differencer.Compare(msg1, msg2)); + EXPECT_EQ( + "moved: item[0] -> item[1] : { b: \"one\" }\n" + "added: item[0]: { b: \"zero\" }\n", + output); +} + TEST(MessageDifferencerTest, RepeatedFieldSetTest_Subset) { protobuf_unittest::TestDiffMessage msg1; protobuf_unittest::TestDiffMessage msg2; @@ -2806,21 +2843,130 @@ TEST_F(ComparisonTest, EquivalentIgnoresUnknown) { } TEST_F(ComparisonTest, MapTest) { - repeated_field_as_set(); + Map<string, string>& map1 = *map_proto1_.mutable_map_string_string(); + map1["key1"] = "1"; + map1["key2"] = "2"; + map1["key3"] = "3"; + Map<string, string>& map2 = *map_proto2_.mutable_map_string_string(); + map2["key3"] = "0"; + map2["key2"] = "2"; + map2["key1"] = "1"; + + EXPECT_EQ("modified: map_string_string.value: \"3\" -> \"0\"\n", + Run(map_proto1_, map_proto2_)); +} +TEST_F(ComparisonTest, MapIgnoreKeyTest) { Map<string, string>& map1 = *map_proto1_.mutable_map_string_string(); - map1["1"] = "1"; - map1["2"] = "2"; - map1["3"] = "3"; + map1["key1"] = "1"; + map1["key2"] = "2"; + map1["key3"] = "3"; Map<string, string>& map2 = *map_proto2_.mutable_map_string_string(); - map2["3"] = "0"; - map2["2"] = "2"; - map2["1"] = "1"; + map2["key4"] = "2"; + map2["key5"] = "3"; + map2["key6"] = "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_)); + util::MessageDifferencer differencer; + differencer.IgnoreField( + GetFieldDescriptor(map_proto1_, "map_string_string.key")); + EXPECT_TRUE(differencer.Compare(map_proto1_, map_proto2_)); +} + +TEST_F(ComparisonTest, MapRoundTripSyncTest) { + google::protobuf::TextFormat::Parser parser; + unittest::TestMap map_reflection1; + + // By setting via reflection, data exists in repeated field. + ASSERT_TRUE(parser.ParseFromString( + "map_int32_foreign_message { key: 1 }", &map_reflection1)); + + // During copy, data is synced from repeated field to map. + unittest::TestMap map_reflection2 = map_reflection1; + + // During comparison, data is synced from map to repeated field. + EXPECT_TRUE( + util::MessageDifferencer::Equals(map_reflection1, map_reflection2)); +} + +TEST_F(ComparisonTest, MapEntryPartialTest) { + google::protobuf::TextFormat::Parser parser; + unittest::TestMap map1; + unittest::TestMap map2; + + string output; + util::MessageDifferencer differencer; + differencer.set_scope(util::MessageDifferencer::PARTIAL); + differencer.ReportDifferencesToString(&output); + + ASSERT_TRUE(parser.ParseFromString( + "map_int32_foreign_message { key: 1 value { c: 1 } }", &map1)); + ASSERT_TRUE(parser.ParseFromString( + "map_int32_foreign_message { key: 1 value { c: 2 }}", &map2)); + EXPECT_FALSE(differencer.Compare(map1, map2)); + EXPECT_EQ("modified: map_int32_foreign_message.value.c: 1 -> 2\n", output); + + ASSERT_TRUE( + parser.ParseFromString("map_int32_foreign_message { key: 1 }", &map1)); + EXPECT_TRUE(differencer.Compare(map1, map2)); +} + +TEST_F(ComparisonTest, MapEntryPartialEmptyKeyTest) { + google::protobuf::TextFormat::Parser parser; + unittest::TestMap map1; + unittest::TestMap map2; + ASSERT_TRUE(parser.ParseFromString("map_int32_foreign_message {}", &map1)); + ASSERT_TRUE( + parser.ParseFromString("map_int32_foreign_message { key: 1 }", &map2)); + + util::MessageDifferencer differencer; + differencer.set_scope(util::MessageDifferencer::PARTIAL); + EXPECT_TRUE(differencer.Compare(map1, map2)); +} + +// Considers strings keys as equal if they have equal lengths. +class LengthMapKeyComparator + : public util::MessageDifferencer::MapKeyComparator { + public: + typedef util::MessageDifferencer::SpecificField SpecificField; + virtual bool IsMatch(const Message& message1, const Message& message2, + const std::vector<SpecificField>& parent_fields) const { + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + const FieldDescriptor* key_field = + message1.GetDescriptor()->FindFieldByName("key"); + return reflection1->GetString(message1, key_field).size() == + reflection2->GetString(message2, key_field).size(); + } +}; + +TEST_F(ComparisonTest, MapEntryCustomMapKeyComparator) { + google::protobuf::TextFormat::Parser parser; + protobuf_unittest::TestMap msg1; + protobuf_unittest::TestMap msg2; + + ASSERT_TRUE(parser.ParseFromString( + "map_string_foreign_message { key: 'key1' value { c: 1 }}", &msg1)); + ASSERT_TRUE(parser.ParseFromString( + "map_string_foreign_message { key: 'key2' value { c: 1 }}", &msg2)); + + util::MessageDifferencer differencer; + LengthMapKeyComparator key_comparator; + differencer.TreatAsMapUsingKeyComparator( + GetFieldDescriptor(msg1, "map_string_foreign_message"), &key_comparator); + string output; + differencer.ReportDifferencesToString(&output); + // Though the above two messages have different keys for their map entries, + // they are considered the same by key_comparator because their lengths are + // equal. However, in value comparison, all fields of the message are taken + // into consideration, so they are reported as different. + EXPECT_FALSE(differencer.Compare(msg1, msg2)); + EXPECT_EQ("modified: map_string_foreign_message.key: \"key1\" -> \"key2\"\n", + output); + differencer.IgnoreField( + GetFieldDescriptor(msg1, "map_string_foreign_message.key")); + output.clear(); + EXPECT_TRUE(differencer.Compare(msg1, msg2)); + EXPECT_EQ("ignored: map_string_foreign_message.key\n", output); } class MatchingTest : public testing::Test { diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h index 5e9aca52..01ee1337 100644 --- a/src/google/protobuf/wire_format.h +++ b/src/google/protobuf/wire_format.h @@ -46,11 +46,6 @@ #include <google/protobuf/message.h> #include <google/protobuf/wire_format_lite.h> -// Do UTF-8 validation on string type in Debug build only -#ifndef NDEBUG -#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED -#endif - namespace google { namespace protobuf { namespace io { diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc index 7987f7c4..359353c3 100644 --- a/src/google/protobuf/wire_format_lite.cc +++ b/src/google/protobuf/wire_format_lite.cc @@ -47,8 +47,8 @@ #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/io/zero_copy_stream_impl_lite.h> -namespace google { +namespace google { namespace protobuf { namespace internal { diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index 56c6f7fc..3e079ea5 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -46,6 +46,11 @@ #include <google/protobuf/message_lite.h> #include <google/protobuf/io/coded_stream.h> // for CodedOutputStream::Varint32Size +// Do UTF-8 validation on string type in Debug build only +#ifndef NDEBUG +#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED +#endif + // Avoid conflict with iOS where <ConditionalMacros.h> #defines TYPE_BOOL. // // If some one needs the macro TYPE_BOOL in a file that includes this header, it's diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index 8b8dc150..d76e8aa6 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -19,23 +19,50 @@ namespace google { namespace protobuf { -class DoubleValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<DoubleValue> { +class DoubleValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<DoubleValue> + _instance; } _DoubleValue_default_instance_; -class FloatValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FloatValue> { +class FloatValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<FloatValue> + _instance; } _FloatValue_default_instance_; -class Int64ValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Int64Value> { +class Int64ValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Int64Value> + _instance; } _Int64Value_default_instance_; -class UInt64ValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<UInt64Value> { +class UInt64ValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<UInt64Value> + _instance; } _UInt64Value_default_instance_; -class Int32ValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Int32Value> { +class Int32ValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<Int32Value> + _instance; } _Int32Value_default_instance_; -class UInt32ValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<UInt32Value> { +class UInt32ValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<UInt32Value> + _instance; } _UInt32Value_default_instance_; -class BoolValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<BoolValue> { +class BoolValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<BoolValue> + _instance; } _BoolValue_default_instance_; -class StringValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<StringValue> { +class StringValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<StringValue> + _instance; } _StringValue_default_instance_; -class BytesValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<BytesValue> { +class BytesValueDefaultTypeInternal { +public: + ::google::protobuf::internal::ExplicitlyConstructed<BytesValue> + _instance; } _BytesValue_default_instance_; namespace protobuf_google_2fprotobuf_2fwrappers_2eproto { @@ -48,28 +75,28 @@ namespace { } // namespace PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { + const TableStruct::entries[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, }; PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { + const TableStruct::aux[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ::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 }, + TableStruct::schema[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, + { NULL, NULL, 0, -1, -1, -1, -1, NULL, false }, }; -const ::google::protobuf::uint32 TableStruct::offsets[] = { +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DoubleValue, _internal_metadata_), ~0u, // no _extensions_ @@ -125,8 +152,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BytesValue, value_), }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(DoubleValue)}, { 6, -1, sizeof(FloatValue)}, { 12, -1, sizeof(Int64Value)}, @@ -172,42 +198,29 @@ void protobuf_RegisterTypes(const ::std::string&) { } } // namespace - -void TableStruct::Shutdown() { - _DoubleValue_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; - _FloatValue_default_instance_.Shutdown(); - delete file_level_metadata[1].reflection; - _Int64Value_default_instance_.Shutdown(); - delete file_level_metadata[2].reflection; - _UInt64Value_default_instance_.Shutdown(); - delete file_level_metadata[3].reflection; - _Int32Value_default_instance_.Shutdown(); - delete file_level_metadata[4].reflection; - _UInt32Value_default_instance_.Shutdown(); - delete file_level_metadata[5].reflection; - _BoolValue_default_instance_.Shutdown(); - delete file_level_metadata[6].reflection; - _StringValue_default_instance_.Shutdown(); - delete file_level_metadata[7].reflection; - _BytesValue_default_instance_.Shutdown(); - delete file_level_metadata[8].reflection; -} - void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); - _DoubleValue_default_instance_.DefaultConstruct(); - _FloatValue_default_instance_.DefaultConstruct(); - _Int64Value_default_instance_.DefaultConstruct(); - _UInt64Value_default_instance_.DefaultConstruct(); - _Int32Value_default_instance_.DefaultConstruct(); - _UInt32Value_default_instance_.DefaultConstruct(); - _BoolValue_default_instance_.DefaultConstruct(); - _StringValue_default_instance_.DefaultConstruct(); - _BytesValue_default_instance_.DefaultConstruct(); -} + _DoubleValue_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_DoubleValue_default_instance_);_FloatValue_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_FloatValue_default_instance_);_Int64Value_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Int64Value_default_instance_);_UInt64Value_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_UInt64Value_default_instance_);_Int32Value_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_Int32Value_default_instance_);_UInt32Value_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_UInt32Value_default_instance_);_BoolValue_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_BoolValue_default_instance_);_StringValue_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_StringValue_default_instance_);_BytesValue_default_instance_._instance.DefaultConstruct(); + ::google::protobuf::internal::OnShutdownDestroyMessage( + &_BytesValue_default_instance_);} void InitDefaults() { static GOOGLE_PROTOBUF_DECLARE_ONCE(once); @@ -216,7 +229,7 @@ void InitDefaults() { namespace { void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\036google/protobuf/wrappers.proto\022\017google" ".protobuf\"\034\n\013DoubleValue\022\r\n\005value\030\001 \001(\001\"" "\033\n\nFloatValue\022\r\n\005value\030\001 \001(\002\"\033\n\nInt64Val" @@ -234,7 +247,6 @@ void AddDescriptorsImpl() { descriptor, 447); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/wrappers.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); } } // anonymous namespace @@ -295,6 +307,7 @@ DoubleValue::~DoubleValue() { void DoubleValue::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -328,7 +341,12 @@ DoubleValue* DoubleValue::New(::google::protobuf::Arena* arena) const { void DoubleValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DoubleValue) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_ = 0; + _internal_metadata_.Clear(); } bool DoubleValue::MergePartialFromCodedStream( @@ -344,7 +362,7 @@ bool DoubleValue::MergePartialFromCodedStream( // double value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(9u)) { + static_cast< ::google::protobuf::uint8>(9u /* 9 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( @@ -357,12 +375,11 @@ bool DoubleValue::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -387,6 +404,10 @@ void DoubleValue::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.DoubleValue) } @@ -402,6 +423,10 @@ void DoubleValue::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DoubleValue) return target; } @@ -410,6 +435,11 @@ size_t DoubleValue::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.DoubleValue) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // double value = 1; if (this->value() != 0) { total_size += 1 + 8; @@ -487,8 +517,10 @@ void DoubleValue::UnsafeArenaSwap(DoubleValue* other) { InternalSwap(other); } void DoubleValue::InternalSwap(DoubleValue* other) { - std::swap(value_, other->value_); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata DoubleValue::GetMetadata() const { @@ -558,6 +590,7 @@ FloatValue::~FloatValue() { void FloatValue::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -591,7 +624,12 @@ FloatValue* FloatValue::New(::google::protobuf::Arena* arena) const { void FloatValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FloatValue) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_ = 0; + _internal_metadata_.Clear(); } bool FloatValue::MergePartialFromCodedStream( @@ -607,7 +645,7 @@ bool FloatValue::MergePartialFromCodedStream( // float value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(13u)) { + static_cast< ::google::protobuf::uint8>(13u /* 13 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( @@ -620,12 +658,11 @@ bool FloatValue::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -650,6 +687,10 @@ void FloatValue::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.FloatValue) } @@ -665,6 +706,10 @@ void FloatValue::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(1, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FloatValue) return target; } @@ -673,6 +718,11 @@ size_t FloatValue::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.FloatValue) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // float value = 1; if (this->value() != 0) { total_size += 1 + 4; @@ -750,8 +800,10 @@ void FloatValue::UnsafeArenaSwap(FloatValue* other) { InternalSwap(other); } void FloatValue::InternalSwap(FloatValue* other) { - std::swap(value_, other->value_); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata FloatValue::GetMetadata() const { @@ -821,6 +873,7 @@ Int64Value::~Int64Value() { void Int64Value::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -854,7 +907,12 @@ Int64Value* Int64Value::New(::google::protobuf::Arena* arena) const { void Int64Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Int64Value) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_ = GOOGLE_LONGLONG(0); + _internal_metadata_.Clear(); } bool Int64Value::MergePartialFromCodedStream( @@ -870,7 +928,7 @@ bool Int64Value::MergePartialFromCodedStream( // int64 value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( @@ -883,12 +941,11 @@ bool Int64Value::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -913,6 +970,10 @@ void Int64Value::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Int64Value) } @@ -928,6 +989,10 @@ void Int64Value::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int64Value) return target; } @@ -936,6 +1001,11 @@ size_t Int64Value::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int64Value) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // int64 value = 1; if (this->value() != 0) { total_size += 1 + @@ -1015,8 +1085,10 @@ void Int64Value::UnsafeArenaSwap(Int64Value* other) { InternalSwap(other); } void Int64Value::InternalSwap(Int64Value* other) { - std::swap(value_, other->value_); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Int64Value::GetMetadata() const { @@ -1086,6 +1158,7 @@ UInt64Value::~UInt64Value() { void UInt64Value::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -1119,7 +1192,12 @@ UInt64Value* UInt64Value::New(::google::protobuf::Arena* arena) const { void UInt64Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UInt64Value) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_ = GOOGLE_ULONGLONG(0); + _internal_metadata_.Clear(); } bool UInt64Value::MergePartialFromCodedStream( @@ -1135,7 +1213,7 @@ bool UInt64Value::MergePartialFromCodedStream( // uint64 value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( @@ -1148,12 +1226,11 @@ bool UInt64Value::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1178,6 +1255,10 @@ void UInt64Value::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.UInt64Value) } @@ -1193,6 +1274,10 @@ void UInt64Value::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt64Value) return target; } @@ -1201,6 +1286,11 @@ size_t UInt64Value::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt64Value) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // uint64 value = 1; if (this->value() != 0) { total_size += 1 + @@ -1280,8 +1370,10 @@ void UInt64Value::UnsafeArenaSwap(UInt64Value* other) { InternalSwap(other); } void UInt64Value::InternalSwap(UInt64Value* other) { - std::swap(value_, other->value_); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata UInt64Value::GetMetadata() const { @@ -1351,6 +1443,7 @@ Int32Value::~Int32Value() { void Int32Value::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -1384,7 +1477,12 @@ Int32Value* Int32Value::New(::google::protobuf::Arena* arena) const { void Int32Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Int32Value) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_ = 0; + _internal_metadata_.Clear(); } bool Int32Value::MergePartialFromCodedStream( @@ -1400,7 +1498,7 @@ bool Int32Value::MergePartialFromCodedStream( // int32 value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -1413,12 +1511,11 @@ bool Int32Value::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1443,6 +1540,10 @@ void Int32Value::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.Int32Value) } @@ -1458,6 +1559,10 @@ void Int32Value::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int32Value) return target; } @@ -1466,6 +1571,11 @@ size_t Int32Value::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int32Value) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // int32 value = 1; if (this->value() != 0) { total_size += 1 + @@ -1545,8 +1655,10 @@ void Int32Value::UnsafeArenaSwap(Int32Value* other) { InternalSwap(other); } void Int32Value::InternalSwap(Int32Value* other) { - std::swap(value_, other->value_); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Int32Value::GetMetadata() const { @@ -1616,6 +1728,7 @@ UInt32Value::~UInt32Value() { void UInt32Value::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -1649,7 +1762,12 @@ UInt32Value* UInt32Value::New(::google::protobuf::Arena* arena) const { void UInt32Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UInt32Value) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_ = 0u; + _internal_metadata_.Clear(); } bool UInt32Value::MergePartialFromCodedStream( @@ -1665,7 +1783,7 @@ bool UInt32Value::MergePartialFromCodedStream( // uint32 value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( @@ -1678,12 +1796,11 @@ bool UInt32Value::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1708,6 +1825,10 @@ void UInt32Value::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.UInt32Value) } @@ -1723,6 +1844,10 @@ void UInt32Value::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt32Value) return target; } @@ -1731,6 +1856,11 @@ size_t UInt32Value::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt32Value) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // uint32 value = 1; if (this->value() != 0) { total_size += 1 + @@ -1810,8 +1940,10 @@ void UInt32Value::UnsafeArenaSwap(UInt32Value* other) { InternalSwap(other); } void UInt32Value::InternalSwap(UInt32Value* other) { - std::swap(value_, other->value_); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata UInt32Value::GetMetadata() const { @@ -1881,6 +2013,7 @@ BoolValue::~BoolValue() { void BoolValue::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -1914,7 +2047,12 @@ BoolValue* BoolValue::New(::google::protobuf::Arena* arena) const { void BoolValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.BoolValue) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_ = false; + _internal_metadata_.Clear(); } bool BoolValue::MergePartialFromCodedStream( @@ -1930,7 +2068,7 @@ bool BoolValue::MergePartialFromCodedStream( // bool value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -1943,12 +2081,11 @@ bool BoolValue::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1973,6 +2110,10 @@ void BoolValue::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.BoolValue) } @@ -1988,6 +2129,10 @@ void BoolValue::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BoolValue) return target; } @@ -1996,6 +2141,11 @@ size_t BoolValue::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.BoolValue) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // bool value = 1; if (this->value() != 0) { total_size += 1 + 1; @@ -2073,8 +2223,10 @@ void BoolValue::UnsafeArenaSwap(BoolValue* other) { InternalSwap(other); } void BoolValue::InternalSwap(BoolValue* other) { - std::swap(value_, other->value_); - std::swap(_cached_size_, other->_cached_size_); + using std::swap; + swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata BoolValue::GetMetadata() const { @@ -2148,6 +2300,7 @@ StringValue::~StringValue() { void StringValue::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -2182,7 +2335,12 @@ StringValue* StringValue::New(::google::protobuf::Arena* arena) const { void StringValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.StringValue) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + _internal_metadata_.Clear(); } bool StringValue::MergePartialFromCodedStream( @@ -2198,7 +2356,7 @@ bool StringValue::MergePartialFromCodedStream( // string value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_value())); DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -2213,12 +2371,11 @@ bool StringValue::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -2248,6 +2405,10 @@ void StringValue::SerializeWithCachedSizes( 1, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.StringValue) } @@ -2269,6 +2430,10 @@ void StringValue::SerializeWithCachedSizes( 1, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.StringValue) return target; } @@ -2277,6 +2442,11 @@ size_t StringValue::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.StringValue) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // string value = 1; if (this->value().size() > 0) { total_size += 1 + @@ -2356,8 +2526,10 @@ void StringValue::UnsafeArenaSwap(StringValue* other) { InternalSwap(other); } void StringValue::InternalSwap(StringValue* other) { + using std::swap; value_.Swap(&other->value_); - std::swap(_cached_size_, other->_cached_size_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata StringValue::GetMetadata() const { @@ -2381,6 +2553,14 @@ void StringValue::set_value(const ::std::string& value) { value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value) } +#if LANG_CXX11 +void StringValue::set_value(::std::string&& value) { + + value_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.StringValue.value) +} +#endif void StringValue::set_value(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -2484,6 +2664,7 @@ BytesValue::~BytesValue() { void BytesValue::SharedDtor() { ::google::protobuf::Arena* arena = GetArenaNoVirtual(); + GOOGLE_DCHECK(arena == NULL); if (arena != NULL) { return; } @@ -2518,7 +2699,12 @@ BytesValue* BytesValue::New(::google::protobuf::Arena* arena) const { void BytesValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.BytesValue) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + _internal_metadata_.Clear(); } bool BytesValue::MergePartialFromCodedStream( @@ -2534,7 +2720,7 @@ bool BytesValue::MergePartialFromCodedStream( // bytes value = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( input, this->mutable_value())); } else { @@ -2545,12 +2731,11 @@ bool BytesValue::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -2576,6 +2761,10 @@ void BytesValue::SerializeWithCachedSizes( 1, this->value(), output); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), output); + } // @@protoc_insertion_point(serialize_end:google.protobuf.BytesValue) } @@ -2593,6 +2782,10 @@ void BytesValue::SerializeWithCachedSizes( 1, this->value(), target); } + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()), target); + } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BytesValue) return target; } @@ -2601,6 +2794,11 @@ size_t BytesValue::ByteSizeLong() const { // @@protoc_insertion_point(message_byte_size_start:google.protobuf.BytesValue) size_t total_size = 0; + if ((_internal_metadata_.have_unknown_fields() && ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance())); + } // bytes value = 1; if (this->value().size() > 0) { total_size += 1 + @@ -2680,8 +2878,10 @@ void BytesValue::UnsafeArenaSwap(BytesValue* other) { InternalSwap(other); } void BytesValue::InternalSwap(BytesValue* other) { + using std::swap; value_.Swap(&other->value_); - std::swap(_cached_size_, other->_cached_size_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata BytesValue::GetMetadata() const { @@ -2705,6 +2905,14 @@ void BytesValue::set_value(const ::std::string& value) { value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value) } +#if LANG_CXX11 +void BytesValue::set_value(::std::string&& value) { + + value_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.BytesValue.value) +} +#endif void BytesValue::set_value(const char* value) { GOOGLE_DCHECK(value != NULL); diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 7495aa68..29d6b738 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3004000 #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 3003002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3004000 < 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. @@ -72,8 +72,9 @@ struct LIBPROTOBUF_EXPORT TableStruct { static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; static void InitDefaultsImpl(); - static void Shutdown(); }; void LIBPROTOBUF_EXPORT AddDescriptors(); void LIBPROTOBUF_EXPORT InitDefaults(); @@ -92,7 +93,21 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message /* @@p CopyFrom(from); return *this; } + #if LANG_CXX11 + DoubleValue(DoubleValue&& from) noexcept + : DoubleValue() { + *this = ::std::move(from); + } + inline DoubleValue& operator=(DoubleValue&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -111,6 +126,9 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message /* @@p void UnsafeArenaSwap(DoubleValue* other); void Swap(DoubleValue* other); + friend void swap(DoubleValue& a, DoubleValue& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -167,7 +185,7 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message /* @@p private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; double value_; @@ -187,7 +205,21 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message /* @@pr CopyFrom(from); return *this; } + #if LANG_CXX11 + FloatValue(FloatValue&& from) noexcept + : FloatValue() { + *this = ::std::move(from); + } + inline FloatValue& operator=(FloatValue&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -206,6 +238,9 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message /* @@pr void UnsafeArenaSwap(FloatValue* other); void Swap(FloatValue* other); + friend void swap(FloatValue& a, FloatValue& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -262,7 +297,7 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message /* @@pr private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; float value_; @@ -282,7 +317,21 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message /* @@pr CopyFrom(from); return *this; } + #if LANG_CXX11 + Int64Value(Int64Value&& from) noexcept + : Int64Value() { + *this = ::std::move(from); + } + inline Int64Value& operator=(Int64Value&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -301,6 +350,9 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message /* @@pr void UnsafeArenaSwap(Int64Value* other); void Swap(Int64Value* other); + friend void swap(Int64Value& a, Int64Value& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -357,7 +409,7 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message /* @@pr private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::int64 value_; @@ -377,7 +429,21 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message /* @@p CopyFrom(from); return *this; } + #if LANG_CXX11 + UInt64Value(UInt64Value&& from) noexcept + : UInt64Value() { + *this = ::std::move(from); + } + inline UInt64Value& operator=(UInt64Value&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -396,6 +462,9 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message /* @@p void UnsafeArenaSwap(UInt64Value* other); void Swap(UInt64Value* other); + friend void swap(UInt64Value& a, UInt64Value& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -452,7 +521,7 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message /* @@p private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::uint64 value_; @@ -472,7 +541,21 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message /* @@pr CopyFrom(from); return *this; } + #if LANG_CXX11 + Int32Value(Int32Value&& from) noexcept + : Int32Value() { + *this = ::std::move(from); + } + inline Int32Value& operator=(Int32Value&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -491,6 +574,9 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message /* @@pr void UnsafeArenaSwap(Int32Value* other); void Swap(Int32Value* other); + friend void swap(Int32Value& a, Int32Value& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -547,7 +633,7 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message /* @@pr private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::int32 value_; @@ -567,7 +653,21 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message /* @@p CopyFrom(from); return *this; } + #if LANG_CXX11 + UInt32Value(UInt32Value&& from) noexcept + : UInt32Value() { + *this = ::std::move(from); + } + inline UInt32Value& operator=(UInt32Value&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -586,6 +686,9 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message /* @@p void UnsafeArenaSwap(UInt32Value* other); void Swap(UInt32Value* other); + friend void swap(UInt32Value& a, UInt32Value& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -642,7 +745,7 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message /* @@p private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::uint32 value_; @@ -662,7 +765,21 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message /* @@pro CopyFrom(from); return *this; } + #if LANG_CXX11 + BoolValue(BoolValue&& from) noexcept + : BoolValue() { + *this = ::std::move(from); + } + inline BoolValue& operator=(BoolValue&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -681,6 +798,9 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message /* @@pro void UnsafeArenaSwap(BoolValue* other); void Swap(BoolValue* other); + friend void swap(BoolValue& a, BoolValue& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -737,7 +857,7 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message /* @@pro private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; bool value_; @@ -757,7 +877,21 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@p CopyFrom(from); return *this; } + #if LANG_CXX11 + StringValue(StringValue&& from) noexcept + : StringValue() { + *this = ::std::move(from); + } + inline StringValue& operator=(StringValue&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -776,6 +910,9 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@p void UnsafeArenaSwap(StringValue* other); void Swap(StringValue* other); + friend void swap(StringValue& a, StringValue& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -827,6 +964,9 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@p static const int kValueFieldNumber = 1; const ::std::string& value() const; void set_value(const ::std::string& value); + #if LANG_CXX11 + void set_value(::std::string&& value); + #endif void set_value(const char* value); void set_value(const char* value, size_t size); ::std::string* mutable_value(); @@ -840,7 +980,7 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@p private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::internal::ArenaStringPtr value_; @@ -860,7 +1000,21 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@pr CopyFrom(from); return *this; } + #if LANG_CXX11 + BytesValue(BytesValue&& from) noexcept + : BytesValue() { + *this = ::std::move(from); + } + inline BytesValue& operator=(BytesValue&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL { return GetArenaNoVirtual(); } @@ -879,6 +1033,9 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@pr void UnsafeArenaSwap(BytesValue* other); void Swap(BytesValue* other); + friend void swap(BytesValue& a, BytesValue& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- @@ -930,6 +1087,9 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@pr static const int kValueFieldNumber = 1; const ::std::string& value() const; void set_value(const ::std::string& value); + #if LANG_CXX11 + void set_value(::std::string&& value); + #endif void set_value(const char* value); void set_value(const void* value, size_t size); ::std::string* mutable_value(); @@ -943,7 +1103,7 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@pr private: ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - friend class ::google::protobuf::Arena; + template <typename T> friend class ::google::protobuf::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; ::google::protobuf::internal::ArenaStringPtr value_; @@ -956,6 +1116,10 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@pr // =================================================================== #if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // DoubleValue // double value = 1; @@ -1097,6 +1261,14 @@ inline void StringValue::set_value(const ::std::string& value) { value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value) } +#if LANG_CXX11 +inline void StringValue::set_value(::std::string&& value) { + + value_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.StringValue.value) +} +#endif inline void StringValue::set_value(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1168,6 +1340,14 @@ inline void BytesValue::set_value(const ::std::string& value) { value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value) } +#if LANG_CXX11 +inline void BytesValue::set_value(::std::string&& value) { + + value_.Set( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.BytesValue.value) +} +#endif inline void BytesValue::set_value(const char* value) { GOOGLE_DCHECK(value != NULL); @@ -1222,6 +1402,9 @@ inline void BytesValue::unsafe_arena_set_allocated_value( // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.BytesValue.value) } +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // ------------------------------------------------------------------- |