Sync from Piper @401883098

PROTOBUF_SYNC_PIPER
This commit is contained in:
Adam Cozzette 2021-10-08 16:45:26 -07:00
commit 3afc828309
195 changed files with 5302 additions and 5449 deletions

View File

@ -2,6 +2,17 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
Protocol Compiler
* Make proto2::Message::DiscardUnknownFields() non-virtual
2021-10-04 version 3.18.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
Python
* Update setup.py to reflect that we now require at least Python 3.5 (#8989)
* Performance fix for DynamicMessage: force GetRaw() to be inlined (#9023)
Ruby
* Update ruby_generator.cc to allow proto2 imports in proto3 (#9003)
2021-09-13 version 3.18.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
Python
* Removed Python 2.x support.
* Pure python descriptor_pool.AddSerializedFile() will always build the
@ -15,18 +26,44 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
* Generated code now uses the c++11 standard integer types int{32,64}_t and
uint{32,64}_t
* Reduce memory usage of the DescriptorPool type.
* Moved the zero-argument New() method on messages to the base class (internal
optimization).
* Unused return values marked with `PROTOBUF_MUST_USE_RESULT` are now
correctly attributed.
* Demotes PrintPath log for maps in MessageDifferencer down from WARNING to
INFO.
* Make sure FullMessageName() is always private.
* Fix race condition in EnumDescriptor.
* Remove MessageLite::GetMaybeArenaPointer.
Java
* Add @deprecated javadoc for set/get/has methods
* correctly decode \? escape sequence in text protos
* Avoid depending on Objects.requireNonNull() until we can verify that no users are depending on older Android versions.
* Avoid depending on Objects.requireNonNull() until we can verify that no
users are depending on older Android versions.
* disallow null string map values in put and putAll
* Add `@CheckReturnValue` to `ByteString` API.
* Make the `hasPresence` method public in `FieldDescriptor`.
* Report more detailed messages in Duration and Timestamp proto parsing
errors.
* New Timestamps.fromDate utility method that converts a java.util.Date to a
Timestamp proto object.
Kotlin
* Generated Kotlin code is Explicit API mode compatible
Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
2021-09-13 version 3.18.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
C++
* Fix warnings raised by clang 11 (#8664)
* Make StringPiece constructible from std::string_view (#8707)
* Add missing capability attributes for LLVM 12 (#8714)
* Stop using std::iterator (deprecated in C++17). (#8741)
* Move field_access_listener from libprotobuf-lite to libprotobuf (#8775)
* Fix #7047 Safely handle setlocale (#8735)
* Remove deprecated version of SetTotalBytesLimit() (#8794)
* Support arena allocation of google::protobuf::AnyMetadata (#8758)
* Fix undefined symbol error around SharedCtor() (#8827)
* Fix default value of enum(int) in json_util with proto2 (#8835)
* Better Smaller ByteSizeLong
* Introduce event filters for inject_field_listener_events
* Reduce memory usage of DescriptorPool
@ -50,6 +87,8 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
* Reduce memory usage of the DescriptorPool type.
Java
* Fix errorprone conflict (#8723)
* Removing deprecated TimeUtil class. (#8749)
* Optimized FieldDescriptor.valueOf() to avoid array copying.
* Removing deprecated TimeUtil class.
* Add Durations.parseUnchecked(String) and Timestamps.parseUnchecked(String)
@ -60,6 +99,24 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
* Fix for optimization when reading doubles from binary wire format
* Replace toArray implementation with toJSON.
Python
* Drops support for 2.7 and 3.5.
PHP
* Migrate PHP & Ruby to ABSL wyhash (#8854)
* Added support for PHP 8.1 (currently in RC1) to the C extension (#8964)
* Fixed PHP SEGV when constructing messages from a destructor. (#8969)
Ruby
* Move DSL implementation from C to pure Ruby (#8850)
* Fixed a memory bug with RepeatedField#+. (#8970)
Other
* [csharp] ByteString.CreateCodedInput should use ArraySegment offset and count (#8740)
* [ObjC] Add support for using the proto package to prefix symbols. (#8760)
* field_presence.md: fix Go example (#8788)
Kotlin
* Suppress NOTHING_TO_INLINE in Kotlin generated inline functions.

View File

@ -297,6 +297,8 @@ java_EXTRA_DIST=
java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java \
java/core/src/main/java/com/google/protobuf/ByteOutput.java \
java/core/src/main/java/com/google/protobuf/ByteString.java \
java/core/src/main/java/com/google/protobuf/CanIgnoreReturnValue.java \
java/core/src/main/java/com/google/protobuf/CheckReturnValue.java \
java/core/src/main/java/com/google/protobuf/CodedInputStream.java \
java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java \
java/core/src/main/java/com/google/protobuf/CodedOutputStream.java \
@ -967,6 +969,7 @@ php_EXTRA_DIST= \
php/tests/GeneratedServiceTest.php \
php/tests/MapFieldTest.php \
php/tests/memory_leak_test.php \
php/tests/memory_leak_test.sh \
php/tests/multirequest.php \
php/tests/multirequest.sh \
php/tests/PhpImplementationTest.php \
@ -1147,19 +1150,14 @@ ruby_EXTRA_DIST= \
ruby/lib/google/protobuf/well_known_types.rb \
ruby/lib/google/protobuf.rb \
ruby/pom.xml \
ruby/src/main/java/com/google/protobuf/jruby/RubyBuilder.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyEnum.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyEnumBuilderContext.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyFileBuilderContext.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyMessageBuilderContext.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyOneofBuilderContext.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyProtobuf.java \
ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java \

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Protobuf-C++'
s.version = '3.17.3'
s.version = '3.18.1'
s.summary = 'Protocol Buffers v3 runtime library for C++.'
s.homepage = 'https://github.com/google/protobuf'
s.license = '3-Clause BSD License'
@ -21,7 +21,8 @@ Pod::Spec.new do |s|
'src/google/**/*_unittest.{h,cc}',
'src/google/protobuf/test_util*.{h,cc}',
'src/google/protobuf/map_lite_test_util.{h,cc}',
'src/google/protobuf/map_test_util*.{h,cc,inc}'
'src/google/protobuf/map_test_util*.{h,cc,inc}',
'src/google/protobuf/reflection_tester.{h,cc}'
s.header_mappings_dir = 'src'

View File

@ -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.17.3'
s.version = '3.18.1'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/protocolbuffers/protobuf'
s.license = '3-Clause BSD License'

View File

@ -45,7 +45,6 @@ maven_install(
"com.google.truth:truth:1.1.2",
"junit:junit:4.12",
"org.easymock:easymock:3.2",
"org.easymock:easymockclassextension:3.2",
],
repositories = [
"https://repo1.maven.org/maven2",

View File

@ -30,9 +30,8 @@ endforeach()
if (protobuf_BUILD_PROTOC_BINARIES)
install(TARGETS protoc EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT protoc)
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
if (UNIX AND NOT APPLE)
set_property(TARGET protoc
PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")

View File

@ -19,6 +19,7 @@ set(libprotobuf_lite_files
${protobuf_source_dir}/src/google/protobuf/message_lite.cc
${protobuf_source_dir}/src/google/protobuf/parse_context.cc
${protobuf_source_dir}/src/google/protobuf/repeated_field.cc
${protobuf_source_dir}/src/google/protobuf/repeated_ptr_field.cc
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.cc
${protobuf_source_dir}/src/google/protobuf/stubs/common.cc
${protobuf_source_dir}/src/google/protobuf/stubs/int128.cc
@ -65,6 +66,7 @@ set(libprotobuf_lite_includes
${protobuf_source_dir}/src/google/protobuf/parse_context.h
${protobuf_source_dir}/src/google/protobuf/port.h
${protobuf_source_dir}/src/google/protobuf/repeated_field.h
${protobuf_source_dir}/src/google/protobuf/repeated_ptr_field.h
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.h
${protobuf_source_dir}/src/google/protobuf/stubs/callback.h
${protobuf_source_dir}/src/google/protobuf/stubs/casts.h

View File

@ -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.17.3],[protobuf@googlegroups.com],[protobuf])
AC_INIT([Protocol Buffers],[3.18.1],[protobuf@googlegroups.com],[protobuf])
AM_MAINTAINER_MODE([enable])

View File

@ -2,6 +2,34 @@ Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.JsonInput.BoolFieldAllCapitalFalse
Recommended.Proto3.JsonInput.BoolFieldAllCapitalTrue
Recommended.Proto3.JsonInput.BoolFieldCamelCaseFalse
@ -29,782 +57,39 @@ Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate
Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate
Recommended.Proto3.JsonInput.Uint32MapFieldKeyNotQuoted
Recommended.Proto3.JsonInput.Uint64MapFieldKeyNotQuoted
Recommended.Proto3.ProtobufInput.OneofZeroBool.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroBool.ProtobufOutput
Recommended.Proto3.ProtobufInput.OneofZeroBytes.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroBytes.ProtobufOutput
Recommended.Proto3.ProtobufInput.OneofZeroDouble.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroDouble.ProtobufOutput
Recommended.Proto3.ProtobufInput.OneofZeroEnum.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroEnum.ProtobufOutput
Recommended.Proto3.ProtobufInput.OneofZeroFloat.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroFloat.ProtobufOutput
Recommended.Proto3.ProtobufInput.OneofZeroMessage.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroMessage.ProtobufOutput
Recommended.Proto3.ProtobufInput.OneofZeroMessageSetTwice.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroMessageSetTwice.ProtobufOutput
Recommended.Proto3.ProtobufInput.OneofZeroString.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroString.ProtobufOutput
Recommended.Proto3.ProtobufInput.OneofZeroUint32.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroUint32.ProtobufOutput
Recommended.Proto3.ProtobufInput.OneofZeroUint64.JsonOutput
Recommended.Proto3.ProtobufInput.OneofZeroUint64.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BOOL.DefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BOOL.MultipleValuesForDifferentField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BOOL.MultipleValuesForSameField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BOOL.NonDefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BYTES.DefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BYTES.MultipleValuesForDifferentField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BYTES.MultipleValuesForSameField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.BYTES.NonDefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.DOUBLE.DefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.DOUBLE.MultipleValuesForDifferentField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.DOUBLE.MultipleValuesForSameField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.DOUBLE.NonDefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.ENUM.DefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.ENUM.MultipleValuesForDifferentField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.ENUM.MultipleValuesForSameField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.ENUM.NonDefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.FLOAT.DefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.FLOAT.MultipleValuesForDifferentField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.FLOAT.MultipleValuesForSameField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.FLOAT.NonDefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.DefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.MultipleValuesForDifferentField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.MultipleValuesForSameField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.NonDefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.STRING.DefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.STRING.MultipleValuesForDifferentField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.STRING.MultipleValuesForSameField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.STRING.NonDefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT32.DefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT32.MultipleValuesForDifferentField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT32.MultipleValuesForSameField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT32.NonDefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT64.DefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT64.MultipleValuesForDifferentField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT64.MultipleValuesForSameField.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.UINT64.NonDefaultValue.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[4].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[5].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[6].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BYTES[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.DOUBLE[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.DOUBLE[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[0].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[5].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FIXED32[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FIXED64[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FLOAT[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FLOAT[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FLOAT[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FLOAT[4].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[4].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[5].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[6].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[7].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[8].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[9].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.MESSAGE[0].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.MESSAGE[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED32[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED32[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED64[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED64[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT32[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT32[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT32[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT32[4].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.STRING[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.STRING[4].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.STRING[5].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.STRING[6].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[3].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[4].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[5].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[6].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[7].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[8].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[9].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT64[1].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT64[2].ProtobufOutput
Required.DurationProtoInputTooLarge.JsonOutput
Required.DurationProtoInputTooSmall.JsonOutput
Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
Required.Proto3.JsonInput.Any.JsonOutput
Required.Proto3.JsonInput.Any.ProtobufOutput
Required.Proto3.JsonInput.AnyNested.JsonOutput
Required.Proto3.JsonInput.AnyNested.ProtobufOutput
Required.Proto3.JsonInput.AnyUnorderedTypeTag.JsonOutput
Required.Proto3.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
Required.Proto3.JsonInput.AnyWithDuration.JsonOutput
Required.Proto3.JsonInput.AnyWithDuration.ProtobufOutput
Required.Proto3.JsonInput.AnyWithFieldMask.JsonOutput
Required.Proto3.JsonInput.AnyWithFieldMask.ProtobufOutput
Required.Proto3.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
Required.Proto3.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
Required.Proto3.JsonInput.AnyWithStruct.JsonOutput
Required.Proto3.JsonInput.AnyWithStruct.ProtobufOutput
Required.Proto3.JsonInput.AnyWithTimestamp.JsonOutput
Required.Proto3.JsonInput.AnyWithTimestamp.ProtobufOutput
Required.Proto3.JsonInput.AnyWithValueForInteger.JsonOutput
Required.Proto3.JsonInput.AnyWithValueForInteger.ProtobufOutput
Required.Proto3.JsonInput.AnyWithValueForJsonObject.JsonOutput
Required.Proto3.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
Required.Proto3.JsonInput.EnumFieldNotQuoted
Required.Proto3.JsonInput.IgnoreUnknownJsonFalse.ProtobufOutput
Required.Proto3.JsonInput.IgnoreUnknownJsonNull.ProtobufOutput
Required.Proto3.JsonInput.IgnoreUnknownJsonNumber.ProtobufOutput
Required.Proto3.JsonInput.IgnoreUnknownJsonObject.ProtobufOutput
Required.Proto3.JsonInput.IgnoreUnknownJsonString.ProtobufOutput
Required.Proto3.JsonInput.IgnoreUnknownJsonTrue.ProtobufOutput
Required.Proto3.JsonInput.Int32FieldLeadingZero
Required.Proto3.JsonInput.Int32FieldNegativeWithLeadingZero
Required.Proto3.JsonInput.Int32FieldPlusSign
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
Required.Proto3.JsonInput.StringFieldNotAString
Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
Required.Proto3.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
Required.Proto3.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
Required.Proto3.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL
Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32
Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64
Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32
Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64
Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32
Required.Proto3.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64
Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.BYTES.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.BYTES.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.ENUM.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.ENUM.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.STRING.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.STRING.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.BOOL.BOOL.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED32.FIXED32.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.FIXED64.FIXED64.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.DOUBLE.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.FLOAT.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT32.INT32.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.INT64.INT64.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED32.SFIXED32.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SFIXED64.SFIXED64.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT32.SINT32.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.SINT64.SINT64.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.BYTES.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.ENUM.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MergeValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MergeValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.STRING.STRING.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT32.UINT32.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.Default.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.Default.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateKey.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateKey.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateKeyInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateKeyInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateValueInMapEntry.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.DuplicateValueInMapEntry.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.MissingDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.MissingDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.NonDefault.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.NonDefault.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.Unordered.JsonOutput
Required.Proto3.ProtobufInput.ValidDataMap.UINT64.UINT64.Unordered.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.DefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.DefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.MultipleValuesForDifferentField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.MultipleValuesForDifferentField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.MultipleValuesForSameField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.MultipleValuesForSameField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.NonDefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BOOL.NonDefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.DefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.DefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.MultipleValuesForDifferentField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.MultipleValuesForDifferentField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.MultipleValuesForSameField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.MultipleValuesForSameField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.NonDefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.NonDefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.DefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.DefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.MultipleValuesForDifferentField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.MultipleValuesForDifferentField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.MultipleValuesForSameField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.MultipleValuesForSameField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.NonDefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.DOUBLE.NonDefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.DefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.DefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.MultipleValuesForDifferentField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.MultipleValuesForDifferentField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.MultipleValuesForSameField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.MultipleValuesForSameField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.NonDefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.ENUM.NonDefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.DefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.DefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.MultipleValuesForDifferentField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.MultipleValuesForDifferentField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.MultipleValuesForSameField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.MultipleValuesForSameField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.NonDefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.FLOAT.NonDefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.DefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.DefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.MultipleValuesForDifferentField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.MultipleValuesForDifferentField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.MultipleValuesForSameField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.MultipleValuesForSameField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.NonDefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.NonDefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.STRING.DefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.STRING.DefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.STRING.MultipleValuesForDifferentField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.STRING.MultipleValuesForDifferentField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.STRING.MultipleValuesForSameField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.STRING.MultipleValuesForSameField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.STRING.NonDefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.STRING.NonDefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.DefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.DefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForDifferentField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForDifferentField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForSameField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.MultipleValuesForSameField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.NonDefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT32.NonDefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.DefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.DefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.MultipleValuesForDifferentField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.MultipleValuesForDifferentField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.MultipleValuesForSameField.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.MultipleValuesForSameField.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.NonDefaultValue.JsonOutput
Required.Proto3.ProtobufInput.ValidDataOneof.UINT64.NonDefaultValue.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.MESSAGE.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.MESSAGE.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.JsonOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[4].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[4].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[5].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[5].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[6].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BOOL[6].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BYTES[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.BYTES[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.DOUBLE[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.DOUBLE[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.DOUBLE[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.DOUBLE[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[0].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[0].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[4].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[4].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[5].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[5].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FIXED32[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FIXED32[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FIXED64[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FIXED64[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[4].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[4].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[4].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[4].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[5].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[5].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[6].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[6].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[7].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[7].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[8].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[8].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[9].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[9].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT64[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT64[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT64[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT64[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT64[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT64[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.MESSAGE[0].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.MESSAGE[0].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.MESSAGE[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.MESSAGE[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED32[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED32[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED32[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED32[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[4].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT32[4].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.STRING[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.STRING[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.STRING[4].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.STRING[4].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.STRING[5].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.STRING[5].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.STRING[6].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.STRING[6].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[3].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[3].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[4].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[4].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[5].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[5].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[6].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[6].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[7].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[7].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[8].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[8].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[9].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[9].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[1].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[1].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[2].JsonOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[2].ProtobufOutput
Required.TimestampProtoInputTooLarge.JsonOutput
Required.TimestampProtoInputTooSmall.JsonOutput

View File

@ -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.17.3</version>
<version>3.18.1</version>
<authors>Google Inc.</authors>
<owners>protobuf-packages</owners>
<licenseUrl>https://github.com/protocolbuffers/protobuf/blob/master/LICENSE</licenseUrl>

View File

@ -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.17.3</VersionPrefix>
<VersionPrefix>3.18.1</VersionPrefix>
<!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence -->
<LangVersion>7.2</LangVersion>
<Authors>Google Inc.</Authors>

View File

@ -4,7 +4,7 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-bom</artifactId>
<version>3.17.3</version>
<version>3.18.1</version>
<packaging>pom</packaging>
<name>Protocol Buffers [BOM]</name>

View File

@ -21,6 +21,8 @@ LITE_SRCS = [
"src/main/java/com/google/protobuf/ByteBufferWriter.java",
"src/main/java/com/google/protobuf/ByteOutput.java",
"src/main/java/com/google/protobuf/ByteString.java",
"src/main/java/com/google/protobuf/CanIgnoreReturnValue.java",
"src/main/java/com/google/protobuf/CheckReturnValue.java",
"src/main/java/com/google/protobuf/CodedInputStream.java",
"src/main/java/com/google/protobuf/CodedInputStreamReader.java",
"src/main/java/com/google/protobuf/CodedOutputStream.java",
@ -359,7 +361,6 @@ junit_tests(
":java_test_protos_java_proto_lite",
":test_util_lite",
"//external:easymock",
"//external:easymock_classextension",
"//external:junit",
"//external:truth",
]

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.17.3</version>
<version>3.18.1</version>
</parent>
<artifactId>protobuf-java</artifactId>
@ -27,11 +27,6 @@
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>

View File

@ -49,6 +49,7 @@ import com.google.protobuf.DescriptorProtos.OneofOptions;
import com.google.protobuf.DescriptorProtos.ServiceDescriptorProto;
import com.google.protobuf.DescriptorProtos.ServiceOptions;
import com.google.protobuf.Descriptors.FileDescriptor.Syntax;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
@ -59,7 +60,6 @@ import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.logging.Logger;
/**
@ -1816,6 +1816,15 @@ public final class Descriptors {
valuesSortedByNumber, distinctNumbers, EnumValueDescriptor.NUMBER_GETTER, number);
}
private static class UnknownEnumValueReference extends WeakReference<EnumValueDescriptor> {
private final int number;
private UnknownEnumValueReference(int number, EnumValueDescriptor descriptor) {
super(descriptor);
this.number = number;
}
}
/**
* Get the enum value for a number. If no enum value has this number, construct an
* EnumValueDescriptor for it.
@ -1827,43 +1836,28 @@ public final class Descriptors {
}
// The number represents an unknown enum value.
synchronized (this) {
// Descriptors are compared by object identity so for the same number
// we need to return the same EnumValueDescriptor object. This means
// we have to store created EnumValueDescriptors. However, as there
// are potentially 2G unknown enum values, storing all of these
// objects persistently will consume lots of memory for long-running
// services and it's also unnecessary as not many EnumValueDescriptors
// will be used at the same time.
//
// To solve the problem we take advantage of Java's weak references and
// rely on gc to release unused descriptors.
//
// Here is how it works:
// * We store unknown EnumValueDescriptors in a WeakHashMap with the
// value being a weak reference to the descriptor.
// * The descriptor holds a strong reference to the key so as long
// as the EnumValueDescriptor is in use, the key will be there
// and the corresponding map entry will be there. Following-up
// queries with the same number will return the same descriptor.
// * If the user no longer uses an unknown EnumValueDescriptor,
// it will be gc-ed since we only hold a weak reference to it in
// the map. The key in the corresponding map entry will also be
// gc-ed as the only strong reference to it is in the descriptor
// which is just gc-ed. With the key being gone WeakHashMap will
// then remove the whole entry. This way unknown descriptors will
// be freed automatically and we don't need to do anything to
// clean-up unused map entries.
// Note: We must use "new Integer(number)" here because we don't want
// these Integer objects to be cached.
Integer key = new Integer(number);
WeakReference<EnumValueDescriptor> reference = unknownValues.get(key);
if (reference != null) {
result = reference.get();
if (cleanupQueue == null) {
cleanupQueue = new ReferenceQueue<EnumValueDescriptor>();
unknownValues = new HashMap<Integer, WeakReference<EnumValueDescriptor>>();
} else {
while (true) {
UnknownEnumValueReference toClean = (UnknownEnumValueReference) cleanupQueue.poll();
if (toClean == null) {
break;
}
unknownValues.remove(toClean.number);
}
}
// There are two ways we can be missing a value: it wasn't in the map, or the reference
// has been GC'd. (It may even have been GC'd since we cleaned up the references a few
// lines of code ago.) So get out the reference, if it's still present...
WeakReference<EnumValueDescriptor> reference = unknownValues.get(number);
result = (reference == null) ? null : reference.get();
if (result == null) {
result = new EnumValueDescriptor(this, key);
unknownValues.put(key, new WeakReference<EnumValueDescriptor>(result));
result = new EnumValueDescriptor(this, number);
unknownValues.put(number, new UnknownEnumValueReference(number, result));
}
}
return result;
@ -1882,8 +1876,8 @@ public final class Descriptors {
private final EnumValueDescriptor[] values;
private final EnumValueDescriptor[] valuesSortedByNumber;
private final int distinctNumbers;
private final WeakHashMap<Integer, WeakReference<EnumValueDescriptor>> unknownValues =
new WeakHashMap<>();
private Map<Integer, WeakReference<EnumValueDescriptor>> unknownValues = null;
private ReferenceQueue<EnumValueDescriptor> cleanupQueue = null;
private EnumDescriptor(
final EnumDescriptorProto proto,

View File

@ -54,6 +54,7 @@ public final class Internal {
private Internal() {}
static final Charset US_ASCII = Charset.forName("US-ASCII");
static final Charset UTF_8 = Charset.forName("UTF-8");
static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");

View File

@ -134,7 +134,7 @@ public class InvalidProtocolBufferException extends IOException {
return new InvalidWireTypeException("Protocol message tag had invalid wire type.");
}
/** Exception indicating that and unexpected wire type was encountered for a field. */
/** Exception indicating that an unexpected wire type was encountered for a field. */
@ExperimentalApi
public static class InvalidWireTypeException extends InvalidProtocolBufferException {
private static final long serialVersionUID = 3283890091615336259L;

View File

@ -187,10 +187,10 @@ final class MessageLiteToString {
return ((Integer) o) == 0;
}
if (o instanceof Float) {
return ((Float) o) == 0f;
return Float.floatToRawIntBits((Float) o) == 0;
}
if (o instanceof Double) {
return ((Double) o) == 0d;
return Double.doubleToRawLongBits((Double) o) == 0;
}
if (o instanceof String) {
return o.equals("");

View File

@ -5808,9 +5808,9 @@ final class MessageSchema<T> implements Schema<T> {
final long offset = offset(typeAndOffset);
switch (type(typeAndOffset)) {
case 0: // DOUBLE:
return UnsafeUtil.getDouble(message, offset) != 0D;
return Double.doubleToRawLongBits(UnsafeUtil.getDouble(message, offset)) != 0L;
case 1: // FLOAT:
return UnsafeUtil.getFloat(message, offset) != 0F;
return Float.floatToRawIntBits(UnsafeUtil.getFloat(message, offset)) != 0;
case 2: // INT64:
return UnsafeUtil.getLong(message, offset) != 0L;
case 3: // UINT64:

View File

@ -68,13 +68,13 @@ final class SchemaUtil {
}
public static void writeDouble(int fieldNumber, double value, Writer writer) throws IOException {
if (Double.compare(value, 0.0) != 0) {
if (Double.doubleToRawLongBits(value) != 0) {
writer.writeDouble(fieldNumber, value);
}
}
public static void writeFloat(int fieldNumber, float value, Writer writer) throws IOException {
if (Float.compare(value, 0.0f) != 0) {
if (Float.floatToRawIntBits(value) != 0) {
writer.writeFloat(fieldNumber, value);
}
}

View File

@ -90,7 +90,7 @@ public class TextFormatParseInfoTree {
/**
* Retrieve all the locations of a field.
*
* @param fieldDescriptor the @{link FieldDescriptor} of the desired field
* @param fieldDescriptor the {@link FieldDescriptor} of the desired field
* @return a list of the locations of values of the field. If there are not values or the field
* doesn't exist, an empty list is returned.
*/
@ -105,7 +105,7 @@ public class TextFormatParseInfoTree {
* <p>Returns the {@link TextFormatParseLocation} for index-th value of the field in the parsed
* text.
*
* @param fieldDescriptor the @{link FieldDescriptor} of the desired field
* @param fieldDescriptor the {@link FieldDescriptor} of the desired field
* @param index the index of the value.
* @return the {@link TextFormatParseLocation} of the value
* @throws IllegalArgumentException index is out of range
@ -117,7 +117,7 @@ public class TextFormatParseInfoTree {
/**
* Retrieve a list of all the location information trees for a sub message field.
*
* @param fieldDescriptor the @{link FieldDescriptor} of the desired field
* @param fieldDescriptor the {@link FieldDescriptor} of the desired field
* @return A list of {@link TextFormatParseInfoTree}
*/
public List<TextFormatParseInfoTree> getNestedTrees(final FieldDescriptor fieldDescriptor) {
@ -128,7 +128,7 @@ public class TextFormatParseInfoTree {
/**
* Returns the parse info tree for the given field, which must be a message type.
*
* @param fieldDescriptor the @{link FieldDescriptor} of the desired sub message
* @param fieldDescriptor the {@link FieldDescriptor} of the desired sub message
* @param index the index of message value.
* @return the {@code ParseInfoTree} of the message value. {@code null} is returned if the field
* doesn't exist or the index is out of range.

View File

@ -1371,29 +1371,39 @@ final class Utf8 {
String.format("buffer length=%d, index=%d, size=%d", bytes.length, index, size));
}
int offset = index;
final int limit = offset + size;
int offset = index + unsafeEstimateConsecutiveAscii(bytes, index, size);
final int limit = index + size;
// The longest possible resulting String is the same as the number of input bytes, when it is
// all ASCII. For other cases, this over-allocates and we will truncate in the end.
char[] resultArr = new char[size];
int resultPos = 0;
// Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
// This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
// get an "exact" consecutive ASCII
while (offset < limit) {
byte b = UnsafeUtil.getByte(bytes, offset);
if (!DecodeUtil.isOneByte(b)) {
if (b < 0) {
break;
}
offset++;
DecodeUtil.handleOneByte(b, resultArr, resultPos++);
}
if (offset == limit) {
// The entire byte sequence is ASCII. Don't bother copying to a char[], JVMs using
// compact strings will just turn it back into the same byte[].
return new String(bytes, index, size, Internal.US_ASCII);
}
// It's not all ASCII, at this point. This may over-allocate, but we will truncate in the
// end.
char[] resultArr = new char[size];
int resultPos = 0;
// Copy over the initial run of ASCII.
for (int i = index; i < offset; i++) {
DecodeUtil.handleOneByte(UnsafeUtil.getByte(bytes, i), resultArr, resultPos++);
}
while (offset < limit) {
byte byte1 = UnsafeUtil.getByte(bytes, offset++);
if (DecodeUtil.isOneByte(byte1)) {
DecodeUtil.handleOneByte(byte1, resultArr, resultPos++);
// It's common for there to be multiple ASCII characters in a run mixed in, so add an
// extra optimized loop to take care of these runs.
while (offset < limit) {
@ -1656,7 +1666,17 @@ final class Utf8 {
return 0;
}
for (int i = 0; i < maxChars; i++) {
int i;
for (i = 0; i + 8 <= maxChars; i += 8) {
if ((UnsafeUtil.getLong(bytes, UnsafeUtil.BYTE_ARRAY_BASE_OFFSET + offset)
& ASCII_MASK_LONG)
!= 0L) {
break;
}
offset += 8;
}
for (; i < maxChars; i++) {
if (UnsafeUtil.getByte(bytes, offset++) < 0) {
return i;
}

View File

@ -49,7 +49,7 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class CheckUtf8Test {
private static final String UTF8_BYTE_STRING_TEXT = "some text";
private static final String UTF8_BYTE_STRING_TEXT = "some text π \uD83D\uDE00";
private static final ByteString UTF8_BYTE_STRING = ByteString.copyFromUtf8(UTF8_BYTE_STRING_TEXT);
private static final ByteString NON_UTF8_BYTE_STRING =
ByteString.copyFrom(new byte[] {(byte) 0x80}); // A lone continuation byte.

View File

@ -1,3 +1,33 @@
// 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 com.google.protobuf.Utf8.Processor;
@ -28,12 +58,13 @@ public class DecodeUtf8Test extends TestCase {
public void testOneByte() throws Exception {
int valid = 0;
ByteBuffer buffer = ByteBuffer.allocateDirect(1);
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
ByteString bs = ByteString.copyFrom(new byte[] { (byte) i });
if (!bs.isValidUtf8()) {
assertInvalid(bs.toByteArray());
} else {
ByteString bs = ByteString.copyFrom(new byte[] {(byte) i});
if (bs.isValidUtf8()) {
valid++;
} else {
assertInvalid(bs.toByteArray(), buffer);
}
}
assertEquals(IsValidUtf8TestUtil.EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, valid);
@ -41,13 +72,14 @@ public class DecodeUtf8Test extends TestCase {
public void testTwoBytes() throws Exception {
int valid = 0;
ByteBuffer buffer = ByteBuffer.allocateDirect(2);
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
for (int j = Byte.MIN_VALUE; j <= Byte.MAX_VALUE; j++) {
ByteString bs = ByteString.copyFrom(new byte[]{(byte) i, (byte) j});
if (!bs.isValidUtf8()) {
assertInvalid(bs.toByteArray());
} else {
ByteString bs = ByteString.copyFrom(new byte[] {(byte) i, (byte) j});
if (bs.isValidUtf8()) {
valid++;
} else {
assertInvalid(bs.toByteArray(), buffer);
}
}
}
@ -55,34 +87,30 @@ public class DecodeUtf8Test extends TestCase {
}
public void testThreeBytes() throws Exception {
// Travis' OOM killer doesn't like this test
if (System.getenv("TRAVIS") == null) {
int count = 0;
int valid = 0;
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
for (int j = Byte.MIN_VALUE; j <= Byte.MAX_VALUE; j++) {
for (int k = Byte.MIN_VALUE; k <= Byte.MAX_VALUE; k++) {
byte[] bytes = new byte[]{(byte) i, (byte) j, (byte) k};
ByteString bs = ByteString.copyFrom(bytes);
if (!bs.isValidUtf8()) {
assertInvalid(bytes);
} else {
valid++;
}
count++;
if (count % 1000000L == 0) {
logger.info("Processed " + (count / 1000000L) + " million characters");
}
int count = 0;
int valid = 0;
ByteBuffer buffer = ByteBuffer.allocateDirect(3);
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
for (int j = Byte.MIN_VALUE; j <= Byte.MAX_VALUE; j++) {
for (int k = Byte.MIN_VALUE; k <= Byte.MAX_VALUE; k++) {
byte[] bytes = new byte[] {(byte) i, (byte) j, (byte) k};
ByteString bs = ByteString.copyFrom(bytes);
if (bs.isValidUtf8()) {
valid++;
} else {
assertInvalid(bytes, buffer);
}
count++;
if (count % 1000000L == 0) {
logger.info("Processed " + (count / 1000000L) + " million characters");
}
}
}
assertEquals(IsValidUtf8TestUtil.EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT, valid);
}
assertEquals(IsValidUtf8TestUtil.EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT, valid);
}
/**
* Tests that round tripping of a sample of four byte permutations work.
*/
/** Tests that round tripping of a sample of four byte permutations work. */
public void testInvalid_4BytesSamples() throws Exception {
// Bad trailing bytes
assertInvalid(0xF0, 0xA4, 0xAD, 0x7F);
@ -99,8 +127,7 @@ public class DecodeUtf8Test extends TestCase {
// German
assertRoundTrips("Quizdeltagerne spiste jordb\u00e6r med fl\u00f8de, mens cirkusklovnen");
// Japanese
assertRoundTrips(
"\u3044\u308d\u306f\u306b\u307b\u3078\u3068\u3061\u308a\u306c\u308b\u3092");
assertRoundTrips("\u3044\u308d\u306f\u306b\u307b\u3078\u3068\u3061\u308a\u306c\u308b\u3092");
// Hebrew
assertRoundTrips(
"\u05d3\u05d2 \u05e1\u05e7\u05e8\u05df \u05e9\u05d8 \u05d1\u05d9\u05dd "
@ -115,9 +142,10 @@ public class DecodeUtf8Test extends TestCase {
assertRoundTrips(
"\u8fd4\u56de\u94fe\u4e2d\u7684\u4e0b\u4e00\u4e2a\u4ee3\u7406\u9879\u9009\u62e9\u5668");
// Chinese with 4-byte chars
assertRoundTrips("\uD841\uDF0E\uD841\uDF31\uD841\uDF79\uD843\uDC53\uD843\uDC78"
+ "\uD843\uDC96\uD843\uDCCF\uD843\uDCD5\uD843\uDD15\uD843\uDD7C\uD843\uDD7F"
+ "\uD843\uDE0E\uD843\uDE0F\uD843\uDE77\uD843\uDE9D\uD843\uDEA2");
assertRoundTrips(
"\uD841\uDF0E\uD841\uDF31\uD841\uDF79\uD843\uDC53\uD843\uDC78"
+ "\uD843\uDC96\uD843\uDCCF\uD843\uDCD5\uD843\uDD15\uD843\uDD7C\uD843\uDD7F"
+ "\uD843\uDE0E\uD843\uDE0F\uD843\uDE77\uD843\uDE9D\uD843\uDEA2");
// Mixed
assertRoundTrips(
"The quick brown \u3044\u308d\u306f\u306b\u307b\u3078\u8fd4\u56de\u94fe"
@ -132,7 +160,7 @@ public class DecodeUtf8Test extends TestCase {
// Max overlong
assertInvalid(0xc1, 0xbf);
assertInvalid(0xe0, 0x9f, 0xbf);
assertInvalid(0xf0 ,0x8f, 0xbf, 0xbf);
assertInvalid(0xf0, 0x8f, 0xbf, 0xbf);
// null overlong
assertInvalid(0xc0, 0x80);
@ -168,7 +196,7 @@ public class DecodeUtf8Test extends TestCase {
}
public void testInvalidBufferSlice() throws Exception {
byte[] bytes = "The quick brown fox jumps over the lazy dog".getBytes(Internal.UTF_8);
byte[] bytes = "The quick brown fox jumps over the lazy dog".getBytes(Internal.UTF_8);
assertInvalidSlice(bytes, bytes.length - 3, 4);
assertInvalidSlice(bytes, bytes.length, 1);
assertInvalidSlice(bytes, bytes.length + 1, 0);
@ -180,10 +208,14 @@ public class DecodeUtf8Test extends TestCase {
for (int i = 0; i < bytesAsInt.length; i++) {
bytes[i] = (byte) bytesAsInt[i];
}
assertInvalid(bytes);
assertInvalid(bytes, null);
}
private void assertInvalid(byte[] bytes) throws Exception {
// Attempts to decode the byte array in several ways and asserts that it always generates an
// exception. Allocating a direct ByteBuffer is slow, so the caller can optionally provide a
// buffer to reuse. If buffer is non-null, it must be a direct-allocated ByteBuffer of the
// appropriate size.
private void assertInvalid(byte[] bytes, ByteBuffer buffer) throws Exception {
try {
UNSAFE_PROCESSOR.decodeUtf8(bytes, 0, bytes.length);
fail();
@ -197,37 +229,24 @@ public class DecodeUtf8Test extends TestCase {
// Expected.
}
ByteBuffer direct = ByteBuffer.allocateDirect(bytes.length);
direct.put(bytes);
direct.flip();
if (buffer == null) {
buffer = ByteBuffer.allocateDirect(bytes.length);
}
buffer.put(bytes);
buffer.flip();
try {
UNSAFE_PROCESSOR.decodeUtf8(direct, 0, bytes.length);
UNSAFE_PROCESSOR.decodeUtf8(buffer, 0, bytes.length);
fail();
} catch (InvalidProtocolBufferException e) {
// Expected.
}
try {
SAFE_PROCESSOR.decodeUtf8(direct, 0, bytes.length);
fail();
} catch (InvalidProtocolBufferException e) {
// Expected.
}
ByteBuffer heap = ByteBuffer.allocate(bytes.length);
heap.put(bytes);
heap.flip();
try {
UNSAFE_PROCESSOR.decodeUtf8(heap, 0, bytes.length);
fail();
} catch (InvalidProtocolBufferException e) {
// Expected.
}
try {
SAFE_PROCESSOR.decodeUtf8(heap, 0, bytes.length);
SAFE_PROCESSOR.decodeUtf8(buffer, 0, bytes.length);
fail();
} catch (InvalidProtocolBufferException e) {
// Expected.
}
buffer.clear();
}
private void assertInvalidSlice(byte[] bytes, int index, int size) throws Exception {
@ -286,25 +305,31 @@ public class DecodeUtf8Test extends TestCase {
if (size == -1) {
size = bytes.length;
}
assertDecode(new String(bytes, index, size, Internal.UTF_8),
assertDecode(
new String(bytes, index, size, Internal.UTF_8),
UNSAFE_PROCESSOR.decodeUtf8(bytes, index, size));
assertDecode(new String(bytes, index, size, Internal.UTF_8),
assertDecode(
new String(bytes, index, size, Internal.UTF_8),
SAFE_PROCESSOR.decodeUtf8(bytes, index, size));
ByteBuffer direct = ByteBuffer.allocateDirect(bytes.length);
direct.put(bytes);
direct.flip();
assertDecode(new String(bytes, index, size, Internal.UTF_8),
assertDecode(
new String(bytes, index, size, Internal.UTF_8),
UNSAFE_PROCESSOR.decodeUtf8(direct, index, size));
assertDecode(new String(bytes, index, size, Internal.UTF_8),
assertDecode(
new String(bytes, index, size, Internal.UTF_8),
SAFE_PROCESSOR.decodeUtf8(direct, index, size));
ByteBuffer heap = ByteBuffer.allocate(bytes.length);
heap.put(bytes);
heap.flip();
assertDecode(new String(bytes, index, size, Internal.UTF_8),
assertDecode(
new String(bytes, index, size, Internal.UTF_8),
UNSAFE_PROCESSOR.decodeUtf8(heap, index, size));
assertDecode(new String(bytes, index, size, Internal.UTF_8),
assertDecode(
new String(bytes, index, size, Internal.UTF_8),
SAFE_PROCESSOR.decodeUtf8(heap, index, size));
}
@ -321,5 +346,4 @@ public class DecodeUtf8Test extends TestCase {
}
return codepoints;
}
}

View File

@ -36,6 +36,7 @@ import static com.google.protobuf.IsValidUtf8TestUtil.EXPECTED_ONE_BYTE_ROUNDTRI
import static com.google.protobuf.IsValidUtf8TestUtil.EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT;
import static com.google.protobuf.IsValidUtf8TestUtil.HEAP_NIO_FACTORY;
import static com.google.protobuf.IsValidUtf8TestUtil.LITERAL_FACTORY;
import static com.google.protobuf.IsValidUtf8TestUtil.ROPE_FACTORY;
import static com.google.protobuf.IsValidUtf8TestUtil.testBytes;
import com.google.protobuf.IsValidUtf8TestUtil.ByteStringFactory;
@ -61,6 +62,7 @@ public class IsValidUtf8Test {
testBytes(LITERAL_FACTORY, 1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(HEAP_NIO_FACTORY, 1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(DIRECT_NIO_FACTORY, 1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(ROPE_FACTORY, 1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT);
}
/** Tests that round tripping of all two byte permutations work. */
@ -69,17 +71,16 @@ public class IsValidUtf8Test {
testBytes(LITERAL_FACTORY, 2, IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(HEAP_NIO_FACTORY, 2, IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(DIRECT_NIO_FACTORY, 2, IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(ROPE_FACTORY, 2, IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT);
}
/** Tests that round tripping of all three byte permutations work. */
@Test
public void testIsValidUtf8_3Bytes() {
// Travis' OOM killer doesn't like this test
if (System.getenv("TRAVIS") == null) {
testBytes(LITERAL_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(HEAP_NIO_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(DIRECT_NIO_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
}
testBytes(LITERAL_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(HEAP_NIO_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(DIRECT_NIO_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
testBytes(ROPE_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
}
/**
@ -168,12 +169,14 @@ public class IsValidUtf8Test {
assertValidUtf8(LITERAL_FACTORY, bytes, false);
assertValidUtf8(HEAP_NIO_FACTORY, bytes, false);
assertValidUtf8(DIRECT_NIO_FACTORY, bytes, false);
assertValidUtf8(ROPE_FACTORY, bytes, false);
}
private void assertInvalidUtf8(int... bytes) {
assertValidUtf8(LITERAL_FACTORY, bytes, true);
assertValidUtf8(HEAP_NIO_FACTORY, bytes, true);
assertValidUtf8(DIRECT_NIO_FACTORY, bytes, true);
assertValidUtf8(ROPE_FACTORY, bytes, true);
}
private static ByteString asBytes(String s) {

View File

@ -35,16 +35,10 @@ import static com.google.common.truth.Truth.assertWithMessage;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.logging.Logger;
/**
* Shared testing code for {@link IsValidUtf8Test} and {@link IsValidUtf8FourByteTest}.
@ -53,8 +47,6 @@ import java.util.logging.Logger;
* @author martinrb@google.com (Martin Buchholz)
*/
final class IsValidUtf8TestUtil {
private static final Logger logger = Logger.getLogger(IsValidUtf8TestUtil.class.getName());
private IsValidUtf8TestUtil() {}
static interface ByteStringFactory {
@ -102,6 +94,29 @@ final class IsValidUtf8TestUtil {
}
};
static final ByteStringFactory ROPE_FACTORY =
new ByteStringFactory() {
// Seed the random number generator with 0 so that the tests are deterministic.
private final Random random = new Random(0);
@Override
public ByteString newByteString(byte[] bytes) {
// We split the byte array into three pieces (some possibly empty) by choosing two random
// cut points i and j.
int i = random.nextInt(bytes.length);
int j = random.nextInt(bytes.length);
if (j < i) {
int tmp = i;
i = j;
j = tmp;
}
return RopeByteString.newInstanceForTest(
ByteString.wrap(bytes, 0, i),
RopeByteString.newInstanceForTest(
ByteString.wrap(bytes, i, j - i), ByteString.wrap(bytes, j, bytes.length - j)));
}
};
// 128 - [chars 0x0000 to 0x007f]
static final long ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x007f - 0x0000 + 1;
@ -247,13 +262,11 @@ final class IsValidUtf8TestUtil {
*/
static void testBytes(
ByteStringFactory factory, int numBytes, long expectedCount, long start, long lim) {
Random rnd = new Random();
byte[] bytes = new byte[numBytes];
if (lim == -1) {
lim = 1L << (numBytes * 8);
}
long count = 0;
long countRoundTripped = 0;
for (long byteChar = start; byteChar < lim; byteChar++) {
long tmpByteChar = byteChar;
@ -271,166 +284,13 @@ final class IsValidUtf8TestUtil {
outputFailure(byteChar, bytes, bytesReencoded);
}
// Check agreement with static Utf8 methods.
// Check agreement with Utf8.isValidUtf8.
assertThat(Utf8.isValidUtf8(bytes)).isEqualTo(isRoundTrippable);
assertThat(Utf8.isValidUtf8(bytes, 0, numBytes)).isEqualTo(isRoundTrippable);
try {
assertThat(Utf8.decodeUtf8(bytes, 0, numBytes)).isEqualTo(s);
} catch (InvalidProtocolBufferException e) {
if (isRoundTrippable) {
System.out.println("Could not decode utf-8");
outputFailure(byteChar, bytes, bytesReencoded);
}
}
// Test partial sequences.
// Partition numBytes into three segments (not necessarily non-empty).
int i = rnd.nextInt(numBytes);
int j = rnd.nextInt(numBytes);
if (j < i) {
int tmp = i;
i = j;
j = tmp;
}
int state1 = Utf8.partialIsValidUtf8(Utf8.COMPLETE, bytes, 0, i);
int state2 = Utf8.partialIsValidUtf8(state1, bytes, i, j);
int state3 = Utf8.partialIsValidUtf8(state2, bytes, j, numBytes);
if (isRoundTrippable != (state3 == Utf8.COMPLETE)) {
System.out.printf("state=%04x %04x %04x i=%d j=%d%n", state1, state2, state3, i, j);
outputFailure(byteChar, bytes, bytesReencoded);
}
assertThat((state3 == Utf8.COMPLETE)).isEqualTo(isRoundTrippable);
// Test ropes built out of small partial sequences
ByteString rope =
RopeByteString.newInstanceForTest(
bs.substring(0, i),
RopeByteString.newInstanceForTest(bs.substring(i, j), bs.substring(j, numBytes)));
assertThat(rope.getClass()).isSameInstanceAs(RopeByteString.class);
ByteString[] byteStrings = {bs, bs.substring(0, numBytes), rope};
for (ByteString x : byteStrings) {
assertThat(x.isValidUtf8()).isEqualTo(isRoundTrippable);
assertThat(x.partialIsValidUtf8(Utf8.COMPLETE, 0, numBytes)).isEqualTo(state3);
assertThat(x.partialIsValidUtf8(Utf8.COMPLETE, 0, i)).isEqualTo(state1);
assertThat(x.substring(0, i).partialIsValidUtf8(Utf8.COMPLETE, 0, i)).isEqualTo(state1);
assertThat(x.partialIsValidUtf8(state1, i, j - i)).isEqualTo(state2);
assertThat(x.substring(i, j).partialIsValidUtf8(state1, 0, j - i)).isEqualTo(state2);
assertThat(x.partialIsValidUtf8(state2, j, numBytes - j)).isEqualTo(state3);
assertThat(x.substring(j, numBytes).partialIsValidUtf8(state2, 0, numBytes - j))
.isEqualTo(state3);
}
// ByteString reduplication should not affect its UTF-8 validity.
ByteString ropeADope = RopeByteString.newInstanceForTest(bs, bs.substring(0, numBytes));
assertThat(ropeADope.isValidUtf8()).isEqualTo(isRoundTrippable);
if (isRoundTrippable) {
countRoundTripped++;
}
count++;
if (byteChar != 0 && byteChar % 1000000L == 0) {
logger.info("Processed " + (byteChar / 1000000L) + " million characters");
}
}
logger.info("Round tripped " + countRoundTripped + " of " + count);
assertThat(countRoundTripped).isEqualTo(expectedCount);
}
/**
* Variation of {@link #testBytes} that does less allocation using the low-level encoders/decoders
* directly. Checked in because it's useful for debugging when trying to process bytes faster, but
* since it doesn't use the actual String class, it's possible for incompatibilities to develop
* (although unlikely).
*
* @param factory the factory for {@link ByteString} instances.
* @param numBytes the number of bytes in the byte array
* @param expectedCount the expected number of roundtrippable permutations
* @param start the starting bytes encoded as a long as big-endian
* @param lim the limit of bytes to process encoded as a long as big-endian, or -1 to mean the max
* limit for numBytes
*/
static void testBytesUsingByteBuffers(
ByteStringFactory factory, int numBytes, long expectedCount, long start, long lim) {
CharsetDecoder decoder =
Internal.UTF_8
.newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
CharsetEncoder encoder =
Internal.UTF_8
.newEncoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
byte[] bytes = new byte[numBytes];
int maxChars = (int) (decoder.maxCharsPerByte() * numBytes) + 1;
char[] charsDecoded = new char[(int) (decoder.maxCharsPerByte() * numBytes) + 1];
int maxBytes = (int) (encoder.maxBytesPerChar() * maxChars) + 1;
byte[] bytesReencoded = new byte[maxBytes];
ByteBuffer bb = ByteBuffer.wrap(bytes);
CharBuffer cb = CharBuffer.wrap(charsDecoded);
ByteBuffer bbReencoded = ByteBuffer.wrap(bytesReencoded);
if (lim == -1) {
lim = 1L << (numBytes * 8);
}
long count = 0;
long countRoundTripped = 0;
for (long byteChar = start; byteChar < lim; byteChar++) {
bb.rewind();
bb.limit(bytes.length);
cb.rewind();
cb.limit(charsDecoded.length);
bbReencoded.rewind();
bbReencoded.limit(bytesReencoded.length);
encoder.reset();
decoder.reset();
long tmpByteChar = byteChar;
for (int i = 0; i < bytes.length; i++) {
bytes[bytes.length - i - 1] = (byte) tmpByteChar;
tmpByteChar = tmpByteChar >> 8;
}
boolean isRoundTrippable = factory.newByteString(bytes).isValidUtf8();
CoderResult result = decoder.decode(bb, cb, true);
assertThat(result.isError()).isFalse();
result = decoder.flush(cb);
assertThat(result.isError()).isFalse();
int charLen = cb.position();
cb.rewind();
cb.limit(charLen);
result = encoder.encode(cb, bbReencoded, true);
assertThat(result.isError()).isFalse();
result = encoder.flush(bbReencoded);
assertThat(result.isError()).isFalse();
boolean bytesEqual = true;
int bytesLen = bbReencoded.position();
if (bytesLen != numBytes) {
bytesEqual = false;
} else {
for (int i = 0; i < numBytes; i++) {
if (bytes[i] != bytesReencoded[i]) {
bytesEqual = false;
break;
}
}
}
if (bytesEqual != isRoundTrippable) {
outputFailure(byteChar, bytes, bytesReencoded, bytesLen);
}
count++;
if (isRoundTrippable) {
countRoundTripped++;
}
if (byteChar != 0 && byteChar % 1000000 == 0) {
logger.info("Processed " + (byteChar / 1000000) + " million characters");
}
}
logger.info("Round tripped " + countRoundTripped + " of " + count);
assertThat(countRoundTripped).isEqualTo(expectedCount);
}

View File

@ -380,4 +380,34 @@ public class MessageTest {
result.getDescriptorForType().findFieldByName("repeated_foreign_message")))
.isEqualTo(2);
}
@Test
public void testPreservesFloatingPointNegative0() throws Exception {
proto3_unittest.UnittestProto3.TestAllTypes message =
proto3_unittest.UnittestProto3.TestAllTypes.newBuilder()
.setOptionalFloat(-0.0f)
.setOptionalDouble(-0.0)
.build();
assertThat(
proto3_unittest.UnittestProto3.TestAllTypes.parseFrom(
message.toByteString(), ExtensionRegistry.getEmptyRegistry()))
.isEqualTo(message);
}
@Test
public void testNegative0FloatingPointEquality() throws Exception {
// Like Double#equals and Float#equals, we treat -0.0 as not being equal to +0.0 even though
// IEEE 754 mandates that they are equivalent. This test asserts that behavior.
proto3_unittest.UnittestProto3.TestAllTypes message1 =
proto3_unittest.UnittestProto3.TestAllTypes.newBuilder()
.setOptionalFloat(-0.0f)
.setOptionalDouble(-0.0)
.build();
proto3_unittest.UnittestProto3.TestAllTypes message2 =
proto3_unittest.UnittestProto3.TestAllTypes.newBuilder()
.setOptionalFloat(0.0f)
.setOptionalDouble(0.0)
.build();
assertThat(message1).isNotEqualTo(message2);
}
}

View File

@ -46,9 +46,9 @@ import protobuf_unittest.UnittestProto.TestService;
import protobuf_unittest.no_generic_services_test.UnittestNoGenericServices;
import java.util.HashSet;
import java.util.Set;
import org.easymock.classextension.EasyMock;
import org.easymock.EasyMock;
import org.easymock.IArgumentMatcher;
import org.easymock.classextension.IMocksControl;
import org.easymock.IMocksControl;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -80,7 +80,7 @@ public class ServiceTest {
BarRequest barRequest = BarRequest.newBuilder().build();
MockCallback<Message> fooCallback = new MockCallback<Message>();
MockCallback<Message> barCallback = new MockCallback<Message>();
TestService mockService = control.createMock(TestService.class);
TestService mockService = EasyMock.createMock(TestService.class);
mockService.foo(
EasyMock.same(mockController),
@ -104,7 +104,7 @@ public class ServiceTest {
/** Tests Service.get{Request,Response}Prototype(). */
@Test
public void testGetPrototype() throws Exception {
TestService mockService = control.createMock(TestService.class);
TestService mockService = EasyMock.createMock(TestService.class);
assertThat(mockService.getRequestPrototype(fooDescriptor))
.isSameInstanceAs(FooRequest.getDefaultInstance());
@ -316,7 +316,6 @@ public class ServiceTest {
}
@Override
@SuppressWarnings("unchecked")
public boolean matches(Object actual) {
if (!(actual instanceof RpcCallback)) {
return false;

View File

@ -41,7 +41,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Test @{link TextFormatParseInfoTree}. */
/** Test {@link TextFormatParseInfoTree}. */
@RunWith(JUnit4.class)
public class TextFormatParseInfoTreeTest {

View File

@ -37,7 +37,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Test @{link TextFormatParseLocation}. */
/** Test {@link TextFormatParseLocation}. */
@RunWith(JUnit4.class)
public class TextFormatParseLocationTest {

View File

@ -1815,4 +1815,15 @@ public class TextFormatTest {
+ "}\n";
assertThat(TextFormat.printer().printToString(message)).isEqualTo(text);
}
@Test
public void testPreservesFloatingPointNegative0() throws Exception {
proto3_unittest.UnittestProto3.TestAllTypes message =
proto3_unittest.UnittestProto3.TestAllTypes.newBuilder()
.setOptionalFloat(-0.0f)
.setOptionalDouble(-0.0)
.build();
assertThat(TextFormat.printer().printToString(message))
.isEqualTo("optional_float: -0.0\noptional_double: -0.0\n");
}
}

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.17.3</version>
<version>3.18.1</version>
</parent>
<artifactId>protobuf-kotlin-lite</artifactId>
@ -35,11 +35,6 @@
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.17.3</version>
<version>3.18.1</version>
</parent>
<artifactId>protobuf-kotlin</artifactId>
@ -34,11 +34,6 @@
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.17.3</version>
<version>3.18.1</version>
</parent>
<artifactId>protobuf-javalite</artifactId>
@ -27,11 +27,6 @@
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
@ -104,6 +99,8 @@
<include>ByteBufferWriter.java</include>
<include>ByteOutput.java</include>
<include>ByteString.java</include>
<include>CanIgnoreReturnValue.java</include>
<include>CheckReturnValue.java</include>
<include>CodedInputStream.java</include>
<include>CodedInputStreamReader.java</include>
<include>CodedOutputStream.java</include>

View File

@ -2752,6 +2752,36 @@ public class LiteTest {
.isTrue();
}
@Test
public void testPreservesFloatingPointNegative0() throws Exception {
proto3_unittest.UnittestProto3.TestAllTypes message =
proto3_unittest.UnittestProto3.TestAllTypes.newBuilder()
.setOptionalFloat(-0.0f)
.setOptionalDouble(-0.0)
.build();
assertThat(
proto3_unittest.UnittestProto3.TestAllTypes.parseFrom(
message.toByteString(), ExtensionRegistryLite.getEmptyRegistry()))
.isEqualTo(message);
}
@Test
public void testNegative0FloatingPointEquality() throws Exception {
// Like Double#equals and Float#equals, we treat -0.0 as not being equal to +0.0 even though
// IEEE 754 mandates that they are equivalent. This test asserts that behavior.
proto3_unittest.UnittestProto3.TestAllTypes message1 =
proto3_unittest.UnittestProto3.TestAllTypes.newBuilder()
.setOptionalFloat(-0.0f)
.setOptionalDouble(-0.0)
.build();
proto3_unittest.UnittestProto3.TestAllTypes message2 =
proto3_unittest.UnittestProto3.TestAllTypes.newBuilder()
.setOptionalFloat(0.0f)
.setOptionalDouble(0.0)
.build();
assertThat(message1).isNotEqualTo(message2);
}
private String encodeHex(ByteString bytes) {
String hexDigits = "0123456789abcdef";
StringBuilder stringBuilder = new StringBuilder(bytes.size() * 2);

View File

@ -4,7 +4,7 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.17.3</version>
<version>3.18.1</version>
<packaging>pom</packaging>
<name>Protocol Buffers [Parent]</name>
@ -81,13 +81,7 @@
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<version>2.2.1</version>
<version>3.2</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.17.3</version>
<version>3.18.1</version>
</parent>
<artifactId>protobuf-java-util</artifactId>
@ -50,10 +50,6 @@
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
</dependency>
<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>

View File

@ -46,6 +46,7 @@ import com.google.protobuf.Message;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
/**
* Utility helper functions to work with {@link com.google.protobuf.FieldMask}.
@ -230,10 +231,8 @@ public final class FieldMaskUtil {
return isValid(descriptor, path);
}
/**
* Checks whether paths in a given fields mask are valid.
*/
public static boolean isValid(Descriptor descriptor, String path) {
/** Checks whether paths in a given fields mask are valid. */
public static boolean isValid(@Nullable Descriptor descriptor, String path) {
String[] parts = path.split(FIELD_SEPARATOR_REGEX);
if (parts.length == 0) {
return false;

View File

@ -88,6 +88,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.logging.Logger;
import javax.annotation.Nullable;
/**
* Utility classes to convert protobuf messages to/from JSON format. The JSON
@ -521,10 +522,12 @@ public class JsonFormat {
* Find a type by its full name. Returns null if it cannot be found in this {@link
* TypeRegistry}.
*/
@Nullable
public Descriptor find(String name) {
return types.get(name);
}
@Nullable
Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException {
return find(getTypeName(typeUrl));
}
@ -546,7 +549,7 @@ public class JsonFormat {
*/
@CanIgnoreReturnValue
public Builder add(Descriptor messageType) {
if (types == null) {
if (built) {
throw new IllegalStateException("A TypeRegistry.Builder can only be used once.");
}
addFile(messageType.getFile());
@ -559,7 +562,7 @@ public class JsonFormat {
*/
@CanIgnoreReturnValue
public Builder add(Iterable<Descriptor> messageTypes) {
if (types == null) {
if (built) {
throw new IllegalStateException("A TypeRegistry.Builder can only be used once.");
}
for (Descriptor type : messageTypes) {
@ -573,10 +576,8 @@ public class JsonFormat {
* one Builder.
*/
public TypeRegistry build() {
TypeRegistry result = new TypeRegistry(types);
// Make sure the built {@link TypeRegistry} is immutable.
types = null;
return result;
built = true;
return new TypeRegistry(types);
}
private void addFile(FileDescriptor file) {
@ -607,6 +608,7 @@ public class JsonFormat {
private final Set<String> files = new HashSet<String>();
private Map<String, Descriptor> types = new HashMap<String, Descriptor>();
private boolean built = false;
}
}
@ -984,7 +986,7 @@ public class JsonFormat {
}
/** Prints a regular message with an optional type URL. */
private void print(MessageOrBuilder message, String typeUrl) throws IOException {
private void print(MessageOrBuilder message, @Nullable String typeUrl) throws IOException {
generator.print("{" + blankOrNewLine);
generator.indent();
@ -1340,7 +1342,9 @@ public class JsonFormat {
throw e;
} catch (Exception e) {
// We convert all exceptions from JSON parsing to our own exceptions.
throw new InvalidProtocolBufferException(e.getMessage());
InvalidProtocolBufferException toThrow = new InvalidProtocolBufferException(e.getMessage());
toThrow.initCause(e);
throw toThrow;
}
}
@ -1899,6 +1903,7 @@ public class JsonFormat {
}
}
@Nullable
private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement json)
throws InvalidProtocolBufferException {
String value = json.getAsString();
@ -1926,6 +1931,7 @@ public class JsonFormat {
return result;
}
@Nullable
private Object parseFieldValue(FieldDescriptor field, JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException {
if (json instanceof JsonNull) {

View File

@ -1887,4 +1887,12 @@ public class JsonFormatTest {
.print(message))
.isEqualTo("{\n" + " \"optionalBool\": false\n" + "}");
}
@Test
public void testPreservesFloatingPointNegative0() throws Exception {
TestAllTypes message =
TestAllTypes.newBuilder().setOptionalFloat(-0.0f).setOptionalDouble(-0.0).build();
assertThat(JsonFormat.printer().print(message))
.isEqualTo("{\n \"optionalFloat\": -0.0,\n \"optionalDouble\": -0.0\n}");
}
}

View File

@ -202,7 +202,11 @@ jspb.utils.splitFloat32 = function(value) {
exp = Math.floor(Math.log(value) / Math.LN2);
mant = value * Math.pow(2, -exp);
mant = Math.round(mant * jspb.BinaryConstants.TWO_TO_23) & 0x7FFFFF;
mant = Math.round(mant * jspb.BinaryConstants.TWO_TO_23);
if (mant >= 0x1000000) {
++exp;
}
mant = mant & 0x7FFFFF;
jspb.utils.split64High = 0;
jspb.utils.split64Low = ((sign << 31) | ((exp + 127) << 23) | mant) >>> 0;

View File

@ -391,6 +391,11 @@ describe('binaryUtilsTest', function() {
// Pi.
test(f32_pi, 0x40490fdb);
// corner cases
test(0.9999999762949594, 0x3f800000);
test(7.99999999999999, 0x41000000);
test(Math.sin(30 * Math.PI / 180), 0x3f000000); // sin(30 degrees)
// Various positive values.
var cursor = f32_eps * 10;
while (cursor != Infinity) {

View File

@ -1,6 +1,6 @@
{
"name": "google-protobuf",
"version": "3.17.3",
"version": "3.18.1",
"description": "Protocol Buffers for JavaScript",
"main": "google-protobuf.js",
"files": [

View File

@ -1,4 +1,4 @@
FROM debian:jessie
FROM debian:stretch
# Install dependencies. We start with the basic ones require to build protoc
# and the C++ build
@ -20,10 +20,13 @@ RUN apt-get update && apt-get install -y \
parallel \
time \
wget \
# Java dependencies
maven \
openjdk-8-jdk \
&& apt-get clean
# Install rvm
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys \
RUN gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys \
409B6B1796C275462A1703113804BB82D39DC0E3 \
7D2BAF1CF37B13E2069D6956105BD0E739499BDB
RUN \curl -sSL https://get.rvm.io | bash -s master
@ -34,6 +37,8 @@ RUN /bin/bash -l -c "rvm install 2.5.1"
RUN /bin/bash -l -c "rvm install 2.6.0"
RUN /bin/bash -l -c "rvm install 2.7.0"
RUN /bin/bash -l -c "rvm install 3.0.0"
RUN /bin/bash -l -c "rvm install jruby-9.2.19.0"
RUN /bin/bash -l -c "rvm install jruby-9.3.0.0"
RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"

18
kokoro/linux/jruby92/build.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
#
# This is the top-level script we give to Kokoro as the entry point for
# running the "pull request" project:
#
# This script selects a specific Dockerfile (for building a Docker image) and
# a script to run inside that image. Then we delegate to the general
# build_and_run_docker.sh script.
# Change to repo root
cd $(dirname $0)/../../..
export DOCKERHUB_ORGANIZATION=protobuftesting
export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/ruby
export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
export OUTPUT_DIR=testoutput
export TEST_SET="jruby92"
./kokoro/linux/build_and_run_docker.sh

View File

@ -0,0 +1,11 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/jruby92/build.sh"
timeout_mins: 120
action {
define_artifacts {
regex: "**/sponge_log.xml"
}
}

View File

@ -0,0 +1,11 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/jruby92/build.sh"
timeout_mins: 120
action {
define_artifacts {
regex: "**/sponge_log.xml"
}
}

18
kokoro/linux/jruby93/build.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
#
# This is the top-level script we give to Kokoro as the entry point for
# running the "pull request" project:
#
# This script selects a specific Dockerfile (for building a Docker image) and
# a script to run inside that image. Then we delegate to the general
# build_and_run_docker.sh script.
# Change to repo root
cd $(dirname $0)/../../..
export DOCKERHUB_ORGANIZATION=protobuftesting
export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/ruby
export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
export OUTPUT_DIR=testoutput
export TEST_SET="jruby93"
./kokoro/linux/build_and_run_docker.sh

View File

@ -0,0 +1,11 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/jruby93/build.sh"
timeout_mins: 120
action {
define_artifacts {
regex: "**/sponge_log.xml"
}
}

View File

@ -0,0 +1,11 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/jruby93/build.sh"
timeout_mins: 120
action {
define_artifacts {
regex: "**/sponge_log.xml"
}
}

View File

@ -15,6 +15,9 @@ docker run $(test -t 0 && echo "-it") -v$PWD:/workspace gcr.io/protobuf-build/ph
docker run $(test -t 0 && echo "-it") -v$PWD:/workspace gcr.io/protobuf-build/php/linux:7.4.18-dbg-14a06550010c0649bf69b6c9b803c1ca609bbb6d "composer test && composer test_c"
docker run $(test -t 0 && echo "-it") -v$PWD:/workspace gcr.io/protobuf-build/php/linux:8.0.5-dbg-14a06550010c0649bf69b6c9b803c1ca609bbb6d "composer test && composer test_c"
# Run specialized memory leak & multirequest tests.
docker run $(test -t 0 && echo "-it") -v$PWD:/workspace gcr.io/protobuf-build/php/linux:8.0.5-dbg-14a06550010c0649bf69b6c9b803c1ca609bbb6d "composer test_c && tests/multirequest.sh && tests/memory_leak_test.sh"
# Most of our tests use a debug build of PHP, but we do one build against an opt
# php just in case that surfaces anything unexpected.
docker run $(test -t 0 && echo "-it") -v$PWD:/workspace gcr.io/protobuf-build/php/linux:8.0.5-14a06550010c0649bf69b6c9b803c1ca609bbb6d "composer test && composer test_c"

View File

@ -6,7 +6,6 @@
cd $(dirname $0)/../../..
# Prepare worker environment to run tests
KOKORO_INSTALL_COCOAPODS=yes
source kokoro/macos/prepare_build_macos_rc
./tests.sh objectivec_cocoapods_integration

View File

@ -19,58 +19,6 @@ export DEVELOPER_DIR=/Applications/Xcode_11.3.app/Contents/Developer
export CC=gcc
export CXX=g++
##
# Brew: update, then upgrade the installed tools to current version and install
# some needed ones not in the Kokoro base image. This ensure current versions
# of CMake, autotools, etc.
# But first...
#
# The transitive deps of the installed tools need protobuf, but Kokoro manually
# installed it outside of brew so it needs to be removed so brew can install the
# tools (and a newer version of protobuf). g/kokoro-users/7FRvQMUdN40 about why
# it is a manual install vs. a brew install in the first place.
sudo rm -rf \
/usr/local/include/google/protobuf \
/usr/local/bin/protoc
# Likewise, updating python can have issues because of some existing binaries.
sudo rm -rf \
/usr/local/bin/2to3* \
/usr/local/bin/idle3* \
/usr/local/bin/pip3 \
/usr/local/bin/pydoc3* \
/usr/local/bin/python3* \
/usr/local/bin/pyvenv*
git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow
# This is needed to fix a conflict between the ilmbase and imath packages,
# which seem to conflict with each other by both trying to install
# libImath.dylib.
brew unlink ilmbase
brew update
brew upgrade
##
# Install Ruby
if [[ "${KOKORO_INSTALL_RUBY:-}" == "yes" ]] ; then
brew install ruby
fi
##
# Install Cocoapods
if [[ "${KOKORO_INSTALL_COCOAPODS:-}" == "yes" ]] ; then
# The existing cocoapods was installed via gem, but that doesn't work well
# with the overlap in deps with things managed by brew (errors around ruby
# versions, etc.); so remove it and install in via brew instead.
gem uninstall -a "$(gem list | grep cocoapods | cut -d ' ' -f 1)"
brew install cocoapods
fi
##
# Install Tox
@ -85,5 +33,5 @@ if [[ "${KOKORO_INSTALL_RVM:-}" == "yes" ]] ; then
curl -sSL https://rvm.io/mpapis.asc | gpg --import -
curl -sSL https://rvm.io/pkuczynski.asc | gpg --import -
curl -sSL https://get.rvm.io | bash -s master --ruby
curl -sSL https://get.rvm.io | bash -s stable --ruby
fi

View File

@ -6,7 +6,6 @@
cd $(dirname $0)/../../..
# Prepare worker environment to run tests
KOKORO_INSTALL_RUBY=yes
KOKORO_INSTALL_RVM=yes
source kokoro/macos/prepare_build_macos_rc

View File

@ -6,7 +6,6 @@
cd $(dirname $0)/../../..
# Prepare worker environment to run tests
KOKORO_INSTALL_RUBY=yes
KOKORO_INSTALL_RVM=yes
source kokoro/macos/prepare_build_macos_rc

View File

@ -6,7 +6,6 @@
cd $(dirname $0)/../../..
# Prepare worker environment to run tests
KOKORO_INSTALL_RUBY=yes
KOKORO_INSTALL_RVM=yes
source kokoro/macos/prepare_build_macos_rc

View File

@ -6,7 +6,6 @@
cd $(dirname $0)/../../..
# Prepare worker environment to run tests
KOKORO_INSTALL_RUBY=yes
KOKORO_INSTALL_RVM=yes
source kokoro/macos/prepare_build_macos_rc

View File

@ -6,7 +6,6 @@
cd $(dirname $0)/../../..
# Prepare worker environment to run tests
KOKORO_INSTALL_RUBY=yes
KOKORO_INSTALL_RVM=yes
source kokoro/macos/prepare_build_macos_rc

View File

@ -6,7 +6,6 @@
cd $(dirname $0)/../../..
# Prepare worker environment to run tests
KOKORO_INSTALL_RUBY=yes
KOKORO_INSTALL_RVM=yes
source kokoro/macos/prepare_build_macos_rc

View File

@ -37,8 +37,6 @@ build_artifact_version() {
before_install
clean_code $REPO_DIR $BUILD_COMMIT
sed -i '/Wno-sign-compare/a \ \ \ \ \ \ \ \ extra_compile_args.append("-std=c++11")' $REPO_DIR/python/setup.py
cat $REPO_DIR/python/setup.py
build_wheel $REPO_DIR/python $PLAT

View File

@ -289,7 +289,7 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
-disable-concurrent-destination-testing
)
;;
11.* | 12.*)
11.* | 12.* | 13.*)
# Dropped 32bit as Apple doesn't seem support the simulators either.
XCODEBUILD_TEST_BASE_IOS+=(
-destination "platform=iOS Simulator,name=iPhone 8,OS=latest" # 64bit
@ -357,6 +357,11 @@ if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then
-destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest"
)
;;
13.*)
XCODEBUILD_TEST_BASE_TVOS+=(
-destination "platform=tvOS Simulator,name=Apple TV 4K (2nd generation),OS=latest"
)
;;
* )
echo ""
echo "ATTENTION: Time to update the simulator targets for Xcode ${XCODE_VERSION}"

View File

@ -640,8 +640,8 @@ void Array_ModuleInit() {
repeated_field_methods);
RepeatedField_class_entry = zend_register_internal_class(&tmp_ce);
zend_class_implements(RepeatedField_class_entry, 3, spl_ce_ArrayAccess,
zend_ce_aggregate, spl_ce_Countable);
zend_class_implements(RepeatedField_class_entry, 3, zend_ce_arrayaccess,
zend_ce_aggregate, zend_ce_countable);
RepeatedField_class_entry->ce_flags |= ZEND_ACC_FINAL;
RepeatedField_class_entry->create_object = RepeatedField_create;

View File

@ -730,45 +730,26 @@ static DescriptorPool *GetPool(const zval* this_ptr) {
return (DescriptorPool*)Z_OBJ_P(this_ptr);
}
/**
* Object handler to create an DescriptorPool.
*/
static zend_object* DescriptorPool_create(zend_class_entry *class_type) {
DescriptorPool *intern = emalloc(sizeof(DescriptorPool));
zend_object_std_init(&intern->std, class_type);
intern->std.handlers = &DescriptorPool_object_handlers;
intern->symtab = upb_symtab_new();
// Skip object_properties_init(), we don't allow derived classes.
return &intern->std;
}
/**
* Object handler to free an DescriptorPool.
*/
static void DescriptorPool_destructor(zend_object* obj) {
DescriptorPool* intern = (DescriptorPool*)obj;
if (intern->symtab) {
upb_symtab_free(intern->symtab);
}
intern->symtab = NULL;
// We can't free our underlying symtab here, because user code may create
// messages from destructors that will refer to it. The symtab will be freed
// by our RSHUTDOWN() handler in protobuf.c
zend_object_std_dtor(&intern->std);
}
void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab) {
ZVAL_OBJ(zv, DescriptorPool_create(DescriptorPool_class_entry));
DescriptorPool *intern = emalloc(sizeof(DescriptorPool));
zend_object_std_init(&intern->std, DescriptorPool_class_entry);
intern->std.handlers = &DescriptorPool_object_handlers;
intern->symtab = symtab;
if (symtab) {
DescriptorPool *intern = GetPool(zv);
upb_symtab_free(intern->symtab);
intern->symtab = symtab;
}
}
upb_symtab *DescriptorPool_Steal(zval *zv) {
DescriptorPool *intern = GetPool(zv);
upb_symtab *ret = intern->symtab;
intern->symtab = NULL;
return ret;
ZVAL_OBJ(zv, &intern->std);
}
upb_symtab *DescriptorPool_GetSymbolTable() {
@ -1120,7 +1101,7 @@ void Def_ModuleInit() {
DescriptorPool_methods);
DescriptorPool_class_entry = zend_register_internal_class(&tmp_ce);
DescriptorPool_class_entry->ce_flags |= ZEND_ACC_FINAL;
DescriptorPool_class_entry->create_object = DescriptorPool_create;
DescriptorPool_class_entry->create_object = CreateHandler_ReturnNull;
h = &DescriptorPool_object_handlers;
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
h->dtor_obj = DescriptorPool_destructor;

View File

@ -38,15 +38,10 @@
// Initializes the Def module, which defines all of the descriptor classes.
void Def_ModuleInit();
// Creates a new DescriptorPool to wrap the given symtab. The DescriptorPool
// takes ownership of the given symtab. If symtab is NULL, the DescriptorPool
// will create an empty symtab instead.
// Creates a new DescriptorPool to wrap the given symtab, which must not be
// NULL.
void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab);
// Given a zval representing a DescriptorPool, steals and returns its symtab,
// which is now owned by the caller.
upb_symtab *DescriptorPool_Steal(zval *zv);
upb_symtab *DescriptorPool_GetSymbolTable();
// Returns true if the global descriptor pool already has the given filename.

View File

@ -636,8 +636,8 @@ void Map_ModuleInit() {
MapField_methods);
MapField_class_entry = zend_register_internal_class(&tmp_ce);
zend_class_implements(MapField_class_entry, 3, spl_ce_ArrayAccess,
zend_ce_aggregate, spl_ce_Countable);
zend_class_implements(MapField_class_entry, 3, zend_ce_arrayaccess,
zend_ce_aggregate, zend_ce_countable);
MapField_class_entry->ce_flags |= ZEND_ACC_FINAL;
MapField_class_entry->create_object = MapField_create;

View File

@ -10,11 +10,11 @@
<email>protobuf-opensource@google.com</email>
<active>yes</active>
</lead>
<date>2021-06-04</date>
<time>21:17:28</time>
<date>2021-10-04</date>
<time>13:03:51</time>
<version>
<release>3.17.3</release>
<api>3.17.3</api>
<release>3.18.1</release>
<api>3.18.1</api>
</version>
<stability>
<release>stable</release>
@ -22,7 +22,7 @@
</stability>
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>
* No new changes in 3.17.2
* No new changes in 3.18.1
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@ -1038,5 +1038,65 @@ G A release.
<notes>
</notes>
</release>
<release>
<version>
<release>3.18.0RC1</release>
<api>3.18.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2021-08-18</date>
<time>15:23:47</time>
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>
</notes>
</release>
<release>
<version>
<release>3.18.0RC2</release>
<api>3.18.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2021-08-27</date>
<time>14:37:43</time>
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>
</notes>
</release>
<release>
<version>
<release>3.18.0</release>
<api>3.18.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2021-09-13</date>
<time>11:30:58</time>
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>
</notes>
</release>
<release>
<version>
<release>3.18.1</release>
<api>3.18.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2021-10-04</date>
<time>13:03:51</time>
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>
</notes>
</release>
</changelog>
</package>

View File

@ -66,7 +66,7 @@ ZEND_BEGIN_MODULE_GLOBALS(protobuf)
// to rebuild it from scratch. When keep_descriptor_pool_after_request==true,
// we steal the upb_symtab from the global DescriptorPool object just before
// destroying it.
upb_symtab *saved_symtab;
upb_symtab *global_symtab;
// Object cache (see interface in protobuf.h).
HashTable object_cache;
@ -82,6 +82,13 @@ ZEND_BEGIN_MODULE_GLOBALS(protobuf)
HashTable descriptors;
ZEND_END_MODULE_GLOBALS(protobuf)
void free_protobuf_globals(zend_protobuf_globals *globals) {
zend_hash_destroy(&globals->name_msg_cache);
zend_hash_destroy(&globals->name_enum_cache);
upb_symtab_free(globals->global_symtab);
globals->global_symtab = NULL;
}
ZEND_DECLARE_MODULE_GLOBALS(protobuf)
const zval *get_generated_pool() {
@ -146,14 +153,14 @@ const zval *get_generated_pool() {
// discouraged by the documentation: https://serverfault.com/a/231660
static PHP_GSHUTDOWN_FUNCTION(protobuf) {
if (protobuf_globals->saved_symtab) {
upb_symtab_free(protobuf_globals->saved_symtab);
if (protobuf_globals->global_symtab) {
free_protobuf_globals(protobuf_globals);
}
}
static PHP_GINIT_FUNCTION(protobuf) {
ZVAL_NULL(&protobuf_globals->generated_pool);
protobuf_globals->saved_symtab = NULL;
protobuf_globals->global_symtab = NULL;
}
/**
@ -164,12 +171,15 @@ static PHP_GINIT_FUNCTION(protobuf) {
static PHP_RINIT_FUNCTION(protobuf) {
// Create the global generated pool.
// Reuse the symtab (if any) left to us by the last request.
upb_symtab *symtab = PROTOBUF_G(saved_symtab);
upb_symtab *symtab = PROTOBUF_G(global_symtab);
if (!symtab) {
PROTOBUF_G(global_symtab) = symtab = upb_symtab_new();
zend_hash_init(&PROTOBUF_G(name_msg_cache), 64, NULL, NULL, 0);
zend_hash_init(&PROTOBUF_G(name_enum_cache), 64, NULL, NULL, 0);
}
DescriptorPool_CreateWithSymbolTable(&PROTOBUF_G(generated_pool), symtab);
zend_hash_init(&PROTOBUF_G(object_cache), 64, NULL, NULL, 0);
zend_hash_init(&PROTOBUF_G(name_msg_cache), 64, NULL, NULL, 0);
zend_hash_init(&PROTOBUF_G(name_enum_cache), 64, NULL, NULL, 0);
zend_hash_init(&PROTOBUF_G(descriptors), 64, NULL, ZVAL_PTR_DTOR, 0);
return SUCCESS;
@ -182,15 +192,12 @@ static PHP_RINIT_FUNCTION(protobuf) {
*/
static PHP_RSHUTDOWN_FUNCTION(protobuf) {
// Preserve the symtab if requested.
if (PROTOBUF_G(keep_descriptor_pool_after_request)) {
zval *zv = &PROTOBUF_G(generated_pool);
PROTOBUF_G(saved_symtab) = DescriptorPool_Steal(zv);
if (!PROTOBUF_G(keep_descriptor_pool_after_request)) {
free_protobuf_globals(ZEND_MODULE_GLOBALS_BULK(protobuf));
}
zval_dtor(&PROTOBUF_G(generated_pool));
zend_hash_destroy(&PROTOBUF_G(object_cache));
zend_hash_destroy(&PROTOBUF_G(name_msg_cache));
zend_hash_destroy(&PROTOBUF_G(name_enum_cache));
zend_hash_destroy(&PROTOBUF_G(descriptors));
return SUCCESS;
@ -296,7 +303,7 @@ static const zend_module_dep protobuf_deps[] = {
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("protobuf.keep_descriptor_pool_after_request", "0",
PHP_INI_SYSTEM, OnUpdateBool,
PHP_INI_ALL, OnUpdateBool,
keep_descriptor_pool_after_request, zend_protobuf_globals,
protobuf_globals)
PHP_INI_END()

View File

@ -52,7 +52,7 @@ const zval *get_generated_pool();
#define PROTO_RETURN_VAL zval*
#endif
// Sine php 8.0, the Object Handlers API was changed to receive zend_object*
// Since php 8.0, the Object Handlers API was changed to receive zend_object*
// instead of zval* and zend_string* instead of zval* for property names.
// https://github.com/php/php-src/blob/php-8.0.0beta1/UPGRADING.INTERNALS#L37-L39
#if PHP_VERSION_ID < 80000
@ -74,6 +74,16 @@ const zval *get_generated_pool();
#define PROTO_STRLEN_P(obj) ZSTR_LEN(obj)
#endif
// In PHP 8.1, several old interfaces are removed:
// https://github.com/php/php-src/blob/14f599ea7def7c7a59c40aff763ce8b105573e7a/UPGRADING.INTERNALS#L27-L31
//
// We now use the new interfaces (zend_ce_arrayaccess and zend_ce_countable).
// However we have to polyfill zend_ce_countable, which was only introduced in
// PHP 7.2.0.
#if PHP_VERSION_ID < 70200
#define zend_ce_countable spl_ce_Countable
#endif
ZEND_BEGIN_ARG_INFO(arginfo_void, 0)
ZEND_END_ARG_INFO()
@ -81,7 +91,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_setter, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
#define PHP_PROTOBUF_VERSION "3.17.3"
#define PHP_PROTOBUF_VERSION "3.18.1"
// ptr -> PHP object cache. This is a weak map that caches lazily-created
// wrapper objects around upb types:

View File

@ -565,7 +565,7 @@ class GeneratedClassTest extends TestBase
$m->setMapInt32Int32($dict);
$this->assertSame(0, count($m->getMapInt32Int32()));
$dict = array(5 => 5, 6.1 => 6.1, "7" => "7");
$dict = array(5 => 5, 6 => 6.1, "7" => "7");
$m->setMapInt32Int32($dict);
$this->assertTrue($m->getMapInt32Int32() instanceof MapField);
$this->assertSame(3, count($m->getMapInt32Int32()));

View File

@ -2,9 +2,22 @@
# phpunit has memory leak by itself. Thus, it cannot be used to test memory leak.
class HasDestructor
{
function __construct() {
$this->foo = $this;
}
function __destruct() {
new Foo\TestMessage();
}
}
require_once('../vendor/autoload.php');
require_once('test_util.php');
$has_destructor = new HasDestructor();
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBType;
use Foo\TestAny;

40
php/tests/memory_leak_test.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/bash
cd $(dirname $0)
set -ex
PORT=12345
TIMEOUT=10
./compile_extension.sh
run_test() {
echo
echo "Running memory leak test, args: $@"
EXTRA_ARGS=""
ARGS="-d xdebug.profiler_enable=0 -d display_errors=on -dextension=../ext/google/protobuf/modules/protobuf.so"
for i in "$@"; do
case $i in
--keep_descriptors)
EXTRA_ARGS=-dprotobuf.keep_descriptor_pool_after_request=1
shift
;;
esac
done
export ZEND_DONT_UNLOAD_MODULES=1
export USE_ZEND_ALLOC=0
if valgrind --error-exitcode=1 --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all --suppressions=valgrind.supp --num-callers=100 php $ARGS $EXTRA_ARGS memory_leak_test.php; then
echo "Memory leak test SUCCEEDED"
else
echo "Memory leak test FAILED"
exit 1
fi
}
run_test
run_test --keep_descriptors

View File

@ -5,28 +5,58 @@ cd $(dirname $0)
set -e
PORT=12345
TIMEOUT=10
./compile_extension.sh
nohup php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so -S localhost:$PORT multirequest.php 2>&1 &
run_test() {
echo
echo "Running multirequest test, args: $@"
sleep 1
RUN_UNDER=""
EXTRA_ARGS=""
ARGS="-d xdebug.profiler_enable=0 -d display_errors=on -dextension=../ext/google/protobuf/modules/protobuf.so"
wget http://localhost:$PORT/multirequest.result -O multirequest.result
wget http://localhost:$PORT/multirequest.result -O multirequest.result
for i in "$@"; do
case $i in
--valgrind)
RUN_UNDER="valgrind --error-exitcode=1"
shift
;;
--keep_descriptors)
EXTRA_ARGS=-dprotobuf.keep_descriptor_pool_after_request=1
shift
;;
esac
done
pushd ../ext/google/protobuf
phpize --clean
popd
export ZEND_DONT_UNLOAD_MODULES=1
export USE_ZEND_ALLOC=0
rm -f nohup.out
nohup $RUN_UNDER php $ARGS $EXTRA_ARGS -S localhost:$PORT multirequest.php >nohup.out 2>&1 &
PID=$!
PID=`ps | grep "php" | awk '{print $1}'`
echo $PID
if ! timeout $TIMEOUT bash -c "until echo > /dev/tcp/localhost/$PORT; do sleep 0.1; done" > /dev/null 2>&1; then
echo "Server failed to come up after $TIMEOUT seconds"
cat nohup.out
exit 1
fi
if [[ -z "$PID" ]]
then
echo "Failed"
exit 1
else
kill $PID
echo "Succeeded"
fi
seq 2 | xargs -I{} wget -nv http://localhost:$PORT/multirequest.result -O multirequest{}.result
REQUESTS_SUCCEEDED=$?
if kill $PID > /dev/null 2>&1 && [[ $REQUESTS_SUCCEEDED == "0" ]]; then
wait
echo "Multirequest test SUCCEEDED"
else
echo "Multirequest test FAILED"
cat nohup.out
exit 1
fi
}
run_test
run_test --keep_descriptors
run_test --valgrind
run_test --valgrind --keep_descriptors

View File

@ -10,3 +10,24 @@
obj:/usr/bin/php7.3
fun:__scandir64_tail
}
{
PHP_ModuleLoadingLeaks
Memcheck:Leak
...
fun:php_module_startup
}
{
PHP_ModuleLoadingLeaks
Memcheck:Leak
...
fun:php_module_startup
}
{
PHP_ModuleLoadingLeaks2
Memcheck:Leak
...
fun:php_load_shlib
}

View File

@ -1 +1 @@
PROTOBUF_VERSION = '3.17.3'
PROTOBUF_VERSION = '3.18.1'

View File

@ -8,7 +8,7 @@
</parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
<version>3.17.3</version>
<version>3.18.1</version>
<packaging>pom</packaging>
<name>Protobuf Compiler</name>
<description>

View File

@ -15,3 +15,5 @@ global-exclude *.dll
global-exclude *.pyc
global-exclude *.pyo
global-exclude *.so
include LICENSE

View File

@ -30,4 +30,4 @@
# Copyright 2007 Google Inc. All Rights Reserved.
__version__ = '3.17.3'
__version__ = '3.18.1'

View File

@ -951,7 +951,7 @@ class FileDescriptor(DescriptorBase):
public_dependencies (list[FileDescriptor]): A subset of
:attr:`dependencies`, which were declared as "public".
message_types_by_name (dict(str, Descriptor)): Mapping from message names
to their :class:`Desctiptor`.
to their :class:`Descriptor`.
enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to
their :class:`EnumDescriptor`.
extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension

View File

@ -41,46 +41,15 @@ try:
# The compile-time constants in the _api_implementation module can be used to
# switch to a certain implementation of the Python API at build time.
_api_version = _api_implementation.api_version
_proto_extension_modules_exist_in_build = True
except ImportError:
_api_version = -1 # Unspecified by compiler flags.
_proto_extension_modules_exist_in_build = False
if _api_version == 1:
raise ValueError('api_version=1 is no longer supported.')
if _api_version < 0: # Still unspecified?
try:
# The presence of this module in a build allows the proto implementation to
# be upgraded merely via build deps rather than a compiler flag or the
# runtime environment variable.
# pylint: disable=g-import-not-at-top
from google.protobuf import _use_fast_cpp_protos
# Work around a known issue in the classic bootstrap .par import hook.
if not _use_fast_cpp_protos:
raise ImportError('_use_fast_cpp_protos import succeeded but was None')
del _use_fast_cpp_protos
_api_version = 2
from google.protobuf import use_pure_python
raise RuntimeError(
'Conflicting deps on both :use_fast_cpp_protos and :use_pure_python.\n'
' go/build_deps_on_BOTH_use_fast_cpp_protos_AND_use_pure_python\n'
'This should be impossible via a link error at build time...')
except ImportError:
try:
# pylint: disable=g-import-not-at-top
from google.protobuf import use_pure_python
del use_pure_python # Avoids a pylint error and namespace pollution.
_api_version = 0
except ImportError:
# TODO(b/74017912): It's unsafe to enable :use_fast_cpp_protos by default;
# it can cause data loss if you have any Python-only extensions to any
# message passed back and forth with C++ code.
#
# TODO(b/17427486): Once that bug is fixed, we want to make both Python 2
# and Python 3 default to `_api_version = 2` (C++ implementation V2).
pass
_default_implementation_type = ('python' if _api_version <= 0 else 'cpp')
_default_implementation_type = ('cpp' if _api_version > 0 else 'python')
# This environment variable can be used to switch to a certain implementation
# of the Python API, overriding the compile-time constants in the
@ -97,21 +66,6 @@ if 'PyPy' in sys.version and _implementation_type == 'cpp':
'Falling back to the python implementation.')
_implementation_type = 'python'
# This environment variable can be used to switch between the two
# 'cpp' implementations, overriding the compile-time constants in the
# _api_implementation module. Right now only '2' is supported. Any other
# value will cause an error to be raised.
_implementation_version_str = os.getenv(
'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION', '2')
if _implementation_version_str != '2':
raise ValueError(
'unsupported PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION: "' +
_implementation_version_str + '" (supported versions: 2)'
)
_implementation_version = int(_implementation_version_str)
# Detect if serialization should be deterministic by default
try:
@ -150,7 +104,7 @@ def _SetType(implementation_type):
# See comment on 'Type' above.
def Version():
return _implementation_version
return 2
# For internal use only

View File

@ -359,6 +359,14 @@ class Message(object):
"""
raise NotImplementedError
@classmethod
def FromString(cls, s):
raise NotImplementedError
@staticmethod
def RegisterExtension(extension_handle):
raise NotImplementedError
def _SetListener(self, message_listener):
"""Internal method used by the protocol message implementation.
Clients should not call this directly.

View File

@ -1919,7 +1919,9 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
// explicit in our correctness checks.
if (ptr == nullptr || ctx.BytesUntilLimit(ptr) < 0) {
// Parse error or the parser overshoot the limit.
PyErr_Format(DecodeError_class, "Error parsing message");
PyErr_Format(
DecodeError_class, "Error parsing message with type '%s'",
self->GetMessageClass()->message_descriptor->full_name().c_str());
return NULL;
}
// ctx has an explicit limit set (length of string_view), so we have to

View File

@ -73,6 +73,9 @@ else
sed -i -r "s/__version__ = '.*'/__version__ = '${VERSION}.${DEV}'/" python/google/protobuf/__init__.py
fi
# Copy LICENSE
cp LICENSE python/LICENSE
cd python
# Run tests locally.

View File

@ -211,11 +211,11 @@ if __name__ == '__main__':
extra_compile_args = []
if sys.platform != 'win32':
extra_compile_args.append('-Wno-write-strings')
extra_compile_args.append('-Wno-invalid-offsetof')
extra_compile_args.append('-Wno-sign-compare')
extra_compile_args.append('-Wno-unused-variable')
extra_compile_args.append('-std=c++11')
extra_compile_args.append('-Wno-write-strings')
extra_compile_args.append('-Wno-invalid-offsetof')
extra_compile_args.append('-Wno-sign-compare')
extra_compile_args.append('-Wno-unused-variable')
extra_compile_args.append('-std=c++11')
if sys.platform == 'darwin':
extra_compile_args.append("-Wno-shorten-64-to-32");
@ -285,21 +285,20 @@ if __name__ == '__main__':
maintainer_email='protobuf@googlegroups.com',
license='3-Clause BSD License',
classifiers=[
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
],
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
],
namespace_packages=['google'],
packages=find_packages(
exclude=[
'import_test_package',
'protobuf_distutils',
],
),
],),
test_suite='google.protobuf.internal',
cmdclass={
'clean': clean,
@ -309,4 +308,5 @@ if __name__ == '__main__':
},
install_requires=install_requires,
ext_modules=ext_module_list,
python_requires=">=3.5",
)

View File

@ -61,22 +61,24 @@ unless ENV['IN_DOCKER'] == 'true'
output_file = proto_file.sub(/\.proto$/, "_pb.rb")
genproto_output << output_file
file output_file => proto_file do |file_task|
sh "#{protoc_command} -I../src -I. --ruby_out=. #{proto_file}"
sh "#{protoc_command} -I../src -I. -I./tests --ruby_out=. #{proto_file}"
end
end
end
if RUBY_PLATFORM == "java"
if `which mvn` == ''
raise ArgumentError, "maven needs to be installed"
end
task :clean do
task :clean => :require_mvn do
system("mvn --batch-mode clean")
end
task :compile do
task :compile => :require_mvn do
system("mvn --batch-mode package")
end
task :require_mvn do
raise ArgumentError, "maven needs to be installed" if `which mvn` == ''
end
else
Rake::ExtensionTask.new("protobuf_c", spec) do |ext|
unless RUBY_PLATFORM =~ /darwin/
@ -95,7 +97,22 @@ else
]
end
task 'gem:java' do
sh "rm Gemfile.lock"
require 'rake_compiler_dock'
# Specify the repo root as the working and mount directory to provide access
# to the java directory
repo_root = File.realdirpath File.join(Dir.pwd, '..')
RakeCompilerDock.sh <<-"EOT", platform: 'jruby', rubyvm: :jruby, mountdir: repo_root, workdir: repo_root
sudo apt-get install maven -y && \
cd java && mvn install -Dmaven.test.skip=true && cd ../ruby && \
bundle && \
IN_DOCKER=true rake compile gem
EOT
end
task 'gem:windows' do
sh "rm Gemfile.lock"
require 'rake_compiler_dock'
['x86-mingw32', 'x64-mingw32', 'x86_64-linux', 'x86-linux'].each do |plat|
RakeCompilerDock.sh <<-"EOT", platform: plat
@ -111,7 +128,7 @@ else
system "rake cross native gem RUBY_CC_VERSION=3.0.0:2.7.0:2.6.0:2.5.1:2.4.0:2.3.0"
end
else
task 'gem:native' => [:genproto, 'gem:windows']
task 'gem:native' => [:genproto, 'gem:windows', 'gem:java']
end
end

View File

@ -14,4 +14,4 @@ wget https://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0/${PROTOC_BI
chmod +x protoc
# Run tests
rake test
RUBYLIB=../../lib:. rake test

View File

@ -551,6 +551,7 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
RepeatedField* dupped = ruby_to_RepeatedField(dupped_);
upb_array *dupped_array = RepeatedField_GetMutable(dupped_);
upb_arena* arena = Arena_get(dupped->arena);
Arena_fuse(list_rptfield->arena, arena);
int size = upb_array_size(list_rptfield->array);
int i;

View File

@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = "google-protobuf"
s.version = "3.17.3"
s.version = "3.18.1"
git_tag = "v#{s.version.to_s.sub('.rc.', '-rc')}" # Converts X.Y.Z.rc.N to vX.Y.Z-rcN, used for the git tag
s.licenses = ["BSD-3-Clause"]
s.summary = "Protocol Buffers"

View File

@ -51,9 +51,9 @@ else
require 'google/protobuf_c'
end
require 'google/protobuf/descriptor_dsl'
end
require 'google/protobuf/descriptor_dsl'
require 'google/protobuf/repeated_field'
module Google

View File

@ -301,8 +301,8 @@ module Google
internal_add_field(:LABEL_REQUIRED, name, type, number, type_class, options)
end
def repeated(name, type, number, type_class = nil)
internal_add_field(:LABEL_REPEATED, name, type, number, type_class, nil)
def repeated(name, type, number, type_class = nil, options=nil)
internal_add_field(:LABEL_REPEATED, name, type, number, type_class, options)
end
def oneof(name, &block)

View File

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.google</groupId>
@ -11,7 +9,7 @@
<groupId>com.google.protobuf.jruby</groupId>
<artifactId>protobuf-jruby</artifactId>
<version>1.0-SNAPSHOT</version>
<version>3.18.1</version>
<name>Protocol Buffer JRuby native extension</name>
<description>
Protocol Buffers are a way of encoding structured data in an efficient yet
@ -74,21 +72,17 @@
</plugins>
</build>
<dependencies>
<!-- Ordering of dependencies matters to update_version.py -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.18.1</version>
</dependency>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>9.2.11.1</version>
<version>9.2.19.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.13.0</version>
</dependency>
</dependencies>
</project>

View File

@ -1,147 +0,0 @@
/*
* Protocol Buffers - Google's data interchange format
* Copyright 2014 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.jruby;
import org.jruby.*;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.*;
import org.jruby.runtime.builtin.IRubyObject;
@JRubyClass(name = "Builder")
public class RubyBuilder extends RubyObject {
public static void createRubyBuilder(Ruby runtime) {
RubyModule internal = runtime.getClassFromPath("Google::Protobuf::Internal");
RubyClass cBuilder = internal.defineClassUnder("Builder", runtime.getObject(), new ObjectAllocator() {
@Override
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
return new RubyBuilder(runtime, klazz);
}
});
cBuilder.defineAnnotatedMethods(RubyBuilder.class);
}
public RubyBuilder(Ruby runtime, RubyClass metaClass) {
super(runtime, metaClass);
this.cFileBuilderContext = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Internal::FileBuilderContext");
}
/*
* call-seq:
* Builder.new => builder
*
* Creates a new Builder. A Builder can accumulate a set of new message and enum
* descriptors and atomically register them into a pool in a way that allows for
* (co)recursive type references.
*/
@JRubyMethod
public IRubyObject initialize(ThreadContext context, IRubyObject descriptorPool) {
this.descriptorPool = (RubyDescriptorPool) descriptorPool;
return this;
}
/*
* call-seq:
* Builder.add_message(name, &block)
*
* Old and deprecated way to create a new descriptor.
* See FileBuilderContext.add_message for the recommended way.
*
* Exists for backwards compatibility to allow building descriptor pool for
* files generated by protoc which don't add messages within "add_file" block.
* Descriptors created this way get assigned to a default empty FileDescriptor.
*/
@JRubyMethod(name = "add_message")
public IRubyObject addMessage(ThreadContext context, IRubyObject name, Block block) {
ensureDefaultFileBuilder(context);
defaultFileBuilder.addMessage(context, name, block);
return context.nil;
}
/*
* call-seq:
* Builder.add_enum(name, &block)
*
* Old and deprecated way to create a new enum descriptor.
* See FileBuilderContext.add_enum for the recommended way.
*
* Exists for backwards compatibility to allow building descriptor pool for
* files generated by protoc which don't add enums within "add_file" block.
* Enum descriptors created this way get assigned to a default empty
* FileDescriptor.
*/
@JRubyMethod(name = "add_enum")
public IRubyObject addEnum(ThreadContext context, IRubyObject name, Block block) {
ensureDefaultFileBuilder(context);
defaultFileBuilder.addEnum(context, name, block);
return context.nil;
}
/*
* call-seq:
* Builder.add_file(name, options = nil, &block)
*
* Creates a new, file descriptor with the given name and options and invokes
* the block in the context of a FileBuilderContext on that descriptor. The
* block can then call FileBuilderContext#add_message or
* FileBuilderContext#add_enum to define new messages or enums, respectively.
*
* This is the recommended, idiomatic way to build file descriptors.
*/
@JRubyMethod(name = "add_file")
public IRubyObject addFile(ThreadContext context, IRubyObject name, IRubyObject options, Block block) {
RubyFileBuilderContext ctx = (RubyFileBuilderContext) cFileBuilderContext.newInstance(context, descriptorPool, name, options, Block.NULL_BLOCK);
ctx.instance_eval(context, block);
ctx.build(context);
return context.nil;
}
/*
* Used to trigger the build when using the deprecated syntax
*/
protected void build(ThreadContext context) {
if (defaultFileBuilder != null) {
defaultFileBuilder.build(context);
}
}
private void ensureDefaultFileBuilder(ThreadContext context) {
if (defaultFileBuilder == null) {
this.defaultFileBuilder = (RubyFileBuilderContext) cFileBuilderContext.newInstance(context, descriptorPool, context.runtime.newString("ruby_default_file.proto"), Block.NULL_BLOCK);
}
}
private RubyClass cFileBuilderContext;
private RubyDescriptorPool descriptorPool;
private RubyFileBuilderContext defaultFileBuilder;
}

View File

@ -37,9 +37,11 @@ import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.DescriptorValidationException;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.InvalidProtocolBufferException;
import org.jruby.*;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.RaiseException;
import org.jruby.runtime.*;
import org.jruby.runtime.builtin.IRubyObject;
@ -61,7 +63,6 @@ public class RubyDescriptorPool extends RubyObject {
cDescriptorPool.defineAnnotatedMethods(RubyDescriptorPool.class);
descriptorPool = (RubyDescriptorPool) cDescriptorPool.newInstance(runtime.getCurrentContext(), Block.NULL_BLOCK);
cBuilder = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Internal::Builder");
cDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Descriptor");
cEnumDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::EnumDescriptor");
}
@ -74,9 +75,10 @@ public class RubyDescriptorPool extends RubyObject {
@JRubyMethod
public IRubyObject build(ThreadContext context, Block block) {
RubyBuilder ctx = (RubyBuilder) cBuilder.newInstance(context, this, Block.NULL_BLOCK);
RubyClass cBuilder = (RubyClass) context.runtime.getClassFromPath("Google::Protobuf::Internal::Builder");
RubyBasicObject ctx = (RubyBasicObject) cBuilder.newInstance(context, this, Block.NULL_BLOCK);
ctx.instance_eval(context, block);
ctx.build(context); // Needs to be called to support the deprecated syntax
ctx.callMethod(context, "build"); // Needs to be called to support the deprecated syntax
return context.nil;
}
@ -109,6 +111,18 @@ public class RubyDescriptorPool extends RubyObject {
return descriptorPool;
}
@JRubyMethod(required = 1)
public IRubyObject add_serialized_file (ThreadContext context, IRubyObject data ) {
byte[] bin = data.convertToString().getBytes();
try {
FileDescriptorProto.Builder builder = FileDescriptorProto.newBuilder().mergeFrom(bin);
registerFileDescriptor(context, builder);
} catch (InvalidProtocolBufferException e) {
throw RaiseException.from(context.runtime, (RubyClass) context.runtime.getClassFromPath("Google::Protobuf::ParseError"), e.getMessage());
}
return context.nil;
}
protected void registerFileDescriptor(ThreadContext context, FileDescriptorProto.Builder builder) {
final FileDescriptor fd;
try {
@ -157,7 +171,6 @@ public class RubyDescriptorPool extends RubyObject {
return fileDescriptors.toArray(new FileDescriptor[fileDescriptors.size()]);
}
private static RubyClass cBuilder;
private static RubyClass cDescriptor;
private static RubyClass cEnumDescriptor;
private static RubyDescriptorPool descriptorPool;

View File

@ -1,91 +0,0 @@
/*
* Protocol Buffers - Google's data interchange format
* Copyright 2014 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.jruby;
import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.RubyNumeric;
import org.jruby.RubyObject;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@JRubyClass(name = "EnumBuilderContext")
public class RubyEnumBuilderContext extends RubyObject {
public static void createRubyEnumBuilderContext(Ruby runtime) {
RubyModule internal = runtime.getClassFromPath("Google::Protobuf::Internal");
RubyClass cEnumBuilderContext = internal.defineClassUnder("EnumBuilderContext", runtime.getObject(), new ObjectAllocator() {
@Override
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
return new RubyEnumBuilderContext(runtime, klazz);
}
});
cEnumBuilderContext.defineAnnotatedMethods(RubyEnumBuilderContext.class);
}
public RubyEnumBuilderContext(Ruby ruby, RubyClass klazz) {
super(ruby, klazz);
}
@JRubyMethod
public IRubyObject initialize(ThreadContext context, IRubyObject fileBuilderContext, IRubyObject name) {
this.fileBuilderContext = (RubyFileBuilderContext) fileBuilderContext;
this.builder = this.fileBuilderContext.getNewEnumBuilder();
this.builder.setName(name.asJavaString());
this.builder.getOptionsBuilder().setAllowAlias(true);
return this;
}
/*
* call-seq:
* EnumBuilder.add_value(name, number)
*
* Adds the given name => number mapping to the enum type. Name must be a Ruby
* symbol.
*/
@JRubyMethod
public IRubyObject value(ThreadContext context, IRubyObject name, IRubyObject number) {
this.builder.addValueBuilder()
.setName(name.asJavaString())
.setNumber(RubyNumeric.num2int(number));
return context.nil;
}
private EnumDescriptorProto.Builder builder;
private RubyFileBuilderContext fileBuilderContext;
}

View File

@ -35,6 +35,7 @@ package com.google.protobuf.jruby;
import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
@ -151,6 +152,7 @@ public class RubyEnumDescriptor extends RubyObject {
Ruby runtime = context.runtime;
RubyModule enumModule = RubyModule.newModule(runtime);
boolean defaultValueRequiredButNotFound = descriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO3;
for (EnumValueDescriptor value : descriptor.getValues()) {
String name = value.getName();
// Make sure its a valid constant name before trying to create it
@ -159,8 +161,14 @@ public class RubyEnumDescriptor extends RubyObject {
} else {
runtime.getWarnings().warn("Enum value " + name + " does not start with an uppercase letter as is required for Ruby constants.");
}
if (value.getNumber() == 0) {
defaultValueRequiredButNotFound = false;
}
}
if (defaultValueRequiredButNotFound) {
throw Utils.createTypeError(context, "Enum definition " + name + " does not contain a value for '0'");
}
enumModule.instance_variable_set(runtime.newString(Utils.DESCRIPTOR_INSTANCE_VAR), this);
enumModule.defineAnnotatedMethods(RubyEnum.class);
return enumModule;

View File

@ -32,8 +32,8 @@
package com.google.protobuf.jruby;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import org.jruby.*;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
@ -228,6 +228,9 @@ public class RubyFieldDescriptor extends RubyObject {
}
protected void setDescriptor(ThreadContext context, FieldDescriptor descriptor, RubyDescriptorPool pool) {
if (descriptor.isRequired() && descriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO3) {
throw Utils.createTypeError(context, descriptor.getName() + " is labeled required but required fields are unsupported in proto3");
}
this.descriptor = descriptor;
this.name = context.runtime.newString(descriptor.getName());
this.pool = pool;

View File

@ -1,348 +0,0 @@
/*
* Protocol Buffers - Google's data interchange format
* Copyright 2014 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.jruby;
import com.google.protobuf.DescriptorProtos.DescriptorProto;
import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
import com.google.protobuf.DescriptorProtos.EnumValueDescriptorProtoOrBuilder;
import com.google.protobuf.DescriptorProtos.FieldDescriptorProto;
import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
import com.google.protobuf.Descriptors.FieldDescriptor;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyHash;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.Block;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;
@JRubyClass(name = "FileBuilderContext")
public class RubyFileBuilderContext extends RubyObject {
public static void createRubyFileBuilderContext(Ruby runtime) {
RubyModule internal = runtime.getClassFromPath("Google::Protobuf::Internal");
RubyClass cFileBuilderContext = internal.defineClassUnder("FileBuilderContext", runtime.getObject(), new ObjectAllocator() {
@Override
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
return new RubyFileBuilderContext(runtime, klazz);
}
});
cFileBuilderContext.defineAnnotatedMethods(RubyFileBuilderContext.class);
cDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Descriptor");
cEnumBuilderContext = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Internal::EnumBuilderContext");
cEnumDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::EnumDescriptor");
cMessageBuilderContext = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Internal::MessageBuilderContext");
}
public RubyFileBuilderContext(Ruby runtime, RubyClass klazz) {
super(runtime, klazz);
}
/*
* call-seq:
* FileBuilderContext.new(descriptor_pool, name, options = nil) => context
*
* Create a new file builder context for the given file descriptor and
* builder context. This class is intended to serve as a DSL context to be used
* with #instance_eval.
*/
@JRubyMethod(required = 2, optional = 1)
public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
this.descriptorPool = (RubyDescriptorPool) args[0];
this.builder = FileDescriptorProto.newBuilder();
this.builder.setName(args[1].asJavaString());
this.builder.setSyntax("proto3");
if (args.length > 2) {
RubyHash options = (RubyHash) args[2];
IRubyObject syntax = options.fastARef(context.runtime.newSymbol("syntax"));
if (syntax != null) {
String syntaxStr = syntax.asJavaString();
this.builder.setSyntax(syntaxStr);
this.proto3 = syntaxStr.equals("proto3");
}
}
return this;
}
/*
* call-seq:
* FileBuilderContext.add_enum(name, &block)
*
* Creates a new, empty enum descriptor with the given name, and invokes the
* block in the context of an EnumBuilderContext on that descriptor. The block
* can then call EnumBuilderContext#add_value to define the enum values.
*
* This is the recommended, idiomatic way to build enum definitions.
*/
@JRubyMethod(name = "add_enum")
public IRubyObject addEnum(ThreadContext context, IRubyObject name, Block block) {
RubyObject ctx = (RubyObject) cEnumBuilderContext.newInstance(context, this, name, Block.NULL_BLOCK);
ctx.instance_eval(context, block);
return context.nil;
}
/*
* call-seq:
* FileBuilderContext.add_message(name, &block)
*
* Creates a new, empty descriptor with the given name, and invokes the block in
* the context of a MessageBuilderContext on that descriptor. The block can then
* call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
* methods to define the message fields.
*
* This is the recommended, idiomatic way to build message definitions.
*/
@JRubyMethod(name = "add_message")
public IRubyObject addMessage(ThreadContext context, IRubyObject name, Block block) {
RubyObject ctx = (RubyObject) cMessageBuilderContext.newInstance(context, this, name, Block.NULL_BLOCK);
ctx.instance_eval(context, block);
return context.nil;
}
protected void build(ThreadContext context) {
Ruby runtime = context.runtime;
List<DescriptorProto.Builder> messageBuilderList = builder.getMessageTypeBuilderList();
List<EnumDescriptorProto.Builder> enumBuilderList = builder.getEnumTypeBuilderList();
// Get the package name from defined names
String packageName = getPackageName(messageBuilderList, enumBuilderList);
if (!packageName.isEmpty()) {
builder.setPackage(packageName);
}
// Make an index of the message builders so we can easily nest them
TreeMap<String, DescriptorProto.Builder> messageBuilderMap = new TreeMap();
for (DescriptorProto.Builder messageBuilder : messageBuilderList) {
messageBuilderMap.put(messageBuilder.getName(), messageBuilder);
}
// Make an index of the enum builders so we can easily nest them
HashMap<String, EnumDescriptorProto.Builder> enumBuilderMap = new HashMap();
for (EnumDescriptorProto.Builder enumBuilder : enumBuilderList) {
enumBuilderMap.put("." + enumBuilder.getName(), enumBuilder);
}
// Rename and properly nest messages and create associated ruby objects
int packageNameLength = packageName.length();
int currentMessageIndex = 0;
int currentEnumIndex = 0;
// Need to get a static list because we are potentially deleting some of them from the collection
DescriptorProto.Builder[] messageBuilders = new DescriptorProto.Builder[messageBuilderList.size()];
messageBuilderList.toArray(messageBuilders);
EnumDescriptorProto.Builder[] enumBuilders = new EnumDescriptorProto.Builder[enumBuilderList.size()];
enumBuilderList.toArray(enumBuilders);
for (EnumDescriptorProto.Builder enumBuilder : enumBuilders) {
String name = enumBuilder.getName();
int lastDot = name.lastIndexOf('.');
if (lastDot > packageNameLength) {
String parentName = name.substring(0, lastDot);
String shortName = name.substring(lastDot + 1);
enumBuilder.setName(shortName);
messageBuilderMap.get(parentName).addEnumType(enumBuilder);
builder.removeEnumType(currentEnumIndex);
} else {
if (packageNameLength > 0) {
// Remove the package name
String shortName = name.substring(packageNameLength + 1);
enumBuilder.setName(shortName);
}
currentEnumIndex++;
}
// Ensure we have a default value if using proto3 syntax
if (proto3) {
boolean foundDefault = false;
for (EnumValueDescriptorProtoOrBuilder enumValue : enumBuilder.getValueOrBuilderList()) {
if (enumValue.getNumber() == 0) {
foundDefault = true;
break;
}
}
if (!foundDefault) {
throw Utils.createTypeError(context, "Enum definition " + enumBuilder.getName() + " does not contain a value for '0'");
}
}
}
// Wipe out top level message builders so we can insert only the ones that should be there
builder.clearMessageType();
/*
* This block is done in this order because calling
* `addNestedType` and `addMessageType` makes a copy of the builder
* so the objects that our maps point to are no longer the objects
* that are being used to build the descriptions.
*/
for (HashMap.Entry<String, DescriptorProto.Builder> entry : messageBuilderMap.descendingMap().entrySet()) {
DescriptorProto.Builder messageBuilder = entry.getValue();
// Rewrite any enum defaults needed
for(FieldDescriptorProto.Builder field : messageBuilder.getFieldBuilderList()) {
String typeName = field.getTypeName();
if (typeName == null || !field.hasDefaultValue()) continue;
EnumDescriptorProto.Builder enumBuilder = enumBuilderMap.get(typeName);
if (enumBuilder == null) continue;
int defaultValue = Integer.parseInt(field.getDefaultValue());
for (EnumValueDescriptorProtoOrBuilder enumValue : enumBuilder.getValueOrBuilderList()) {
if (enumValue.getNumber() == defaultValue) {
field.setDefaultValue(enumValue.getName());
break;
}
}
}
// Turn Foo.Bar.Baz into a correctly nested structure with the correct name
String name = messageBuilder.getName();
int lastDot = name.lastIndexOf('.');
if (lastDot > packageNameLength) {
String parentName = name.substring(0, lastDot);
String shortName = name.substring(lastDot + 1);
messageBuilder.setName(shortName);
messageBuilderMap.get(parentName).addNestedType(messageBuilder);
} else {
if (packageNameLength > 0) {
// Remove the package name
messageBuilder.setName(name.substring(packageNameLength + 1));
}
// Add back in top level message definitions
builder.addMessageType(messageBuilder);
currentMessageIndex++;
}
}
descriptorPool.registerFileDescriptor(context, builder);
}
protected EnumDescriptorProto.Builder getNewEnumBuilder() {
return builder.addEnumTypeBuilder();
}
protected DescriptorProto.Builder getNewMessageBuilder() {
return builder.addMessageTypeBuilder();
}
protected boolean isProto3() {
return proto3;
}
private String getPackageName(List<DescriptorProto.Builder> messages, List<EnumDescriptorProto.Builder> enums) {
String shortest = null;
String longest = null;
/*
* The >= in the longest string comparisons below makes it so we replace
* the name in case all the names are the same length. This makes it so
* that the shortest and longest aren't the same name to prevent
* finding a "package" that isn't correct
*/
for (DescriptorProto.Builder message : messages) {
String name = message.getName();
int nameLength = name.length();
if (shortest == null) {
shortest = name;
longest = name;
} else if (nameLength < shortest.length()) {
shortest = name;
} else if (nameLength >= longest.length()) {
longest = name;
}
}
for (EnumDescriptorProto.Builder item : enums) {
String name = item.getName();
int nameLength = name.length();
if (shortest == null) {
shortest = name;
longest = name;
} else if (nameLength < shortest.length()) {
shortest = name;
} else if (nameLength >= longest.length()) {
longest = name;
}
}
if (shortest == null) {
return "";
}
int lastCommonDot = 0;
for (int i = 0; i < shortest.length(); i++) {
char nextChar = shortest.charAt(i);
if (nextChar != longest.charAt(i)) break;
if (nextChar == '.') lastCommonDot = i;
}
return shortest.substring(0, lastCommonDot);
}
private static RubyClass cDescriptor;
private static RubyClass cEnumBuilderContext;
private static RubyClass cEnumDescriptor;
private static RubyClass cMessageBuilderContext;
private FileDescriptorProto.Builder builder;
private RubyDescriptorPool descriptorPool;
private boolean proto3 = true;
}

View File

@ -37,7 +37,6 @@ import com.google.protobuf.DynamicMessage;
import org.jruby.*;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.runtime.Block;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ObjectAllocator;
@ -80,11 +79,12 @@ public class RubyMap extends RubyObject {
* on the same values as field-type symbols in message descriptors) that
* indicate the type of the map key and value fields.
*
* The supported key types are: :int32, :int64, :uint32, :uint64, :bool,
* :string, :bytes.
* The supported key types are: :int32, :int64, :uint32, :uint64, :fixed32,
* :fixed64, :sfixed32, :sfixed64, :sint32, :sint64, :bool, :string, :bytes.
*
* The supported value types are: :int32, :int64, :uint32, :uint64, :bool,
* :string, :bytes, :enum, :message.
* The supported value types are: :int32, :int64, :uint32, :uint64, :fixed32,
* :fixed64, :sfixed32, :sfixed64, :sint32, :sint64, :bool, :string, :bytes,
* :enum, :message.
*
* The third argument, value_typeclass, must be present if value_type is :enum
* or :message. As in RepeatedField#new, this argument must be a message class
@ -113,8 +113,14 @@ public class RubyMap extends RubyObject {
break;
case INT32:
case INT64:
case SINT32:
case SINT64:
case UINT32:
case UINT64:
case FIXED32:
case FIXED64:
case SFIXED32:
case SFIXED64:
case BOOL:
// These are OK.
break;
@ -154,7 +160,7 @@ public class RubyMap extends RubyObject {
* other types for keys, so deal with them specifically first
*/
if (keyTypeIsString && !(key instanceof RubySymbol || key instanceof RubyString)) {
throw context.runtime.newTypeError("Expected string for map key");
throw Utils.createTypeError(context, "Expected string for map key");
}
key = Utils.checkType(context, keyType, "key", key, (RubyModule) valueTypeClass);
value = Utils.checkType(context, valueType, "value", value, (RubyModule) valueTypeClass);
@ -399,7 +405,7 @@ public class RubyMap extends RubyObject {
protected RubyMap mergeIntoSelf(final ThreadContext context, IRubyObject hashmap) {
if (hashmap instanceof RubyHash) {
((RubyHash) hashmap).visitAll(new RubyHash.Visitor() {
((RubyHash) hashmap).visitAll(context, new RubyHash.Visitor() {
@Override
public void visit(IRubyObject key, IRubyObject val) {
if (val instanceof RubyHash && !valueTypeClass.isNil()) {
@ -407,14 +413,14 @@ public class RubyMap extends RubyObject {
}
indexSet(context, key, val);
}
});
}, null);
} else if (hashmap instanceof RubyMap) {
RubyMap other = (RubyMap) hashmap;
if (!typeCompatible(other)) {
throw Utils.createTypeError(context, "Attempt to merge Map with mismatching types");
}
} else {
throw context.runtime.newTypeError("Unknown type merging into Map");
throw Utils.createTypeError(context, "Unknown type merging into Map");
}
return this;
}

View File

@ -93,16 +93,18 @@ public class RubyMessage extends RubyObject {
throw runtime.newArgumentError("expected Hash arguments.");
}
RubyHash hash = args[0].convertToHash();
hash.visitAll(new RubyHash.Visitor() {
hash.visitAll(context, new RubyHash.Visitor() {
@Override
public void visit(IRubyObject key, IRubyObject value) {
if (!(key instanceof RubySymbol) && !(key instanceof RubyString))
throw runtime.newTypeError("Expected string or symbols as hash keys in initialization map.");
if (!(key instanceof RubySymbol) && !(key instanceof RubyString)) {
throw Utils.createTypeError(context,
"Expected string or symbols as hash keys in initialization map.");
}
final FieldDescriptor fieldDescriptor = findField(context, key, ignoreUnknownFieldsOnInit);
if (value == null || value.isNil()) return;
if (Utils.isMapEntry(fieldDescriptor)) {
if (fieldDescriptor.isMapField()) {
if (!(value instanceof RubyHash))
throw runtime.newArgumentError("Expected Hash object as initializer value for map field '" + key.asJavaString() + "' (given " + value.getMetaClass() + ").");
@ -130,7 +132,7 @@ public class RubyMessage extends RubyObject {
}
}
});
}, null);
}
return this;
}
@ -181,6 +183,9 @@ public class RubyMessage extends RubyObject {
sb.append(cname).append(colon);
for (FieldDescriptor fd : descriptor.getFields()) {
if (fd.hasPresence() && !fields.containsKey(fd)) {
continue;
}
if (addComma) {
sb.append(comma);
} else {
@ -346,9 +351,11 @@ public class RubyMessage extends RubyObject {
fieldDescriptor = descriptor.findFieldByName(methodName);
if (fieldDescriptor != null &&
(!proto3 || fieldDescriptor.getContainingOneof() == null) && // This seems like a bug but its needed to pass the tests...
fieldHasPresence(fieldDescriptor)) {
return fields.containsKey(fieldDescriptor) ? runtime.getTrue() : runtime.getFalse();
(!proto3 || fieldDescriptor.getContainingOneof() == null || fieldDescriptor
.getContainingOneof().isSynthetic()) &&
fieldDescriptor.hasPresence()) {
return fields.containsKey(fieldDescriptor) ? runtime.getTrue()
: runtime.getFalse();
}
} else if (methodName.endsWith(AS_VALUE_SUFFIX)) {
@ -428,12 +435,11 @@ public class RubyMessage extends RubyObject {
@JRubyMethod
public IRubyObject dup(ThreadContext context) {
RubyMessage dup = (RubyMessage) metaClass.newInstance(context, Block.NULL_BLOCK);
IRubyObject value;
for (FieldDescriptor fieldDescriptor : this.descriptor.getFields()) {
if (fieldDescriptor.isRepeated()) {
dup.fields.put(fieldDescriptor, this.getRepeatedField(context, fieldDescriptor));
} else if (fields.containsKey(fieldDescriptor)) {
dup.fields.put(fieldDescriptor, fields.get(fieldDescriptor));
dup.setFieldInternal(context, fieldDescriptor, fields.get(fieldDescriptor));
} else if (this.builder.hasField(fieldDescriptor)) {
dup.fields.put(fieldDescriptor, wrapField(context, fieldDescriptor, this.builder.getField(fieldDescriptor)));
}
@ -474,7 +480,7 @@ public class RubyMessage extends RubyObject {
* MessageClass.decode(data) => message
*
* Decodes the given data (as a string containing bytes in protocol buffers wire
* format) under the interpretration given by this message class's definition
* format) under the interpretation given by this message class's definition
* and returns a message object with the corresponding field values.
*/
@JRubyMethod(meta = true)
@ -532,11 +538,14 @@ public class RubyMessage extends RubyObject {
printer = printer.preservingProtoFieldNames();
}
}
printer = printer.usingTypeRegistry(JsonFormat.TypeRegistry.newBuilder().add(message.descriptor).build());
try {
result = printer.print(message.build(context));
} catch(InvalidProtocolBufferException e) {
} catch (InvalidProtocolBufferException e) {
throw runtime.newRuntimeError(e.getMessage());
} catch (IllegalArgumentException e) {
throw createParseError(context, e.getMessage());
}
return runtime.newString(result);
@ -547,7 +556,7 @@ public class RubyMessage extends RubyObject {
* MessageClass.decode_json(data, options = {}) => message
*
* Decodes the given data (as a string containing bytes in protocol buffers wire
* format) under the interpretration given by this message class's definition
* format) under the interpretation given by this message class's definition
* and returns a message object with the corresponding field values.
*
* @param options [Hash] options for the decoder
@ -577,6 +586,7 @@ public class RubyMessage extends RubyObject {
}
RubyMessage ret = (RubyMessage) ((RubyClass) recv).newInstance(context, Block.NULL_BLOCK);
parser = parser.usingTypeRegistry(JsonFormat.TypeRegistry.newBuilder().add(ret.descriptor).build());
try {
parser.merge(data.asJavaString(), ret.builder);
@ -633,6 +643,8 @@ public class RubyMessage extends RubyObject {
if (depth > SINK_MAXIMUM_NESTING) {
throw context.runtime.newRuntimeError("Maximum recursion depth exceeded during encoding.");
}
// Handle the typical case where the fields.keySet contain the fieldDescriptors
for (FieldDescriptor fieldDescriptor : fields.keySet()) {
IRubyObject value = fields.get(fieldDescriptor);
@ -648,15 +660,53 @@ public class RubyMessage extends RubyObject {
builder.clearField(fieldDescriptor);
for (int i = 0; i < repeatedField.size(); i++) {
Object item = convert(context, fieldDescriptor, repeatedField.get(i), depth);
Object item = convert(context, fieldDescriptor, repeatedField.get(i), depth,
/*isDefaultValueForBytes*/ false);
builder.addRepeatedField(fieldDescriptor, item);
}
} else {
builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth));
} else if (!value.isNil()) {
/**
* Detect the special case where default_value strings are provided for byte fields.
* If so, disable normal string encoding behavior within convert.
* For a more detailed explanation of other possible workarounds, see the comments
* above {@code com.google.protobuf.Internal#stringDefaultValue()
* stringDefaultValue}.
*/
boolean isDefaultStringForBytes = false;
FieldDescriptor enumFieldDescriptorForType =
this.builder.getDescriptorForType().findFieldByName("type");
String type = enumFieldDescriptorForType == null ?
null : fields.get(enumFieldDescriptorForType).toString();
if (type != null && type.equals("TYPE_BYTES") &&
fieldDescriptor.getFullName().equals("google.protobuf.FieldDescriptorProto.default_value")) {
isDefaultStringForBytes = true;
}
builder.setField(fieldDescriptor, convert(context, fieldDescriptor, value, depth, isDefaultStringForBytes));
}
}
// Handle cases where {@code fields} doesn't contain the value until after getFieldInternal
// is called - typical of a deserialized message. Skip non-maps and descriptors that already
// have an entry in {@code fields}.
for (FieldDescriptor fieldDescriptor : descriptor.getFields()) {
if (!fieldDescriptor.isMapField()) {
continue;
}
IRubyObject value = fields.get(fieldDescriptor);
if (value!=null) {
continue;
}
value = getFieldInternal(context, fieldDescriptor);
if (value instanceof RubyMap) {
builder.clearField(fieldDescriptor);
RubyDescriptor mapDescriptor = (RubyDescriptor) getDescriptorForField(context,
fieldDescriptor);
for (DynamicMessage kv : ((RubyMap) value).build(context, mapDescriptor, depth)) {
builder.addRepeatedField(fieldDescriptor, kv);
}
}
}
return builder.build();
}
@ -667,7 +717,7 @@ public class RubyMessage extends RubyObject {
if (fdef.isRepeated()) {
copy.fields.put(fdef, this.getRepeatedField(context, fdef).deepCopy(context));
} else if (fields.containsKey(fdef)) {
copy.fields.put(fdef, fields.get(fdef));
copy.setFieldInternal(context, fdef, fields.get(fdef));
} else if (builder.hasField(fdef)) {
copy.fields.put(fdef, wrapField(context, fdef, builder.getField(fdef)));
}
@ -691,7 +741,9 @@ public class RubyMessage extends RubyObject {
protected IRubyObject hasField(ThreadContext context, FieldDescriptor fieldDescriptor) {
validateMessageType(context, fieldDescriptor, "has?");
if (!fieldHasPresence(fieldDescriptor)) throw context.runtime.newArgumentError("does not track presence");
if (!fieldDescriptor.hasPresence()) {
throw context.runtime.newArgumentError("does not track presence");
}
return fields.containsKey(fieldDescriptor) ? context.runtime.getTrue() : context.runtime.getFalse();
}
@ -762,19 +814,24 @@ public class RubyMessage extends RubyObject {
// convert a ruby object to protobuf type, skip type check since it is checked on the way in
private Object convert(ThreadContext context,
FieldDescriptor fieldDescriptor,
IRubyObject value, int depth) {
Ruby runtime = context.runtime;
IRubyObject value, int depth, boolean isDefaultStringForBytes) {
Object val = null;
switch (fieldDescriptor.getType()) {
case INT32:
case SFIXED32:
case SINT32:
val = RubyNumeric.num2int(value);
break;
case INT64:
case SFIXED64:
case SINT64:
val = RubyNumeric.num2long(value);
break;
case FIXED32:
case UINT32:
val = Utils.num2uint(value);
break;
case FIXED64:
case UINT64:
val = Utils.num2ulong(context.runtime, value);
break;
@ -791,7 +848,11 @@ public class RubyMessage extends RubyObject {
val = ByteString.copyFrom(((RubyString) value).getBytes());
break;
case STRING:
val = ((RubyString) value).asJavaString();
if (isDefaultStringForBytes) {
val = ((RubyString) value).getByteList().toString();
} else {
val = value.asJavaString();
}
break;
case MESSAGE:
val = ((RubyMessage) value).build(context, depth + 1);
@ -819,6 +880,10 @@ public class RubyMessage extends RubyObject {
}
private IRubyObject wrapField(ThreadContext context, FieldDescriptor fieldDescriptor, Object value) {
return wrapField(context, fieldDescriptor, value, false);
}
private IRubyObject wrapField(ThreadContext context, FieldDescriptor fieldDescriptor, Object value, boolean encodeBytes) {
if (value == null) {
return context.runtime.getNil();
}
@ -827,6 +892,12 @@ public class RubyMessage extends RubyObject {
switch (fieldDescriptor.getType()) {
case INT32:
case INT64:
case FIXED32:
case SINT32:
case FIXED64:
case SINT64:
case SFIXED64:
case SFIXED32:
case UINT32:
case UINT64:
case FLOAT:
@ -834,7 +905,7 @@ public class RubyMessage extends RubyObject {
case BOOL:
case BYTES:
case STRING:
return Utils.wrapPrimaryValue(context, fieldDescriptor.getType(), value);
return Utils.wrapPrimaryValue(context, fieldDescriptor.getType(), value, encodeBytes);
case MESSAGE:
RubyClass typeClass = (RubyClass) ((RubyDescriptor) getDescriptorForField(context, fieldDescriptor)).msgclass(context);
RubyMessage msg = (RubyMessage) typeClass.newInstance(context, Block.NULL_BLOCK);
@ -872,22 +943,44 @@ public class RubyMessage extends RubyObject {
return getFieldInternal(context, fieldDescriptor, true);
}
private IRubyObject getFieldInternal(ThreadContext context, FieldDescriptor fieldDescriptor, boolean returnDefaults) {
private IRubyObject getFieldInternal(ThreadContext context, FieldDescriptor fieldDescriptor,
boolean returnDefaults) {
OneofDescriptor oneofDescriptor = fieldDescriptor.getContainingOneof();
if (oneofDescriptor != null) {
if (oneofCases.get(oneofDescriptor) == fieldDescriptor) {
return fields.get(fieldDescriptor);
IRubyObject value = fields.get(fieldDescriptor);
if (value == null) {
FieldDescriptor oneofCase = builder.getOneofFieldDescriptor(oneofDescriptor);
if (oneofCase != null) {
Object builderValue = builder.getField(oneofCase);
if (builderValue != null) {
boolean encodeBytes = oneofCase.hasDefaultValue() && builderValue.equals(oneofCase.getDefaultValue());
value = wrapField(context, oneofCase, builderValue, encodeBytes);
}
}
if (value == null) {
return context.nil;
} else {
return value;
}
} else {
return value;
}
} else {
FieldDescriptor oneofCase = builder.getOneofFieldDescriptor(oneofDescriptor);
if (oneofCase != fieldDescriptor) {
if (fieldDescriptor.getType() == FieldDescriptor.Type.MESSAGE || !returnDefaults) {
return context.nil;
} else {
return wrapField(context, fieldDescriptor, fieldDescriptor.getDefaultValue());
}
if (fieldDescriptor.getType() == FieldDescriptor.Type.MESSAGE
|| !returnDefaults) {
return context.nil;
} else {
return wrapField(context, fieldDescriptor,
fieldDescriptor.getDefaultValue(), true);
}
}
if (returnDefaults || builder.hasField(fieldDescriptor)) {
IRubyObject value = wrapField(context, oneofCase, builder.getField(oneofCase));
Object rawValue = builder.getField(oneofCase);
boolean encodeBytes = oneofCase.hasDefaultValue() && rawValue.equals(oneofCase.getDefaultValue());
IRubyObject value = wrapField(context, oneofCase, rawValue, encodeBytes);
fields.put(fieldDescriptor, value);
return value;
} else {
@ -896,7 +989,7 @@ public class RubyMessage extends RubyObject {
}
}
if (Utils.isMapEntry(fieldDescriptor)) {
if (fieldDescriptor.isMapField()) {
RubyMap map = (RubyMap) fields.get(fieldDescriptor);
if (map == null) {
map = newMapForField(context, fieldDescriptor);
@ -925,7 +1018,9 @@ public class RubyMessage extends RubyObject {
if (fields.containsKey(fieldDescriptor)) {
return fields.get(fieldDescriptor);
} else if (returnDefaults || builder.hasField(fieldDescriptor)) {
IRubyObject value = wrapField(context, fieldDescriptor, builder.getField(fieldDescriptor));
Object rawValue = builder.getField(fieldDescriptor);
boolean encodeBytes = fieldDescriptor.hasDefaultValue() && rawValue.equals(fieldDescriptor.getDefaultValue());
IRubyObject value = wrapField(context, fieldDescriptor, rawValue, encodeBytes);
if (builder.hasField(fieldDescriptor)) {
fields.put(fieldDescriptor, value);
}
@ -938,7 +1033,7 @@ public class RubyMessage extends RubyObject {
private IRubyObject setFieldInternal(ThreadContext context, FieldDescriptor fieldDescriptor, IRubyObject value) {
testFrozen("can't modify frozen " + getMetaClass());
if (Utils.isMapEntry(fieldDescriptor)) {
if (fieldDescriptor.isMapField()) {
if (!(value instanceof RubyMap)) {
throw Utils.createTypeError(context, "Expected Map instance");
}
@ -980,7 +1075,9 @@ public class RubyMessage extends RubyObject {
// Keep track of what Oneofs are set
if (value.isNil()) {
oneofCases.remove(oneofDescriptor);
addValue = false;
if (!oneofDescriptor.isSynthetic()) {
addValue = false;
}
} else {
oneofCases.put(oneofDescriptor, fieldDescriptor);
}
@ -1019,20 +1116,12 @@ public class RubyMessage extends RubyObject {
return context.runtime.newSymbol("UNKNOWN");
}
private boolean fieldHasPresence(FieldDescriptor fieldDescriptor) {
return !fieldDescriptor.isRepeated() &&
(fieldDescriptor.getType() == FieldDescriptor.Type.MESSAGE ||
fieldDescriptor.getContainingOneof() != null ||
!proto3);
}
private RubyRepeatedField rubyToRepeatedField(ThreadContext context,
FieldDescriptor fieldDescriptor, IRubyObject value) {
RubyArray arr = value.convertToArray();
RubyRepeatedField repeatedField = repeatedFieldForFieldDescriptor(context, fieldDescriptor);
IRubyObject[] values = new IRubyObject[arr.size()];
FieldDescriptor.Type fieldType = fieldDescriptor.getType();
String fieldName = fieldDescriptor.getName();
RubyModule typeClass = null;
if (fieldType == FieldDescriptor.Type.MESSAGE) {
@ -1045,8 +1134,11 @@ public class RubyMessage extends RubyObject {
for (int i = 0; i < arr.size(); i++) {
IRubyObject item = arr.eltInternal(i);
if (item.isNil()) {
throw Utils.createTypeError(context, "nil message not allowed here.");
}
if (item instanceof RubyHash && typeClass != null) {
values[i] = (IRubyObject) ((RubyClass) typeClass).newInstance(context, item, Block.NULL_BLOCK);
values[i] = ((RubyClass) typeClass).newInstance(context, item, Block.NULL_BLOCK);
} else {
if (fieldType == FieldDescriptor.Type.ENUM) {
item = enumToSymbol(context, fieldDescriptor.getEnumType(), item);
@ -1086,13 +1178,6 @@ public class RubyMessage extends RubyObject {
}
}
private FieldDescriptor getOneofCase(OneofDescriptor oneof) {
if (oneofCases.containsKey(oneof)) {
return oneofCases.get(oneof);
}
return builder.getOneofFieldDescriptor(oneof);
}
private boolean isWrappable(FieldDescriptor fieldDescriptor) {
if (fieldDescriptor.getType() != FieldDescriptor.Type.MESSAGE) return false;
@ -1118,7 +1203,7 @@ public class RubyMessage extends RubyObject {
private void validateMessageType(ThreadContext context, FieldDescriptor fieldDescriptor, String methodName) {
if (descriptor != fieldDescriptor.getContainingType()) {
throw context.runtime.newTypeError(methodName + " method called on wrong message type");
throw Utils.createTypeError(context, methodName + " method called on wrong message type");
}
}
@ -1139,6 +1224,4 @@ public class RubyMessage extends RubyObject {
private RubyClass cMap;
private boolean ignoreUnknownFieldsOnInit = false;
private boolean proto3;
}

Some files were not shown because too many files have changed in this diff Show More