PROTOBUF_SYNC_PIPER
pull/8262/head
Joshua Haberman 4 years ago
commit 51daaba638
  1. 26
      CHANGES.txt
  2. 14
      Makefile.am
  3. 1
      cmake/libprotoc.cmake
  4. 6
      conformance/Makefile.am
  5. 810
      conformance/failure_list_jruby.txt
  6. 8
      conformance/text_format_failure_list_jruby.txt
  7. 24
      csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
  8. 26
      csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
  9. 17
      csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
  10. 20
      csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
  11. 123
      csharp/src/Google.Protobuf/Collections/MapField.cs
  12. 2
      csharp/src/Google.Protobuf/ExtensionValue.cs
  13. 6
      csharp/src/Google.Protobuf/FieldCodec.cs
  14. 63
      csharp/src/Google.Protobuf/ParsingPrimitivesMessages.cs
  15. 19
      csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
  16. 64
      csharp/src/Google.Protobuf/WritingPrimitives.cs
  17. 11
      java/core/src/main/java/com/google/protobuf/Android.java
  18. 6
      java/core/src/main/java/com/google/protobuf/RawMessageInfo.java
  19. 5
      java/lite/proguard.pgcfg
  20. 223
      js/binary/reader_test.js
  21. 89
      js/binary/writer_test.js
  22. 220
      js/compatibility_tests/v3.1.0/binary/reader_test.js
  23. 90
      js/compatibility_tests/v3.1.0/binary/writer_test.js
  24. 101
      js/compatibility_tests/v3.1.0/maps_test.js
  25. 541
      js/compatibility_tests/v3.1.0/message_test.js
  26. 161
      js/maps_test.js
  27. 5
      js/message_test.js
  28. 27
      js/proto3_test.js
  29. 8
      kokoro/README.md
  30. 20
      kokoro/linux/dockerfile/test/php/Dockerfile
  31. 19
      kokoro/linux/dockerfile/test/php_32bit/Dockerfile
  32. 31
      kokoro/linux/dockerfile/test/python39/Dockerfile
  33. 18
      kokoro/linux/python39/build.sh
  34. 11
      kokoro/linux/python39/continuous.cfg
  35. 11
      kokoro/linux/python39/presubmit.cfg
  36. 18
      kokoro/linux/python39_cpp/build.sh
  37. 11
      kokoro/linux/python39_cpp/continuous.cfg
  38. 11
      kokoro/linux/python39_cpp/presubmit.cfg
  39. 3
      kokoro/release/csharp/windows/build_nuget.bat
  40. 1
      kokoro/release/python/linux/build_artifacts.sh
  41. 1
      kokoro/release/python/macos/build_artifacts.sh
  42. 10
      kokoro/release/python/windows/build_artifacts.bat
  43. 8
      kokoro/release/python/windows/build_single_artifact.bat
  44. 3
      kokoro/windows/csharp/build.bat
  45. 4
      php/composer.json
  46. 76
      php/ext/google/protobuf/array.c
  47. 19
      php/ext/google/protobuf/array.h
  48. 31
      php/ext/google/protobuf/convert.c
  49. 11
      php/ext/google/protobuf/convert.h
  50. 23
      php/ext/google/protobuf/def.h
  51. 120
      php/ext/google/protobuf/map.c
  52. 15
      php/ext/google/protobuf/map.h
  53. 143
      php/ext/google/protobuf/message.c
  54. 3
      php/ext/google/protobuf/message.h
  55. 2158
      php/ext/google/protobuf/php-upb.c
  56. 876
      php/ext/google/protobuf/php-upb.h
  57. 4
      php/ext/google/protobuf/protobuf.h
  58. 7
      php/src/Google/Protobuf/Internal/FileOptions.php
  59. 4
      php/src/Google/Protobuf/Internal/GPBWire.php
  60. 5
      php/src/Google/Protobuf/Internal/Message.php
  61. 12
      php/tests/ArrayTest.php
  62. 10
      php/tests/EncodeDecodeTest.php
  63. 66
      php/tests/GeneratedClassTest.php
  64. 7
      php/tests/GeneratedPhpdocTest.php
  65. 18
      php/tests/MapFieldTest.php
  66. 7
      php/tests/proto/test.proto
  67. 6
      python/release/wheel/Dockerfile
  68. 17
      python/release/wheel/README.md
  69. 27
      python/release/wheel/build_wheel_manylinux.sh
  70. 66
      python/release/wheel/protobuf_optimized_pip.sh
  71. 4
      python/setup.py
  72. 2
      python/tox.ini
  73. 10
      ruby/ext/google/protobuf_c/ruby-upb.c
  74. 2
      ruby/ext/google/protobuf_c/ruby-upb.h
  75. 1
      src/Makefile.am
  76. 2
      src/google/protobuf/arena.h
  77. 18
      src/google/protobuf/compiler/command_line_interface.cc
  78. 42
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  79. 2
      src/google/protobuf/compiler/cpp/cpp_field.h
  80. 5
      src/google/protobuf/compiler/cpp/cpp_file.cc
  81. 11
      src/google/protobuf/compiler/java/java_helpers.cc
  82. 1
      src/google/protobuf/compiler/java/java_message_field.cc
  83. 139
      src/google/protobuf/compiler/js/js_generator.cc
  84. 42
      src/google/protobuf/compiler/php/php_generator.cc
  85. 38
      src/google/protobuf/dynamic_message.cc
  86. 6
      src/google/protobuf/generated_message_table_driven_lite.h
  87. 17
      src/google/protobuf/message_lite.cc
  88. 2
      src/google/protobuf/message_lite.h
  89. 28
      src/google/protobuf/message_unittest.inc
  90. 29
      src/google/protobuf/metadata_lite.h
  91. 4
      src/google/protobuf/repeated_field.h
  92. 1
      src/google/protobuf/util/internal/default_value_objectwriter.cc
  93. 1
      src/google/protobuf/util/internal/json_stream_parser.cc
  94. 2
      src/google/protobuf/util/internal/json_stream_parser_test.cc
  95. 1
      src/google/protobuf/util/internal/proto_writer.cc
  96. 2
      src/google/protobuf/util/internal/protostream_objectsource.cc
  97. 80
      src/google/protobuf/util/internal/protostream_objectsource.h
  98. 12
      src/google/protobuf/util/internal/protostream_objectsource_test.cc
  99. 5
      src/google/protobuf/util/internal/type_info_test_helper.cc
  100. 5
      src/google/protobuf/util/internal/type_info_test_helper.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -12,6 +12,22 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
implementation detail users must not rely on. It should not be used in
unit tests.
* Change the signature of Any::PackFrom() to return false on error.
* Add fast reflection getter API for strings.
* Constant initialize the global message instances
* Avoid potential for missed wakeup in UnknownFieldSet
* Now Proto3 Oneof fields have "has" methods for checking their presence in
C++.
* Bugfix for NVCC
* Return early in _InternalSerialize for empty maps.
* Adding functionality for outputting map key values in proto path logging
output (does not affect comparison logic) and stop printing 'value' in the
path. The modified print functionality is in the
MessageDifferencer::StreamReporter.
* Fixes https://github.com/protocolbuffers/protobuf/issues/8129
* Ensure that null char symbol, package and file names do not result in a
crash.
* Constant initialize the global message instances
* Pretty print 'max' instead of numeric values in reserved ranges.
Java
* Avoid possible UnsupportedOperationException when using CodedInputSteam
@ -19,10 +35,20 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
* Make Durations.comparator() and Timestamps.comparator() Serializable.
* Add more detailed error information for dynamic message field type
validation failure
* Removed declarations of functions declared in java_names.h from
java_helpers.h.
* Now Proto3 Oneof fields have "has" methods for checking their presence in
Java.
* Annotates Java proto generated *_FIELD_NUMBER constants.
Python
* Provided an override for the reverse() method that will reverse the internal
collection directly instead of using the other methods of the BaseContainer.
* MessageFactory.CreateProtoype can be overridden to customize class creation.
Javascript
* Generate `getDescriptor` methods with `*` as their `this` type.
* Enforce `let/const` for generated messages.
2020-11-11 version 3.14.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)

@ -1094,17 +1094,21 @@ ruby_EXTRA_DIST= \
ruby/compatibility_tests/v3.0.0/test.sh \
ruby/compatibility_tests/v3.0.0/Rakefile \
ruby/compatibility_tests/v3.0.0/README.md \
ruby/ext/google/protobuf_c/convert.c \
ruby/ext/google/protobuf_c/convert.h \
ruby/ext/google/protobuf_c/defs.c \
ruby/ext/google/protobuf_c/encode_decode.c \
ruby/ext/google/protobuf_c/defs.h \
ruby/ext/google/protobuf_c/extconf.rb \
ruby/ext/google/protobuf_c/map.c \
ruby/ext/google/protobuf_c/map.h \
ruby/ext/google/protobuf_c/message.c \
ruby/ext/google/protobuf_c/message.h \
ruby/ext/google/protobuf_c/protobuf.c \
ruby/ext/google/protobuf_c/protobuf.h \
ruby/ext/google/protobuf_c/repeated_field.c \
ruby/ext/google/protobuf_c/storage.c \
ruby/ext/google/protobuf_c/upb.c \
ruby/ext/google/protobuf_c/upb.h \
ruby/ext/google/protobuf_c/repeated_field.h \
ruby/ext/google/protobuf_c/ruby-upb.c \
ruby/ext/google/protobuf_c/ruby-upb.h \
ruby/ext/google/protobuf_c/wrap_memcpy.c \
ruby/google-protobuf.gemspec \
ruby/lib/google/protobuf/message_exts.rb \
@ -1144,6 +1148,8 @@ ruby_EXTRA_DIST= \
ruby/tests/generated_code_proto2_test.rb \
ruby/tests/generated_code_proto2.proto \
ruby/tests/generated_code.proto \
ruby/tests/multi_level_nesting_test.proto \
ruby/tests/multi_level_nesting_test.rb \
ruby/tests/test_import_proto2.proto \
ruby/tests/test_import.proto \
ruby/tests/test_ruby_package_proto2.proto \

@ -93,6 +93,7 @@ set(libprotoc_headers
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_message.h
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_message_field.h
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_names.h
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_options.h
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_primitive_field.h

@ -5,7 +5,7 @@ conformance_protoc_inputs = \
$(top_srcdir)/src/google/protobuf/test_messages_proto3.proto
# proto2 input files, should be separated with proto3, as we
# can't generate proto2 files for ruby, php and objc
# can't generate proto2 files for php.
conformance_proto2_protoc_inputs = \
$(top_srcdir)/src/google/protobuf/test_messages_proto2.proto
@ -261,7 +261,7 @@ if USE_EXTERNAL_PROTOC
# Some implementations include pre-generated versions of well-known types.
protoc_middleman: $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. --js_out=import_style=commonjs,binary:. $(conformance_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --objc_out=. --python_out=. --js_out=import_style=commonjs,binary:. $(conformance_proto2_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --js_out=import_style=commonjs,binary:. $(conformance_proto2_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. --js_out=import_style=commonjs,binary:google-protobuf $(well_known_type_protoc_inputs)
## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
touch protoc_middleman
@ -273,7 +273,7 @@ else
# building out-of-tree.
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_protoc_inputs) )
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --objc_out=. --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_proto2_protoc_inputs) )
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_proto2_protoc_inputs) )
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd/google-protobuf $(well_known_type_protoc_inputs) )
## @mkdir -p lite
## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) )

@ -0,0 +1,810 @@
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
Recommended.Proto3.JsonInput.BoolFieldAllCapitalFalse
Recommended.Proto3.JsonInput.BoolFieldAllCapitalTrue
Recommended.Proto3.JsonInput.BoolFieldCamelCaseFalse
Recommended.Proto3.JsonInput.BoolFieldCamelCaseTrue
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.Proto3.JsonInput.BoolMapFieldKeyNotQuoted
Recommended.Proto3.JsonInput.DoubleFieldInfinityNotQuoted
Recommended.Proto3.JsonInput.DoubleFieldNanNotQuoted
Recommended.Proto3.JsonInput.DoubleFieldNegativeInfinityNotQuoted
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
Recommended.Proto3.JsonInput.FieldNameDuplicate
Recommended.Proto3.JsonInput.FieldNameNotQuoted
Recommended.Proto3.JsonInput.FloatFieldInfinityNotQuoted
Recommended.Proto3.JsonInput.FloatFieldNanNotQuoted
Recommended.Proto3.JsonInput.FloatFieldNegativeInfinityNotQuoted
Recommended.Proto3.JsonInput.Int32MapFieldKeyNotQuoted
Recommended.Proto3.JsonInput.Int64MapFieldKeyNotQuoted
Recommended.Proto3.JsonInput.JsonWithComments
Recommended.Proto3.JsonInput.StringFieldSingleQuoteBoth
Recommended.Proto3.JsonInput.StringFieldSingleQuoteKey
Recommended.Proto3.JsonInput.StringFieldSingleQuoteValue
Recommended.Proto3.JsonInput.StringFieldSurrogateInWrongOrder
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

@ -0,0 +1,8 @@
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Drop.TextFormatOutput
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Print.TextFormatOutput
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Drop.TextFormatOutput
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Print.TextFormatOutput
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Print.TextFormatOutput
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Print.TextFormatOutput

@ -35,6 +35,7 @@ using System.IO;
using Google.Protobuf.TestProtos;
using Google.Protobuf.Buffers;
using NUnit.Framework;
using System.Text;
namespace Google.Protobuf
{
@ -516,5 +517,28 @@ namespace Google.Protobuf
var stream = new CodedOutputStream(new byte[10]);
stream.Dispose();
}
[Test]
public void WriteStringsOfDifferentSizes()
{
for (int i = 1; i <= 1024; i++)
{
var buffer = new byte[4096];
var output = new CodedOutputStream(buffer);
var sb = new StringBuilder();
for (int j = 0; j < i; j++)
{
sb.Append((j % 10).ToString()); // incrementing numbers, repeating
}
var s = sb.ToString();
output.WriteString(s);
output.Flush();
// Verify written content
var input = new CodedInputStream(buffer);
Assert.AreEqual(s, input.ReadString());
}
}
}
}

@ -611,6 +611,32 @@ namespace Google.Protobuf.Collections
Assert.IsTrue(input.IsAtEnd);
}
[Test]
public void AddEntriesFrom_CodedInputStream_MissingKey()
{
// map will have string key and string value
var keyTag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
var valueTag = WireFormat.MakeTag(2, WireFormat.WireType.LengthDelimited);
var memoryStream = new MemoryStream();
var output = new CodedOutputStream(memoryStream);
output.WriteLength(11); // total of valueTag + value
output.WriteTag(valueTag);
output.WriteString("the_value");
output.Flush();
Console.WriteLine(BitConverter.ToString(memoryStream.ToArray()));
var field = new MapField<string, string>();
var mapCodec = new MapField<string, string>.Codec(FieldCodec.ForString(keyTag, ""), FieldCodec.ForString(valueTag, ""), 10);
var input = new CodedInputStream(memoryStream.ToArray());
field.AddEntriesFrom(input, mapCodec);
CollectionAssert.AreEquivalent(new[] { "" }, field.Keys);
CollectionAssert.AreEquivalent(new[] { "the_value" }, field.Values);
Assert.IsTrue(input.IsAtEnd);
}
#if !NET35
[Test]
public void IDictionaryKeys_Equals_IReadOnlyDictionaryKeys()

@ -116,7 +116,22 @@ namespace Google.Protobuf
var other = message.Clone();
Assert.AreEqual(message, other);
Assert.AreEqual(message.CalculateSize(), message.CalculateSize());
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
}
[Test]
public void TestDefaultValueRoundTrip()
{
var message = new TestAllExtensions();
message.SetExtension(OptionalBoolExtension, false);
Assert.IsFalse(message.GetExtension(OptionalBoolExtension));
Assert.IsTrue(message.HasExtension(OptionalBoolExtension));
var bytes = message.ToByteArray();
var registry = new ExtensionRegistry { OptionalBoolExtension };
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(registry).ParseFrom(bytes);
Assert.IsFalse(parsed.GetExtension(OptionalBoolExtension));
Assert.IsTrue(parsed.HasExtension(OptionalBoolExtension));
}
}
}

@ -35,7 +35,9 @@ using NUnit.Framework;
using ProtobufUnittest;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnitTest.Issues.TestProtos;
namespace Google.Protobuf.Reflection
{
@ -70,6 +72,24 @@ namespace Google.Protobuf.Reflection
TestFileDescriptor(converted[2], converted[1], converted[0]);
}
[Test]
public void FileDescriptor_BuildFromByteStrings_WithExtensionRegistry()
{
var extension = UnittestCustomOptionsProto3Extensions.MessageOpt1;
var byteStrings = new[]
{
DescriptorReflection.Descriptor.Proto.ToByteString(),
UnittestCustomOptionsProto3Reflection.Descriptor.Proto.ToByteString()
};
var registry = new ExtensionRegistry { extension };
var descriptor = FileDescriptor.BuildFromByteStrings(byteStrings, registry).Last();
var message = descriptor.MessageTypes.Single(t => t.Name == nameof(TestMessageWithCustomOptions));
var extensionValue = message.GetOptions().GetExtension(extension);
Assert.AreEqual(-56, extensionValue);
}
private void TestFileDescriptor(FileDescriptor file, FileDescriptor importedFile, FileDescriptor importedPublicFile)
{
Assert.AreEqual("unittest_proto3.proto", file.Name);

@ -448,12 +448,10 @@ namespace Google.Protobuf.Collections
[SecuritySafeCritical]
public void AddEntriesFrom(ref ParseContext ctx, Codec codec)
{
var adapter = new Codec.MessageAdapter(codec);
do
{
adapter.Reset();
ctx.ReadMessage(adapter);
this[adapter.Key] = adapter.Value;
KeyValuePair<TKey, TValue> entry = ParsingPrimitivesMessages.ReadMapEntry(ref ctx, codec);
this[entry.Key] = entry.Value;
} while (ParsingPrimitives.MaybeConsumeTag(ref ctx.buffer, ref ctx.state, codec.MapTag));
}
@ -485,13 +483,13 @@ namespace Google.Protobuf.Collections
[SecuritySafeCritical]
public void WriteTo(ref WriteContext ctx, Codec codec)
{
var message = new Codec.MessageAdapter(codec);
foreach (var entry in list)
{
message.Key = entry.Key;
message.Value = entry.Value;
ctx.WriteTag(codec.MapTag);
ctx.WriteMessage(message);
WritingPrimitives.WriteLength(ref ctx.buffer, ref ctx.state, CalculateEntrySize(codec, entry));
codec.KeyCodec.WriteTagAndValue(ref ctx, entry.Key);
codec.ValueCodec.WriteTagAndValue(ref ctx, entry.Value);
}
}
@ -506,18 +504,22 @@ namespace Google.Protobuf.Collections
{
return 0;
}
var message = new Codec.MessageAdapter(codec);
int size = 0;
foreach (var entry in list)
{
message.Key = entry.Key;
message.Value = entry.Value;
int entrySize = CalculateEntrySize(codec, entry);
size += CodedOutputStream.ComputeRawVarint32Size(codec.MapTag);
size += CodedOutputStream.ComputeMessageSize(message);
size += CodedOutputStream.ComputeLengthSize(entrySize) + entrySize;
}
return size;
}
private static int CalculateEntrySize(Codec codec, KeyValuePair<TKey, TValue> entry)
{
return codec.KeyCodec.CalculateSizeWithTag(entry.Key) + codec.ValueCodec.CalculateSizeWithTag(entry.Value);
}
/// <summary>
/// Returns a string representation of this repeated field, in the same
/// way as it would be represented by the default JSON formatter.
@ -655,100 +657,19 @@ namespace Google.Protobuf.Collections
}
/// <summary>
/// The tag used in the enclosing message to indicate map entries.
/// The key codec.
/// </summary>
internal uint MapTag { get { return mapTag; } }
internal FieldCodec<TKey> KeyCodec => keyCodec;
/// <summary>
/// A mutable message class, used for parsing and serializing. This
/// delegates the work to a codec, but implements the <see cref="IMessage"/> interface
/// for interop with <see cref="CodedInputStream"/> and <see cref="CodedOutputStream"/>.
/// This is nested inside Codec as it's tightly coupled to the associated codec,
/// and it's simpler if it has direct access to all its fields.
/// The value codec.
/// </summary>
internal class MessageAdapter : IMessage, IBufferMessage
{
private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 };
private readonly Codec codec;
internal TKey Key { get; set; }
internal TValue Value { get; set; }
internal MessageAdapter(Codec codec)
{
this.codec = codec;
}
internal void Reset()
{
Key = codec.keyCodec.DefaultValue;
Value = codec.valueCodec.DefaultValue;
}
public void MergeFrom(CodedInputStream input)
{
// Message adapter is an internal class and we know that all the parsing will happen via InternalMergeFrom.
throw new NotImplementedException();
}
internal FieldCodec<TValue> ValueCodec => valueCodec;
[SecuritySafeCritical]
public void InternalMergeFrom(ref ParseContext ctx)
{
uint tag;
while ((tag = ctx.ReadTag()) != 0)
{
if (tag == codec.keyCodec.Tag)
{
Key = codec.keyCodec.Read(ref ctx);
}
else if (tag == codec.valueCodec.Tag)
{
Value = codec.valueCodec.Read(ref ctx);
}
else
{
ParsingPrimitivesMessages.SkipLastField(ref ctx.buffer, ref ctx.state);
}
}
// Corner case: a map entry with a key but no value, where the value type is a message.
// Read it as if we'd seen input with no data (i.e. create a "default" message).
if (Value == null)
{
if (ctx.state.CodedInputStream != null)
{
// the decoded message might not support parsing from ParseContext, so
// we need to allow fallback to the legacy MergeFrom(CodedInputStream) parsing.
Value = codec.valueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData));
}
else
{
ParseContext.Initialize(new ReadOnlySequence<byte>(ZeroLengthMessageStreamData), out ParseContext zeroLengthCtx);
Value = codec.valueCodec.Read(ref zeroLengthCtx);
}
}
}
public void WriteTo(CodedOutputStream output)
{
// Message adapter is an internal class and we know that all the writing will happen via InternalWriteTo.
throw new NotImplementedException();
}
[SecuritySafeCritical]
public void InternalWriteTo(ref WriteContext ctx)
{
codec.keyCodec.WriteTagAndValue(ref ctx, Key);
codec.valueCodec.WriteTagAndValue(ref ctx, Value);
}
public int CalculateSize()
{
return codec.keyCodec.CalculateSizeWithTag(Key) + codec.valueCodec.CalculateSizeWithTag(Value);
}
MessageDescriptor IMessage.Descriptor { get { return null; } }
}
/// <summary>
/// The tag used in the enclosing message to indicate map entries.
/// </summary>
internal uint MapTag => mapTag;
}
private class MapView<T> : ICollection<T>, ICollection

@ -59,7 +59,7 @@ namespace Google.Protobuf
public int CalculateSize()
{
return codec.CalculateSizeWithTag(field);
return codec.CalculateUnconditionalSizeWithTag(field);
}
public IExtensionValue Clone()

@ -876,6 +876,12 @@ namespace Google.Protobuf
/// </summary>
public int CalculateSizeWithTag(T value) => IsDefault(value) ? 0 : ValueSizeCalculator(value) + tagSize;
/// <summary>
/// Calculates the size required to write the given value, with a tag, even
/// if the value is the default.
/// </summary>
internal int CalculateUnconditionalSizeWithTag(T value) => ValueSizeCalculator(value) + tagSize;
private bool IsDefault(T value) => EqualityComparer.Equals(value, DefaultValue);
}
}

@ -32,9 +32,11 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Security;
using Google.Protobuf.Collections;
namespace Google.Protobuf
{
@ -44,6 +46,8 @@ namespace Google.Protobuf
[SecuritySafeCritical]
internal static class ParsingPrimitivesMessages
{
private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 };
public static void SkipLastField(ref ReadOnlySpan<byte> buffer, ref ParserInternalState state)
{
if (state.lastTag == 0)
@ -134,6 +138,65 @@ namespace Google.Protobuf
SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit);
}
public static KeyValuePair<TKey, TValue> ReadMapEntry<TKey, TValue>(ref ParseContext ctx, MapField<TKey, TValue>.Codec codec)
{
int length = ParsingPrimitives.ParseLength(ref ctx.buffer, ref ctx.state);
if (ctx.state.recursionDepth >= ctx.state.recursionLimit)
{
throw InvalidProtocolBufferException.RecursionLimitExceeded();
}
int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, length);
++ctx.state.recursionDepth;
TKey key = codec.KeyCodec.DefaultValue;
TValue value = codec.ValueCodec.DefaultValue;
uint tag;
while ((tag = ctx.ReadTag()) != 0)
{
if (tag == codec.KeyCodec.Tag)
{
key = codec.KeyCodec.Read(ref ctx);
}
else if (tag == codec.ValueCodec.Tag)
{
value = codec.ValueCodec.Read(ref ctx);
}
else
{
SkipLastField(ref ctx.buffer, ref ctx.state);
}
}
// Corner case: a map entry with a key but no value, where the value type is a message.
// Read it as if we'd seen input with no data (i.e. create a "default" message).
if (value == null)
{
if (ctx.state.CodedInputStream != null)
{
// the decoded message might not support parsing from ParseContext, so
// we need to allow fallback to the legacy MergeFrom(CodedInputStream) parsing.
value = codec.ValueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData));
}
else
{
ParseContext.Initialize(new ReadOnlySequence<byte>(ZeroLengthMessageStreamData), out ParseContext zeroLengthCtx);
value = codec.ValueCodec.Read(ref zeroLengthCtx);
}
}
CheckReadEndOfStreamTag(ref ctx.state);
// Check that we've read exactly as much data as expected.
if (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state))
{
throw InvalidProtocolBufferException.TruncatedMessage();
}
--ctx.state.recursionDepth;
SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit);
return new KeyValuePair<TKey, TValue>(key, value);
}
public static void ReadGroup(ref ParseContext ctx, IMessage message)
{
if (ctx.state.recursionDepth >= ctx.state.recursionLimit)

@ -481,18 +481,21 @@ namespace Google.Protobuf.Reflection
/// dependencies must come before the descriptor which depends on them. (If A depends on B, and B
/// depends on C, then the descriptors must be presented in the order C, B, A.) This is compatible
/// with the order in which protoc provides descriptors to plugins.</param>
/// <param name="registry">The extension registry to use when parsing, or null if no extensions are required.</param>
/// <returns>The file descriptors corresponding to <paramref name="descriptorData"/>.</returns>
public static IReadOnlyList<FileDescriptor> BuildFromByteStrings(IEnumerable<ByteString> descriptorData)
public static IReadOnlyList<FileDescriptor> BuildFromByteStrings(IEnumerable<ByteString> descriptorData, ExtensionRegistry registry)
{
ProtoPreconditions.CheckNotNull(descriptorData, nameof(descriptorData));
var parser = FileDescriptorProto.Parser.WithExtensionRegistry(registry);
// TODO: See if we can build a single DescriptorPool instead of building lots of them.
// This will all behave correctly, but it's less efficient than we'd like.
var descriptors = new List<FileDescriptor>();
var descriptorsByName = new Dictionary<string, FileDescriptor>();
foreach (var data in descriptorData)
{
var proto = FileDescriptorProto.Parser.ParseFrom(data);
var proto = parser.ParseFrom(data);
var dependencies = new List<FileDescriptor>();
foreach (var dependencyName in proto.Dependency)
{
@ -518,6 +521,18 @@ namespace Google.Protobuf.Reflection
return new ReadOnlyCollection<FileDescriptor>(descriptors);
}
/// <summary>
/// Converts the given descriptor binary data into FileDescriptor objects.
/// Note: reflection using the returned FileDescriptors is not currently supported.
/// </summary>
/// <param name="descriptorData">The binary file descriptor proto data. Must not be null, and any
/// dependencies must come before the descriptor which depends on them. (If A depends on B, and B
/// depends on C, then the descriptors must be presented in the order C, B, A.) This is compatible
/// with the order in which protoc provides descriptors to plugins.</param>
/// <returns>The file descriptors corresponding to <paramref name="descriptorData"/>.</returns>
public static IReadOnlyList<FileDescriptor> BuildFromByteStrings(IEnumerable<ByteString> descriptorData) =>
BuildFromByteStrings(descriptorData, null);
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>

@ -163,10 +163,25 @@ namespace Google.Protobuf
/// </summary>
public static void WriteString(ref Span<byte> buffer, ref WriterInternalState state, string value)
{
// Optimise the case where we have enough space to write
// the string directly to the buffer, which should be common.
const int MaxBytesPerChar = 3;
const int MaxSmallStringLength = 128 / MaxBytesPerChar;
// The string is small enough that the length will always be a 1 byte varint.
// Also there is enough space to write length + bytes to buffer.
// Write string directly to the buffer, and then write length.
// This saves calling GetByteCount on the string. We get the string length from GetBytes.
if (value.Length <= MaxSmallStringLength && buffer.Length - state.position - 1 >= value.Length * MaxBytesPerChar)
{
int indexOfLengthDelimiter = state.position++;
buffer[indexOfLengthDelimiter] = (byte)WriteStringToBuffer(buffer, ref state, value);
return;
}
int length = Utf8Encoding.GetByteCount(value);
WriteLength(ref buffer, ref state, length);
// Optimise the case where we have enough space to write
// the string directly to the buffer, which should be common.
if (buffer.Length - state.position >= length)
{
if (length == value.Length) // Must be all ASCII...
@ -179,23 +194,7 @@ namespace Google.Protobuf
}
else
{
#if NETSTANDARD1_1
// slowpath when Encoding.GetBytes(Char*, Int32, Byte*, Int32) is not available
byte[] bytes = Utf8Encoding.GetBytes(value);
WriteRawBytes(ref buffer, ref state, bytes);
#else
ReadOnlySpan<char> source = value.AsSpan();
int bytesUsed;
unsafe
{
fixed (char* sourceChars = &MemoryMarshal.GetReference(source))
fixed (byte* destinationBytes = &MemoryMarshal.GetReference(buffer.Slice(state.position)))
{
bytesUsed = Utf8Encoding.GetBytes(sourceChars, source.Length, destinationBytes, buffer.Length);
}
}
state.position += bytesUsed;
#endif
WriteStringToBuffer(buffer, ref state, value);
}
}
else
@ -209,6 +208,33 @@ namespace Google.Protobuf
}
}
private static int WriteStringToBuffer(Span<byte> buffer, ref WriterInternalState state, string value)
{
#if NETSTANDARD1_1
// slowpath when Encoding.GetBytes(Char*, Int32, Byte*, Int32) is not available
byte[] bytes = Utf8Encoding.GetBytes(value);
WriteRawBytes(ref buffer, ref state, bytes);
return bytes.Length;
#else
ReadOnlySpan<char> source = value.AsSpan();
int bytesUsed;
unsafe
{
fixed (char* sourceChars = &MemoryMarshal.GetReference(source))
fixed (byte* destinationBytes = &MemoryMarshal.GetReference(buffer))
{
bytesUsed = Utf8Encoding.GetBytes(
sourceChars,
source.Length,
destinationBytes + state.position,
buffer.Length - state.position);
}
}
state.position += bytesUsed;
return bytesUsed;
#endif
}
/// <summary>
/// Write a byte string, without a tag, to the stream.
/// The data is length-prefixed.

@ -31,14 +31,21 @@
package com.google.protobuf;
final class Android {
private Android() {
}
// Set to true in lite_proguard_android.pgcfg.
@SuppressWarnings("ConstantField")
private static boolean ASSUME_ANDROID;
private static final Class<?> MEMORY_CLASS = getClassForName("libcore.io.Memory");
private static final boolean IS_ROBOLECTRIC =
getClassForName("org.robolectric.Robolectric") != null;
!ASSUME_ANDROID && getClassForName("org.robolectric.Robolectric") != null;
/** Returns {@code true} if running on an Android device. */
static boolean isOnAndroidDevice() {
return MEMORY_CLASS != null && !IS_ROBOLECTRIC;
return ASSUME_ANDROID || (MEMORY_CLASS != null && !IS_ROBOLECTRIC);
}
/** Returns the memory class or {@code null} if not on Android device. */

@ -184,20 +184,20 @@ final class RawMessageInfo implements MessageInfo {
int value;
try {
value = (int) info.charAt(0);
} catch (ArrayIndexOutOfBoundsException e) {
} catch (StringIndexOutOfBoundsException e) {
// This is a fix for issues
// that error out on a subset of phones on charAt(0) with an index out of bounds exception.
char[] infoChars = info.toCharArray();
info = new String(infoChars);
try {
value = (int) info.charAt(0);
} catch (ArrayIndexOutOfBoundsException e2) {
} catch (StringIndexOutOfBoundsException e2) {
try {
char[] infoChars2 = new char[info.length()];
info.getChars(0, info.length(), infoChars2, 0);
info = new String(infoChars2);
value = (int) info.charAt(0);
} catch (ArrayIndexOutOfBoundsException e3) {
} catch (StringIndexOutOfBoundsException | ArrayIndexOutOfBoundsException e3) {
throw new IllegalStateException(
String.format(
"Failed parsing '%s' with charArray.length of %d", info, infoChars.length),

@ -1,3 +1,8 @@
# Skip runtime check for isOnAndroidDevice().
# One line to make it easy to remove with sed.
-assumevalues class com.google.protobuf.Android { static boolean ASSUME_ANDROID return true; }
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
<fields>;
}

@ -46,7 +46,8 @@ goog.require('jspb.BinaryConstants');
goog.require('jspb.BinaryDecoder');
goog.require('jspb.BinaryReader');
goog.require('jspb.BinaryWriter');
goog.require('jspb.utils');
goog.requireType('jspb.BinaryMessage');
describe('binaryReaderTest', function() {
@ -55,7 +56,7 @@ describe('binaryReaderTest', function() {
*/
it('testInstanceCaches', /** @suppress {visibility} */ function() {
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
writer.writeMessage(1, dummyMessage, goog.nullFunction);
writer.writeMessage(2, dummyMessage, goog.nullFunction);
@ -135,7 +136,7 @@ describe('binaryReaderTest', function() {
// Calling readMessage on a non-delimited field should trigger an
// assertion.
var reader = jspb.BinaryReader.alloc([8, 1]);
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
reader.nextField();
assertThrows(function() {
reader.readMessage(dummyMessage, goog.nullFunction);
@ -144,47 +145,91 @@ describe('binaryReaderTest', function() {
// Reading past the end of the stream should trigger an assertion.
reader = jspb.BinaryReader.alloc([9, 1]);
reader.nextField();
assertThrows(function() {reader.readFixed64()});
assertThrows(function() {
reader.readFixed64()
});
// Reading past the end of a submessage should trigger an assertion.
reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
reader.nextField();
reader.readMessage(dummyMessage, function() {
reader.nextField();
assertThrows(function() {reader.readFixed32()});
assertThrows(function() {
reader.readFixed32()
});
});
// Skipping an invalid field should trigger an assertion.
reader = jspb.BinaryReader.alloc([12, 1]);
reader.nextWireType_ = 1000;
assertThrows(function() {reader.skipField()});
assertThrows(function() {
reader.skipField()
});
// Reading fields with the wrong wire type should assert.
reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
reader.nextField();
assertThrows(function() {reader.readInt32()});
assertThrows(function() {reader.readInt32String()});
assertThrows(function() {reader.readInt64()});
assertThrows(function() {reader.readInt64String()});
assertThrows(function() {reader.readUint32()});
assertThrows(function() {reader.readUint32String()});
assertThrows(function() {reader.readUint64()});
assertThrows(function() {reader.readUint64String()});
assertThrows(function() {reader.readSint32()});
assertThrows(function() {reader.readBool()});
assertThrows(function() {reader.readEnum()});
assertThrows(function() {
reader.readInt32()
});
assertThrows(function() {
reader.readInt32String()
});
assertThrows(function() {
reader.readInt64()
});
assertThrows(function() {
reader.readInt64String()
});
assertThrows(function() {
reader.readUint32()
});
assertThrows(function() {
reader.readUint32String()
});
assertThrows(function() {
reader.readUint64()
});
assertThrows(function() {
reader.readUint64String()
});
assertThrows(function() {
reader.readSint32()
});
assertThrows(function() {
reader.readBool()
});
assertThrows(function() {
reader.readEnum()
});
reader = jspb.BinaryReader.alloc([8, 1]);
reader.nextField();
assertThrows(function() {reader.readFixed32()});
assertThrows(function() {reader.readFixed64()});
assertThrows(function() {reader.readSfixed32()});
assertThrows(function() {reader.readSfixed64()});
assertThrows(function() {reader.readFloat()});
assertThrows(function() {reader.readDouble()});
assertThrows(function() {
reader.readFixed32()
});
assertThrows(function() {
reader.readFixed64()
});
assertThrows(function() {
reader.readSfixed32()
});
assertThrows(function() {
reader.readSfixed64()
});
assertThrows(function() {
reader.readFloat()
});
assertThrows(function() {
reader.readDouble()
});
assertThrows(function() {reader.readString()});
assertThrows(function() {reader.readBytes()});
assertThrows(function() {
reader.readString()
});
assertThrows(function() {
reader.readBytes()
});
});
@ -198,8 +243,8 @@ describe('binaryReaderTest', function() {
* @private
* @suppress {missingProperties}
*/
var doTestUnsignedField_ = function(readField,
writeField, epsilon, upperLimit, filter) {
var doTestUnsignedField_ = function(
readField, writeField, epsilon, upperLimit, filter) {
assertNotNull(readField);
assertNotNull(writeField);
@ -250,8 +295,8 @@ describe('binaryReaderTest', function() {
* @private
* @suppress {missingProperties}
*/
var doTestSignedField_ = function(readField,
writeField, epsilon, lowerLimit, upperLimit, filter) {
var doTestSignedField_ = function(
readField, writeField, epsilon, lowerLimit, upperLimit, filter) {
var writer = new jspb.BinaryWriter();
// Encode zero and limits.
@ -267,20 +312,14 @@ describe('binaryReaderTest', function() {
for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
var val = filter(cursor);
writeField.call(writer, 6, val);
inputValues.push({
fieldNumber: 6,
value: val
});
inputValues.push({fieldNumber: 6, value: val});
}
// Encode positive values.
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
var val = filter(cursor);
writeField.call(writer, 7, val);
inputValues.push({
fieldNumber: 7,
value: val
});
inputValues.push({fieldNumber: 7, value: val});
}
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
@ -327,33 +366,34 @@ describe('binaryReaderTest', function() {
assertNotUndefined(jspb.BinaryWriter.prototype.writeBool);
doTestUnsignedField_(
jspb.BinaryReader.prototype.readUint32,
jspb.BinaryWriter.prototype.writeUint32,
1, Math.pow(2, 32) - 1, Math.round);
jspb.BinaryWriter.prototype.writeUint32, 1, Math.pow(2, 32) - 1,
Math.round);
doTestUnsignedField_(
jspb.BinaryReader.prototype.readUint64,
jspb.BinaryWriter.prototype.writeUint64,
1, Math.pow(2, 64) - 1025, Math.round);
jspb.BinaryWriter.prototype.writeUint64, 1, Math.pow(2, 64) - 1025,
Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readInt32,
jspb.BinaryWriter.prototype.writeInt32,
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
jspb.BinaryWriter.prototype.writeInt32, 1, -Math.pow(2, 31),
Math.pow(2, 31) - 1, Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readInt64,
jspb.BinaryWriter.prototype.writeInt64,
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
jspb.BinaryWriter.prototype.writeInt64, 1, -Math.pow(2, 63),
Math.pow(2, 63) - 513, Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readEnum,
jspb.BinaryWriter.prototype.writeEnum,
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
jspb.BinaryWriter.prototype.writeEnum, 1, -Math.pow(2, 31),
Math.pow(2, 31) - 1, Math.round);
doTestUnsignedField_(
jspb.BinaryReader.prototype.readBool,
jspb.BinaryWriter.prototype.writeBool,
1, 1, function(x) { return !!x; });
jspb.BinaryWriter.prototype.writeBool, 1, 1, function(x) {
return !!x;
});
});
@ -387,24 +427,22 @@ describe('binaryReaderTest', function() {
// uint32 and sint32 take no more than 5 bytes
// 08 - field prefix (type = 0 means varint)
doTestHexStringVarint_(
jspb.BinaryReader.prototype.readUint32,
12, '08 8C 80 80 80 00');
jspb.BinaryReader.prototype.readUint32, 12, '08 8C 80 80 80 00');
// 11 stands for -6 in zigzag encoding
doTestHexStringVarint_(
jspb.BinaryReader.prototype.readSint32,
-6, '08 8B 80 80 80 00');
jspb.BinaryReader.prototype.readSint32, -6, '08 8B 80 80 80 00');
// uint64 and sint64 take no more than 10 bytes
// 08 - field prefix (type = 0 means varint)
doTestHexStringVarint_(
jspb.BinaryReader.prototype.readUint64,
12, '08 8C 80 80 80 80 80 80 80 80 00');
jspb.BinaryReader.prototype.readUint64, 12,
'08 8C 80 80 80 80 80 80 80 80 00');
// 11 stands for -6 in zigzag encoding
doTestHexStringVarint_(
jspb.BinaryReader.prototype.readSint64,
-6, '08 8B 80 80 80 80 80 80 80 80 00');
jspb.BinaryReader.prototype.readSint64, -6,
'08 8B 80 80 80 80 80 80 80 80 00');
});
/**
@ -440,27 +478,15 @@ describe('binaryReaderTest', function() {
var writer = new jspb.BinaryWriter();
var testSignedData = [
'2730538252207801776',
'-2688470994844604560',
'3398529779486536359',
'3568577411627971000',
'272477188847484900',
'-6649058714086158188',
'-7695254765712060806',
'-4525541438037104029',
'-4993706538836508568',
'2730538252207801776', '-2688470994844604560', '3398529779486536359',
'3568577411627971000', '272477188847484900', '-6649058714086158188',
'-7695254765712060806', '-4525541438037104029', '-4993706538836508568',
'4990160321893729138'
];
var testUnsignedData = [
'7822732630241694882',
'6753602971916687352',
'2399935075244442116',
'8724292567325338867',
'16948784802625696584',
'4136275908516066934',
'3575388346793700364',
'5167142028379259461',
'1557573948689737699',
'7822732630241694882', '6753602971916687352', '2399935075244442116',
'8724292567325338867', '16948784802625696584', '4136275908516066934',
'3575388346793700364', '5167142028379259461', '1557573948689737699',
'17100725280812548567'
];
@ -488,13 +514,13 @@ describe('binaryReaderTest', function() {
it('testZigzagFields', function() {
doTestSignedField_(
jspb.BinaryReader.prototype.readSint32,
jspb.BinaryWriter.prototype.writeSint32,
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
jspb.BinaryWriter.prototype.writeSint32, 1, -Math.pow(2, 31),
Math.pow(2, 31) - 1, Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readSint64,
jspb.BinaryWriter.prototype.writeSint64,
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
jspb.BinaryWriter.prototype.writeSint64, 1, -Math.pow(2, 63),
Math.pow(2, 63) - 513, Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readSintHash64,
@ -509,23 +535,23 @@ describe('binaryReaderTest', function() {
it('testFixedFields', function() {
doTestUnsignedField_(
jspb.BinaryReader.prototype.readFixed32,
jspb.BinaryWriter.prototype.writeFixed32,
1, Math.pow(2, 32) - 1, Math.round);
jspb.BinaryWriter.prototype.writeFixed32, 1, Math.pow(2, 32) - 1,
Math.round);
doTestUnsignedField_(
jspb.BinaryReader.prototype.readFixed64,
jspb.BinaryWriter.prototype.writeFixed64,
1, Math.pow(2, 64) - 1025, Math.round);
jspb.BinaryWriter.prototype.writeFixed64, 1, Math.pow(2, 64) - 1025,
Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readSfixed32,
jspb.BinaryWriter.prototype.writeSfixed32,
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
jspb.BinaryWriter.prototype.writeSfixed32, 1, -Math.pow(2, 31),
Math.pow(2, 31) - 1, Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readSfixed64,
jspb.BinaryWriter.prototype.writeSfixed64,
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
jspb.BinaryWriter.prototype.writeSfixed64, 1, -Math.pow(2, 63),
Math.pow(2, 63) - 513, Math.round);
});
@ -536,18 +562,17 @@ describe('binaryReaderTest', function() {
doTestSignedField_(
jspb.BinaryReader.prototype.readFloat,
jspb.BinaryWriter.prototype.writeFloat,
jspb.BinaryConstants.FLOAT32_MIN,
-jspb.BinaryConstants.FLOAT32_MAX,
jspb.BinaryConstants.FLOAT32_MAX,
truncate);
jspb.BinaryConstants.FLOAT32_MIN, -jspb.BinaryConstants.FLOAT32_MAX,
jspb.BinaryConstants.FLOAT32_MAX, truncate);
doTestSignedField_(
jspb.BinaryReader.prototype.readDouble,
jspb.BinaryWriter.prototype.writeDouble,
jspb.BinaryConstants.FLOAT64_EPS * 10,
-jspb.BinaryConstants.FLOAT64_MIN,
jspb.BinaryConstants.FLOAT64_MIN,
function(x) { return x; });
-jspb.BinaryConstants.FLOAT64_MIN, jspb.BinaryConstants.FLOAT64_MIN,
function(x) {
return x;
});
});
@ -614,7 +639,7 @@ describe('binaryReaderTest', function() {
*/
it('testNesting', function() {
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
writer.writeInt32(1, 100);
@ -707,7 +732,7 @@ describe('binaryReaderTest', function() {
// Write a group with a nested group inside.
writer.writeInt32(5, sentinel);
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
writer.writeGroup(5, dummyMessage, function() {
// Previously the skipGroup implementation was wrong, which only consume
// the decoder by nextField. This case is for making the previous
@ -726,7 +751,7 @@ describe('binaryReaderTest', function() {
writer.writeInt64(84, 42);
writer.writeInt64(84, 44);
writer.writeBytes(
43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
});
});
@ -875,7 +900,7 @@ describe('binaryReaderTest', function() {
var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
var blob = [1, 2, 3, 4, 5];
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
writer.writeMessage(1, dummyMessage, function() {
writer.writeMessage(1, dummyMessage, function() {
@ -908,7 +933,7 @@ describe('binaryReaderTest', function() {
*/
it('testReadCallbacks', function() {
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
// Add an int, a submessage, and another int.
writer.writeInt32(1, 100);

@ -44,7 +44,8 @@ goog.require('jspb.BinaryConstants');
goog.require('jspb.BinaryReader');
goog.require('jspb.BinaryWriter');
goog.require('jspb.utils');
goog.require('goog.crypt.base64');
goog.requireType('jspb.BinaryMessage');
/**
* @param {function()} func This function should throw an error when run.
@ -61,7 +62,7 @@ describe('binaryWriterTest', function() {
it('testWriteErrors', function() {
// Submessages with invalid field indices should assert.
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
assertFails(function() {
writer.writeMessage(-1, dummyMessage, goog.nullFunction);
@ -69,40 +70,82 @@ describe('binaryWriterTest', function() {
// Writing invalid field indices should assert.
writer = new jspb.BinaryWriter();
assertFails(function() {writer.writeUint64(-1, 1);});
assertFails(function() {
writer.writeUint64(-1, 1);
});
// Writing out-of-range field values should assert.
writer = new jspb.BinaryWriter();
assertFails(function() {writer.writeInt32(1, -Infinity);});
assertFails(function() {writer.writeInt32(1, Infinity);});
assertFails(function() {
writer.writeInt32(1, -Infinity);
});
assertFails(function() {
writer.writeInt32(1, Infinity);
});
assertFails(function() {writer.writeInt64(1, -Infinity);});
assertFails(function() {writer.writeInt64(1, Infinity);});
assertFails(function() {
writer.writeInt64(1, -Infinity);
});
assertFails(function() {
writer.writeInt64(1, Infinity);
});
assertFails(function() {writer.writeUint32(1, -1);});
assertFails(function() {writer.writeUint32(1, Infinity);});
assertFails(function() {
writer.writeUint32(1, -1);
});
assertFails(function() {
writer.writeUint32(1, Infinity);
});
assertFails(function() {writer.writeUint64(1, -1);});
assertFails(function() {writer.writeUint64(1, Infinity);});
assertFails(function() {
writer.writeUint64(1, -1);
});
assertFails(function() {
writer.writeUint64(1, Infinity);
});
assertFails(function() {writer.writeSint32(1, -Infinity);});
assertFails(function() {writer.writeSint32(1, Infinity);});
assertFails(function() {
writer.writeSint32(1, -Infinity);
});
assertFails(function() {
writer.writeSint32(1, Infinity);
});
assertFails(function() {writer.writeSint64(1, -Infinity);});
assertFails(function() {writer.writeSint64(1, Infinity);});
assertFails(function() {
writer.writeSint64(1, -Infinity);
});
assertFails(function() {
writer.writeSint64(1, Infinity);
});
assertFails(function() {writer.writeFixed32(1, -1);});
assertFails(function() {writer.writeFixed32(1, Infinity);});
assertFails(function() {
writer.writeFixed32(1, -1);
});
assertFails(function() {
writer.writeFixed32(1, Infinity);
});
assertFails(function() {writer.writeFixed64(1, -1);});
assertFails(function() {writer.writeFixed64(1, Infinity);});
assertFails(function() {
writer.writeFixed64(1, -1);
});
assertFails(function() {
writer.writeFixed64(1, Infinity);
});
assertFails(function() {writer.writeSfixed32(1, -Infinity);});
assertFails(function() {writer.writeSfixed32(1, Infinity);});
assertFails(function() {
writer.writeSfixed32(1, -Infinity);
});
assertFails(function() {
writer.writeSfixed32(1, Infinity);
});
assertFails(function() {writer.writeSfixed64(1, -Infinity);});
assertFails(function() {writer.writeSfixed64(1, Infinity);});
assertFails(function() {
writer.writeSfixed64(1, -Infinity);
});
assertFails(function() {
writer.writeSfixed64(1, Infinity);
});
});

@ -46,7 +46,7 @@ goog.require('jspb.BinaryConstants');
goog.require('jspb.BinaryDecoder');
goog.require('jspb.BinaryReader');
goog.require('jspb.BinaryWriter');
goog.requireType('jspb.BinaryMessage');
describe('binaryReaderTest', function() {
@ -55,7 +55,7 @@ describe('binaryReaderTest', function() {
*/
it('testInstanceCaches', /** @suppress {visibility} */ function() {
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
writer.writeMessage(1, dummyMessage, goog.nullFunction);
writer.writeMessage(2, dummyMessage, goog.nullFunction);
@ -135,7 +135,7 @@ describe('binaryReaderTest', function() {
// Calling readMessage on a non-delimited field should trigger an
// assertion.
var reader = jspb.BinaryReader.alloc([8, 1]);
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
reader.nextField();
assertThrows(function() {
reader.readMessage(dummyMessage, goog.nullFunction);
@ -144,47 +144,91 @@ describe('binaryReaderTest', function() {
// Reading past the end of the stream should trigger an assertion.
reader = jspb.BinaryReader.alloc([9, 1]);
reader.nextField();
assertThrows(function() {reader.readFixed64()});
assertThrows(function() {
reader.readFixed64()
});
// Reading past the end of a submessage should trigger an assertion.
reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
reader.nextField();
reader.readMessage(dummyMessage, function() {
reader.nextField();
assertThrows(function() {reader.readFixed32()});
assertThrows(function() {
reader.readFixed32()
});
});
// Skipping an invalid field should trigger an assertion.
reader = jspb.BinaryReader.alloc([12, 1]);
reader.nextWireType_ = 1000;
assertThrows(function() {reader.skipField()});
assertThrows(function() {
reader.skipField()
});
// Reading fields with the wrong wire type should assert.
reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
reader.nextField();
assertThrows(function() {reader.readInt32()});
assertThrows(function() {reader.readInt32String()});
assertThrows(function() {reader.readInt64()});
assertThrows(function() {reader.readInt64String()});
assertThrows(function() {reader.readUint32()});
assertThrows(function() {reader.readUint32String()});
assertThrows(function() {reader.readUint64()});
assertThrows(function() {reader.readUint64String()});
assertThrows(function() {reader.readSint32()});
assertThrows(function() {reader.readBool()});
assertThrows(function() {reader.readEnum()});
assertThrows(function() {
reader.readInt32()
});
assertThrows(function() {
reader.readInt32String()
});
assertThrows(function() {
reader.readInt64()
});
assertThrows(function() {
reader.readInt64String()
});
assertThrows(function() {
reader.readUint32()
});
assertThrows(function() {
reader.readUint32String()
});
assertThrows(function() {
reader.readUint64()
});
assertThrows(function() {
reader.readUint64String()
});
assertThrows(function() {
reader.readSint32()
});
assertThrows(function() {
reader.readBool()
});
assertThrows(function() {
reader.readEnum()
});
reader = jspb.BinaryReader.alloc([8, 1]);
reader.nextField();
assertThrows(function() {reader.readFixed32()});
assertThrows(function() {reader.readFixed64()});
assertThrows(function() {reader.readSfixed32()});
assertThrows(function() {reader.readSfixed64()});
assertThrows(function() {reader.readFloat()});
assertThrows(function() {reader.readDouble()});
assertThrows(function() {
reader.readFixed32()
});
assertThrows(function() {
reader.readFixed64()
});
assertThrows(function() {
reader.readSfixed32()
});
assertThrows(function() {
reader.readSfixed64()
});
assertThrows(function() {
reader.readFloat()
});
assertThrows(function() {
reader.readDouble()
});
assertThrows(function() {reader.readString()});
assertThrows(function() {reader.readBytes()});
assertThrows(function() {
reader.readString()
});
assertThrows(function() {
reader.readBytes()
});
});
@ -198,8 +242,8 @@ describe('binaryReaderTest', function() {
* @private
* @suppress {missingProperties}
*/
var doTestUnsignedField_ = function(readField,
writeField, epsilon, upperLimit, filter) {
var doTestUnsignedField_ = function(
readField, writeField, epsilon, upperLimit, filter) {
assertNotNull(readField);
assertNotNull(writeField);
@ -250,8 +294,8 @@ describe('binaryReaderTest', function() {
* @private
* @suppress {missingProperties}
*/
var doTestSignedField_ = function(readField,
writeField, epsilon, lowerLimit, upperLimit, filter) {
var doTestSignedField_ = function(
readField, writeField, epsilon, lowerLimit, upperLimit, filter) {
var writer = new jspb.BinaryWriter();
// Encode zero and limits.
@ -267,20 +311,14 @@ describe('binaryReaderTest', function() {
for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
var val = filter(cursor);
writeField.call(writer, 6, val);
inputValues.push({
fieldNumber: 6,
value: val
});
inputValues.push({fieldNumber: 6, value: val});
}
// Encode positive values.
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
var val = filter(cursor);
writeField.call(writer, 7, val);
inputValues.push({
fieldNumber: 7,
value: val
});
inputValues.push({fieldNumber: 7, value: val});
}
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
@ -327,33 +365,34 @@ describe('binaryReaderTest', function() {
assertNotUndefined(jspb.BinaryWriter.prototype.writeBool);
doTestUnsignedField_(
jspb.BinaryReader.prototype.readUint32,
jspb.BinaryWriter.prototype.writeUint32,
1, Math.pow(2, 32) - 1, Math.round);
jspb.BinaryWriter.prototype.writeUint32, 1, Math.pow(2, 32) - 1,
Math.round);
doTestUnsignedField_(
jspb.BinaryReader.prototype.readUint64,
jspb.BinaryWriter.prototype.writeUint64,
1, Math.pow(2, 64) - 1025, Math.round);
jspb.BinaryWriter.prototype.writeUint64, 1, Math.pow(2, 64) - 1025,
Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readInt32,
jspb.BinaryWriter.prototype.writeInt32,
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
jspb.BinaryWriter.prototype.writeInt32, 1, -Math.pow(2, 31),
Math.pow(2, 31) - 1, Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readInt64,
jspb.BinaryWriter.prototype.writeInt64,
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
jspb.BinaryWriter.prototype.writeInt64, 1, -Math.pow(2, 63),
Math.pow(2, 63) - 513, Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readEnum,
jspb.BinaryWriter.prototype.writeEnum,
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
jspb.BinaryWriter.prototype.writeEnum, 1, -Math.pow(2, 31),
Math.pow(2, 31) - 1, Math.round);
doTestUnsignedField_(
jspb.BinaryReader.prototype.readBool,
jspb.BinaryWriter.prototype.writeBool,
1, 1, function(x) { return !!x; });
jspb.BinaryWriter.prototype.writeBool, 1, 1, function(x) {
return !!x;
});
});
@ -387,24 +426,22 @@ describe('binaryReaderTest', function() {
// uint32 and sint32 take no more than 5 bytes
// 08 - field prefix (type = 0 means varint)
doTestHexStringVarint_(
jspb.BinaryReader.prototype.readUint32,
12, '08 8C 80 80 80 00');
jspb.BinaryReader.prototype.readUint32, 12, '08 8C 80 80 80 00');
// 11 stands for -6 in zigzag encoding
doTestHexStringVarint_(
jspb.BinaryReader.prototype.readSint32,
-6, '08 8B 80 80 80 00');
jspb.BinaryReader.prototype.readSint32, -6, '08 8B 80 80 80 00');
// uint64 and sint64 take no more than 10 bytes
// 08 - field prefix (type = 0 means varint)
doTestHexStringVarint_(
jspb.BinaryReader.prototype.readUint64,
12, '08 8C 80 80 80 80 80 80 80 80 00');
jspb.BinaryReader.prototype.readUint64, 12,
'08 8C 80 80 80 80 80 80 80 80 00');
// 11 stands for -6 in zigzag encoding
doTestHexStringVarint_(
jspb.BinaryReader.prototype.readSint64,
-6, '08 8B 80 80 80 80 80 80 80 80 00');
jspb.BinaryReader.prototype.readSint64, -6,
'08 8B 80 80 80 80 80 80 80 80 00');
});
@ -415,27 +452,15 @@ describe('binaryReaderTest', function() {
var writer = new jspb.BinaryWriter();
var testSignedData = [
'2730538252207801776',
'-2688470994844604560',
'3398529779486536359',
'3568577411627971000',
'272477188847484900',
'-6649058714086158188',
'-7695254765712060806',
'-4525541438037104029',
'-4993706538836508568',
'2730538252207801776', '-2688470994844604560', '3398529779486536359',
'3568577411627971000', '272477188847484900', '-6649058714086158188',
'-7695254765712060806', '-4525541438037104029', '-4993706538836508568',
'4990160321893729138'
];
var testUnsignedData = [
'7822732630241694882',
'6753602971916687352',
'2399935075244442116',
'8724292567325338867',
'16948784802625696584',
'4136275908516066934',
'3575388346793700364',
'5167142028379259461',
'1557573948689737699',
'7822732630241694882', '6753602971916687352', '2399935075244442116',
'8724292567325338867', '16948784802625696584', '4136275908516066934',
'3575388346793700364', '5167142028379259461', '1557573948689737699',
'17100725280812548567'
];
@ -463,13 +488,13 @@ describe('binaryReaderTest', function() {
it('testZigzagFields', function() {
doTestSignedField_(
jspb.BinaryReader.prototype.readSint32,
jspb.BinaryWriter.prototype.writeSint32,
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
jspb.BinaryWriter.prototype.writeSint32, 1, -Math.pow(2, 31),
Math.pow(2, 31) - 1, Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readSint64,
jspb.BinaryWriter.prototype.writeSint64,
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
jspb.BinaryWriter.prototype.writeSint64, 1, -Math.pow(2, 63),
Math.pow(2, 63) - 513, Math.round);
});
@ -479,23 +504,23 @@ describe('binaryReaderTest', function() {
it('testFixedFields', function() {
doTestUnsignedField_(
jspb.BinaryReader.prototype.readFixed32,
jspb.BinaryWriter.prototype.writeFixed32,
1, Math.pow(2, 32) - 1, Math.round);
jspb.BinaryWriter.prototype.writeFixed32, 1, Math.pow(2, 32) - 1,
Math.round);
doTestUnsignedField_(
jspb.BinaryReader.prototype.readFixed64,
jspb.BinaryWriter.prototype.writeFixed64,
1, Math.pow(2, 64) - 1025, Math.round);
jspb.BinaryWriter.prototype.writeFixed64, 1, Math.pow(2, 64) - 1025,
Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readSfixed32,
jspb.BinaryWriter.prototype.writeSfixed32,
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
jspb.BinaryWriter.prototype.writeSfixed32, 1, -Math.pow(2, 31),
Math.pow(2, 31) - 1, Math.round);
doTestSignedField_(
jspb.BinaryReader.prototype.readSfixed64,
jspb.BinaryWriter.prototype.writeSfixed64,
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
jspb.BinaryWriter.prototype.writeSfixed64, 1, -Math.pow(2, 63),
Math.pow(2, 63) - 513, Math.round);
});
@ -506,18 +531,17 @@ describe('binaryReaderTest', function() {
doTestSignedField_(
jspb.BinaryReader.prototype.readFloat,
jspb.BinaryWriter.prototype.writeFloat,
jspb.BinaryConstants.FLOAT32_MIN,
-jspb.BinaryConstants.FLOAT32_MAX,
jspb.BinaryConstants.FLOAT32_MAX,
truncate);
jspb.BinaryConstants.FLOAT32_MIN, -jspb.BinaryConstants.FLOAT32_MAX,
jspb.BinaryConstants.FLOAT32_MAX, truncate);
doTestSignedField_(
jspb.BinaryReader.prototype.readDouble,
jspb.BinaryWriter.prototype.writeDouble,
jspb.BinaryConstants.FLOAT64_EPS * 10,
-jspb.BinaryConstants.FLOAT64_MIN,
jspb.BinaryConstants.FLOAT64_MIN,
function(x) { return x; });
-jspb.BinaryConstants.FLOAT64_MIN, jspb.BinaryConstants.FLOAT64_MIN,
function(x) {
return x;
});
});
@ -584,7 +608,7 @@ describe('binaryReaderTest', function() {
*/
it('testNesting', function() {
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
writer.writeInt32(1, 100);
@ -677,7 +701,7 @@ describe('binaryReaderTest', function() {
// Write a group with a nested group inside.
writer.writeInt32(5, sentinel);
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
writer.writeGroup(5, dummyMessage, function() {
writer.writeInt64(42, 42);
writer.writeGroup(6, dummyMessage, function() {
@ -830,7 +854,7 @@ describe('binaryReaderTest', function() {
var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
var blob = [1, 2, 3, 4, 5];
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
writer.writeMessage(1, dummyMessage, function() {
writer.writeMessage(1, dummyMessage, function() {
@ -863,7 +887,7 @@ describe('binaryReaderTest', function() {
*/
it('testReadCallbacks', function() {
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
// Add an int, a submessage, and another int.
writer.writeInt32(1, 100);

@ -41,14 +41,14 @@
goog.require('goog.crypt');
goog.require('goog.testing.asserts');
goog.require('jspb.BinaryWriter');
goog.requireType('jspb.BinaryMessage');
/**
* @param {function()} func This function should throw an error when run.
*/
function assertFails(func) {
var e = assertThrows(func);
//assertNotNull(e.toString().match(/Error/));
// assertNotNull(e.toString().match(/Error/));
}
@ -59,7 +59,7 @@ describe('binaryWriterTest', function() {
it('testWriteErrors', function() {
// Submessages with invalid field indices should assert.
var writer = new jspb.BinaryWriter();
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
assertFails(function() {
writer.writeMessage(-1, dummyMessage, goog.nullFunction);
@ -67,40 +67,82 @@ describe('binaryWriterTest', function() {
// Writing invalid field indices should assert.
writer = new jspb.BinaryWriter();
assertFails(function() {writer.writeUint64(-1, 1);});
assertFails(function() {
writer.writeUint64(-1, 1);
});
// Writing out-of-range field values should assert.
writer = new jspb.BinaryWriter();
assertFails(function() {writer.writeInt32(1, -Infinity);});
assertFails(function() {writer.writeInt32(1, Infinity);});
assertFails(function() {
writer.writeInt32(1, -Infinity);
});
assertFails(function() {
writer.writeInt32(1, Infinity);
});
assertFails(function() {writer.writeInt64(1, -Infinity);});
assertFails(function() {writer.writeInt64(1, Infinity);});
assertFails(function() {
writer.writeInt64(1, -Infinity);
});
assertFails(function() {
writer.writeInt64(1, Infinity);
});
assertFails(function() {writer.writeUint32(1, -1);});
assertFails(function() {writer.writeUint32(1, Infinity);});
assertFails(function() {
writer.writeUint32(1, -1);
});
assertFails(function() {
writer.writeUint32(1, Infinity);
});
assertFails(function() {writer.writeUint64(1, -1);});
assertFails(function() {writer.writeUint64(1, Infinity);});
assertFails(function() {
writer.writeUint64(1, -1);
});
assertFails(function() {
writer.writeUint64(1, Infinity);
});
assertFails(function() {writer.writeSint32(1, -Infinity);});
assertFails(function() {writer.writeSint32(1, Infinity);});
assertFails(function() {
writer.writeSint32(1, -Infinity);
});
assertFails(function() {
writer.writeSint32(1, Infinity);
});
assertFails(function() {writer.writeSint64(1, -Infinity);});
assertFails(function() {writer.writeSint64(1, Infinity);});
assertFails(function() {
writer.writeSint64(1, -Infinity);
});
assertFails(function() {
writer.writeSint64(1, Infinity);
});
assertFails(function() {writer.writeFixed32(1, -1);});
assertFails(function() {writer.writeFixed32(1, Infinity);});
assertFails(function() {
writer.writeFixed32(1, -1);
});
assertFails(function() {
writer.writeFixed32(1, Infinity);
});
assertFails(function() {writer.writeFixed64(1, -1);});
assertFails(function() {writer.writeFixed64(1, Infinity);});
assertFails(function() {
writer.writeFixed64(1, -1);
});
assertFails(function() {
writer.writeFixed64(1, Infinity);
});
assertFails(function() {writer.writeSfixed32(1, -Infinity);});
assertFails(function() {writer.writeSfixed32(1, Infinity);});
assertFails(function() {
writer.writeSfixed32(1, -Infinity);
});
assertFails(function() {
writer.writeSfixed32(1, Infinity);
});
assertFails(function() {writer.writeSfixed64(1, -Infinity);});
assertFails(function() {writer.writeSfixed64(1, Infinity);});
assertFails(function() {
writer.writeSfixed64(1, -Infinity);
});
assertFails(function() {
writer.writeSfixed64(1, Infinity);
});
});

@ -40,6 +40,8 @@ goog.require('proto.jspb.test.TestMapFields');
goog.require('proto.jspb.test.MapValueMessageNoBinary');
goog.require('proto.jspb.test.TestMapFieldsNoBinary');
goog.requireType('jspb.Map');
/**
* Helper: check that the given map has exactly this set of (sorted) entries.
* @param {!jspb.Map} map
@ -98,7 +100,9 @@ function makeTests(msgInfo, submessageCtor, suffix) {
msg.getMapStringMsgMap().get('k').setFoo(42);
msg.getMapStringMsgMap().get('l').setFoo(84);
msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b');
msg.getMapInt64StringMap().set(0x123456789abc, 'c').set(0xcba987654321, 'd');
msg.getMapInt64StringMap()
.set(0x123456789abc, 'c')
.set(0xcba987654321, 'd');
msg.getMapBoolStringMap().set(false, 'e').set(true, 'f');
};
@ -107,42 +111,24 @@ function makeTests(msgInfo, submessageCtor, suffix) {
* @param {?} msg
*/
var checkMapFields = function(msg) {
checkMapEquals(msg.getMapStringStringMap(), [
['asdf', 'jkl;'],
['key 2', 'hello world']
]);
checkMapEquals(msg.getMapStringInt32Map(), [
['a', 1],
['b', -2]
]);
checkMapEquals(msg.getMapStringInt64Map(), [
['c', 0x100000000],
['d', 0x200000000]
]);
checkMapEquals(msg.getMapStringBoolMap(), [
['e', true],
['f', false]
]);
checkMapEquals(msg.getMapStringDoubleMap(), [
['g', 3.14159],
['h', 2.71828]
]);
checkMapEquals(
msg.getMapStringStringMap(),
[['asdf', 'jkl;'], ['key 2', 'hello world']]);
checkMapEquals(msg.getMapStringInt32Map(), [['a', 1], ['b', -2]]);
checkMapEquals(
msg.getMapStringInt64Map(), [['c', 0x100000000], ['d', 0x200000000]]);
checkMapEquals(msg.getMapStringBoolMap(), [['e', true], ['f', false]]);
checkMapEquals(
msg.getMapStringDoubleMap(), [['g', 3.14159], ['h', 2.71828]]);
checkMapEquals(msg.getMapStringEnumMap(), [
['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
]);
checkMapEquals(msg.getMapInt32StringMap(), [
[-1, 'a'],
[42, 'b']
]);
checkMapEquals(msg.getMapInt64StringMap(), [
[0x123456789abc, 'c'],
[0xcba987654321, 'd']
]);
checkMapEquals(msg.getMapBoolStringMap(), [
[false, 'e'],
[true, 'f']
['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
]);
checkMapEquals(msg.getMapInt32StringMap(), [[-1, 'a'], [42, 'b']]);
checkMapEquals(
msg.getMapInt64StringMap(),
[[0x123456789abc, 'c'], [0xcba987654321, 'd']]);
checkMapEquals(msg.getMapBoolStringMap(), [[false, 'e'], [true, 'f']]);
assertEquals(msg.getMapStringMsgMap().getLength(), 2);
assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42);
@ -187,10 +173,7 @@ function makeTests(msgInfo, submessageCtor, suffix) {
assertElementsEquals(it.next().value, ['asdf', 'hello world']);
assertElementsEquals(it.next().value, ['jkl;', 'key 2']);
assertEquals(it.next().done, true);
checkMapEquals(m, [
['asdf', 'hello world'],
['jkl;', 'key 2']
]);
checkMapEquals(m, [['asdf', 'hello world'], ['jkl;', 'key 2']]);
m.del('jkl;');
assertEquals(m.has('jkl;'), false);
assertEquals(m.get('jkl;'), undefined);
@ -242,11 +225,11 @@ function makeTests(msgInfo, submessageCtor, suffix) {
msg.getMapStringStringMap().set('A', 'a');
var serialized = msg.serializeBinary();
var expectedSerialized = [
0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
0x41, // ASCII 'A'
0x12, 0x1, // field 2 in submessage (value), delimited, length 1
0x61 // ASCII 'a'
0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
0x41, // ASCII 'A'
0x12, 0x1, // field 2 in submessage (value), delimited, length 1
0x61 // ASCII 'a'
];
assertEquals(serialized.length, expectedSerialized.length);
for (var i = 0; i < serialized.length; i++) {
@ -267,11 +250,7 @@ function makeTests(msgInfo, submessageCtor, suffix) {
*/
it('testLazyMapSync' + suffix, function() {
// Start with a JSPB array containing a few map entries.
var entries = [
['a', 'entry 1'],
['c', 'entry 2'],
['b', 'entry 3']
];
var entries = [['a', 'entry 1'], ['c', 'entry 2'], ['b', 'entry 3']];
var msg = new msgInfo.constructor([entries]);
assertEquals(entries.length, 3);
assertEquals(entries[0][0], 'a');
@ -279,9 +258,9 @@ function makeTests(msgInfo, submessageCtor, suffix) {
assertEquals(entries[2][0], 'b');
msg.getMapStringStringMap().del('a');
assertEquals(entries.length, 3); // not yet sync'd
msg.toArray(); // force a sync
msg.toArray(); // force a sync
assertEquals(entries.length, 2);
assertEquals(entries[0][0], 'b'); // now in sorted order
assertEquals(entries[0][0], 'b'); // now in sorted order
assertEquals(entries[1][0], 'c');
var a = msg.toArray();
@ -290,12 +269,16 @@ function makeTests(msgInfo, submessageCtor, suffix) {
}
describe('mapsTest', function() {
makeTests({
constructor: proto.jspb.test.TestMapFields,
deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary
}, proto.jspb.test.MapValueMessage, "_Binary");
makeTests({
constructor: proto.jspb.test.TestMapFieldsNoBinary,
deserializeBinary: null
}, proto.jspb.test.MapValueMessageNoBinary, "_NoBinary");
makeTests(
{
constructor: proto.jspb.test.TestMapFields,
deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary
},
proto.jspb.test.MapValueMessage, '_Binary');
makeTests(
{
constructor: proto.jspb.test.TestMapFieldsNoBinary,
deserializeBinary: null
},
proto.jspb.test.MapValueMessageNoBinary, '_NoBinary');
});

@ -67,7 +67,6 @@ goog.require('proto.jspb.test.Simple1');
goog.require('proto.jspb.test.Simple2');
goog.require('proto.jspb.test.SpecialCases');
goog.require('proto.jspb.test.TestClone');
goog.require('proto.jspb.test.TestEndsWithBytes');
goog.require('proto.jspb.test.TestGroup');
goog.require('proto.jspb.test.TestGroup1');
goog.require('proto.jspb.test.TestMessageWithOneof');
@ -77,7 +76,7 @@ goog.require('proto.jspb.test.TestReservedNamesExtension');
// CommonJS-LoadFromFile: test2_pb proto.jspb.test
goog.require('proto.jspb.test.ExtensionMessage');
goog.require('proto.jspb.test.TestExtensionsMessage');
goog.require('proto.jspb.test.simple1');
@ -102,59 +101,59 @@ describe('Message test suite', function() {
});
it('testComplexConversion', function() {
var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, true];
var data2 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, true];
var data1 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , true];
var data2 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , true];
var foo = new proto.jspb.test.Complex(data1);
var bar = new proto.jspb.test.Complex(data2);
var result = foo.toObject();
assertObjectEquals({
aString: 'a',
anOutOfOrderBool: true,
aNestedMessage: {
anInt: 11
},
aRepeatedMessageList: [{anInt: 22}, {anInt: 33}],
aRepeatedStringList: ['s1', 's2']
}, result);
assertObjectEquals(
{
aString: 'a',
anOutOfOrderBool: true,
aNestedMessage: {anInt: 11},
aRepeatedMessageList: [{anInt: 22}, {anInt: 33}],
aRepeatedStringList: ['s1', 's2']
},
result);
// Now test with the jspb instances included.
result = foo.toObject(true /* opt_includeInstance */);
assertObjectEquals({
aString: 'a',
anOutOfOrderBool: true,
aNestedMessage: {
anInt: 11,
$jspbMessageInstance: foo.getANestedMessage()
},
aRepeatedMessageList: [
{anInt: 22, $jspbMessageInstance: foo.getARepeatedMessageList()[0]},
{anInt: 33, $jspbMessageInstance: foo.getARepeatedMessageList()[1]}
],
aRepeatedStringList: ['s1', 's2'],
$jspbMessageInstance: foo
}, result);
assertObjectEquals(
{
aString: 'a',
anOutOfOrderBool: true,
aNestedMessage:
{anInt: 11, $jspbMessageInstance: foo.getANestedMessage()},
aRepeatedMessageList: [
{anInt: 22, $jspbMessageInstance: foo.getARepeatedMessageList()[0]},
{anInt: 33, $jspbMessageInstance: foo.getARepeatedMessageList()[1]}
],
aRepeatedStringList: ['s1', 's2'],
$jspbMessageInstance: foo
},
result);
});
it('testMissingFields', function() {
var foo = new proto.jspb.test.Complex([
undefined, undefined, undefined, [],
undefined, undefined, undefined, undefined]);
undefined, undefined, undefined, [], undefined, undefined, undefined,
undefined
]);
var bar = new proto.jspb.test.Complex([
undefined, undefined, undefined, [],
undefined, undefined, undefined, undefined]);
undefined, undefined, undefined, [], undefined, undefined, undefined,
undefined
]);
var result = foo.toObject();
assertObjectEquals({
aString: undefined,
anOutOfOrderBool: undefined,
aNestedMessage: {
anInt: undefined
},
// Note: JsPb converts undefined repeated fields to empty arrays.
aRepeatedMessageList: [],
aRepeatedStringList: []
}, result);
assertObjectEquals(
{
aString: undefined,
anOutOfOrderBool: undefined,
aNestedMessage: {anInt: undefined},
// Note: JsPb converts undefined repeated fields to empty arrays.
aRepeatedMessageList: [],
aRepeatedStringList: []
},
result);
});
it('testNestedComplexMessage', function() {
@ -167,20 +166,21 @@ describe('Message test suite', function() {
it('testSpecialCases', function() {
// Note: Some property names are reserved in JavaScript.
// These names are converted to the Js property named pb_<reserved_name>.
var special =
new proto.jspb.test.SpecialCases(['normal', 'default', 'function',
'var']);
var special = new proto.jspb.test.SpecialCases(
['normal', 'default', 'function', 'var']);
var result = special.toObject();
assertObjectEquals({
normal: 'normal',
pb_default: 'default',
pb_function: 'function',
pb_var: 'var'
}, result);
assertObjectEquals(
{
normal: 'normal',
pb_default: 'default',
pb_function: 'function',
pb_var: 'var'
},
result);
});
it('testDefaultValues', function() {
var defaultString = "default<>\'\"abc";
var defaultString = 'default<>\'"abc';
var response = new proto.jspb.test.DefaultValues();
// Test toObject
@ -244,8 +244,10 @@ describe('Message test suite', function() {
// Test that clearing the values reverts them to the default state.
response = makeDefault(['blah', false, 111, 77]);
response.clearStringField(); response.clearBoolField();
response.clearIntField(); response.clearEnumField();
response.clearStringField();
response.clearBoolField();
response.clearIntField();
response.clearEnumField();
assertEquals(defaultString, response.getStringField());
assertEquals(true, response.getBoolField());
assertEquals(11, response.getIntField());
@ -257,8 +259,10 @@ describe('Message test suite', function() {
// Test that setFoo(null) clears the values.
response = makeDefault(['blah', false, 111, 77]);
response.setStringField(null); response.setBoolField(null);
response.setIntField(undefined); response.setEnumField(undefined);
response.setStringField(null);
response.setBoolField(null);
response.setIntField(undefined);
response.setEnumField(undefined);
assertEquals(defaultString, response.getStringField());
assertEquals(true, response.getBoolField());
assertEquals(11, response.getIntField());
@ -288,15 +292,15 @@ describe('Message test suite', function() {
// but we actually get a sparse array instead. We could use something
// like [1,undefined,2] to avoid this, except that this is still
// sparse on IE. No comment...
var expected = [,,, [], []];
var expected = [, , , [], []];
expected[0] = expected[1] = expected[2] = undefined;
assertObjectEquals(expected, foo.toArray());
});
it('testDifferenceRawObject', /** @suppress {visibility} */ function() {
var p1 = new proto.jspb.test.HasExtensions(['hi', 'diff', {}]);
var p2 = new proto.jspb.test.HasExtensions(['hi', 'what',
{1000: 'unique'}]);
var p2 =
new proto.jspb.test.HasExtensions(['hi', 'what', {1000: 'unique'}]);
var diff = /** @type {proto.jspb.test.HasExtensions} */
(jspb.Message.difference(p1, p2));
assertEquals('', diff.getStr1());
@ -310,13 +314,13 @@ describe('Message test suite', function() {
assertTrue(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi'])));
assertFalse(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['bye'])));
var s1b = new proto.jspb.test.Simple1(['hi', ['hello']]);
assertTrue(jspb.Message.equals(s1b,
new proto.jspb.test.Simple1(['hi', ['hello']])));
assertTrue(jspb.Message.equals(s1b,
new proto.jspb.test.Simple1(['hi', ['hello', undefined,
undefined, undefined]])));
assertFalse(jspb.Message.equals(s1b,
new proto.jspb.test.Simple1(['no', ['hello']])));
assertTrue(jspb.Message.equals(
s1b, new proto.jspb.test.Simple1(['hi', ['hello']])));
assertTrue(jspb.Message.equals(s1b, new proto.jspb.test.Simple1([
'hi', ['hello', undefined, undefined, undefined]
])));
assertFalse(jspb.Message.equals(
s1b, new proto.jspb.test.Simple1(['no', ['hello']])));
// Test with messages of different types
var s2 = new proto.jspb.test.Simple2(['hi']);
assertFalse(jspb.Message.equals(s1, s2));
@ -324,18 +328,18 @@ describe('Message test suite', function() {
it('testEquals_softComparison', function() {
var s1 = new proto.jspb.test.Simple1(['hi', [], null]);
assertTrue(jspb.Message.equals(s1,
new proto.jspb.test.Simple1(['hi', []])));
assertTrue(
jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi', []])));
var s1b = new proto.jspb.test.Simple1(['hi', [], true]);
assertTrue(jspb.Message.equals(s1b,
new proto.jspb.test.Simple1(['hi', [], 1])));
assertTrue(
jspb.Message.equals(s1b, new proto.jspb.test.Simple1(['hi', [], 1])));
});
it('testEqualsComplex', function() {
var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
var data2 = ['a',,, [, 11], [[, 22], [, 34]],, ['s1', 's2'],, 1];
var data3 = ['a',,, [, 11], [[, 22]],, ['s1', 's2'],, 1];
var data1 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , 1];
var data2 = ['a', , , [, 11], [[, 22], [, 34]], , ['s1', 's2'], , 1];
var data3 = ['a', , , [, 11], [[, 22]], , ['s1', 's2'], , 1];
var data4 = ['hi'];
var c1a = new proto.jspb.test.Complex(data1);
var c1b = new proto.jspb.test.Complex(data1);
@ -352,42 +356,34 @@ describe('Message test suite', function() {
it('testEqualsExtensionsConstructed', function() {
assertTrue(jspb.Message.equals(
new proto.jspb.test.HasExtensions([]),
new proto.jspb.test.HasExtensions([{}])
));
new proto.jspb.test.HasExtensions([{}])));
assertTrue(jspb.Message.equals(
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
));
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])));
assertFalse(jspb.Message.equals(
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}])
));
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}])));
assertTrue(jspb.Message.equals(
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
));
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])));
assertTrue(jspb.Message.equals(
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}])
));
new proto.jspb.test.HasExtensions([, , , {100: [{200: 'a'}]}])));
assertTrue(jspb.Message.equals(
new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}]),
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
));
new proto.jspb.test.HasExtensions([, , , {100: [{200: 'a'}]}]),
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])));
assertTrue(jspb.Message.equals(
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}])
));
new proto.jspb.test.HasExtensions(['hi', , , {100: [{200: 'a'}]}])));
assertTrue(jspb.Message.equals(
new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}]),
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
));
new proto.jspb.test.HasExtensions(['hi', , , {100: [{200: 'a'}]}]),
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])));
});
it('testEqualsExtensionsUnconstructed', function() {
assertTrue(jspb.Message.compareFields([], [{}]));
assertTrue(jspb.Message.compareFields([,,, {}], []));
assertTrue(jspb.Message.compareFields([,,, {}], [,, {}]));
assertTrue(jspb.Message.compareFields([, , , {}], []));
assertTrue(jspb.Message.compareFields([, , , {}], [, , {}]));
assertTrue(jspb.Message.compareFields(
['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
assertFalse(jspb.Message.compareFields(
@ -395,25 +391,25 @@ describe('Message test suite', function() {
assertTrue(jspb.Message.compareFields(
[{100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
assertTrue(jspb.Message.compareFields(
[{100: [{200: 'a'}]}], [,,, {100: [{200: 'a'}]}]));
[{100: [{200: 'a'}]}], [, , , {100: [{200: 'a'}]}]));
assertTrue(jspb.Message.compareFields(
[,,, {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
[, , , {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
assertTrue(jspb.Message.compareFields(
['hi', {100: [{200: 'a'}]}], ['hi',,, {100: [{200: 'a'}]}]));
['hi', {100: [{200: 'a'}]}], ['hi', , , {100: [{200: 'a'}]}]));
assertTrue(jspb.Message.compareFields(
['hi',,, {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
['hi', , , {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
});
it('testToMap', function() {
var p1 = new proto.jspb.test.Simple1(['k', ['v']]);
var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]);
var soymap = jspb.Message.toMap([p1, p2],
proto.jspb.test.Simple1.prototype.getAString,
var soymap = jspb.Message.toMap(
[p1, p2], proto.jspb.test.Simple1.prototype.getAString,
proto.jspb.test.Simple1.prototype.toObject);
assertEquals('k', soymap['k'].aString);
assertArrayEquals(['v'], soymap['k'].aRepeatedStringList);
var protomap = jspb.Message.toMap([p1, p2],
proto.jspb.test.Simple1.prototype.getAString);
var protomap = jspb.Message.toMap(
[p1, p2], proto.jspb.test.Simple1.prototype.getAString);
assertEquals('k', protomap['k'].getAString());
assertArrayEquals(['v'], protomap['k'].getARepeatedStringList());
});
@ -434,8 +430,12 @@ describe('Message test suite', function() {
extension.setExt('e1');
original.setExtension(proto.jspb.test.IsExtension.extField, extension);
var clone = original.clone();
assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
[['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }],
assertArrayEquals(
[
'v1', , ['x1', ['y1', 'z1']], ,
[['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1, ,
{100: [, 'e1']}
],
clone.toArray());
clone.setStr('v2');
var simple4 = new proto.jspb.test.Simple1(['a1', ['b1', 'c1']]);
@ -452,11 +452,19 @@ describe('Message test suite', function() {
var newExtension = new proto.jspb.test.CloneExtension();
newExtension.setExt('e2');
clone.setExtension(proto.jspb.test.CloneExtension.extField, newExtension);
assertArrayEquals(['v2',, ['a1', ['b1', 'c1']],,
[['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]], bytes2,, { 100: [, 'e2'] }],
assertArrayEquals(
[
'v2', , ['a1', ['b1', 'c1']], ,
[['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]], bytes2, ,
{100: [, 'e2']}
],
clone.toArray());
assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
[['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }],
assertArrayEquals(
[
'v1', , ['x1', ['y1', 'z1']], ,
[['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1, ,
{100: [, 'e1']}
],
original.toArray());
});
@ -488,11 +496,12 @@ describe('Message test suite', function() {
jspb.Message.copyInto(original, dest);
assertArrayEquals(original.toArray(), dest.toArray());
assertEquals('x1', dest.getSimple1().getAString());
assertEquals('e1',
assertEquals(
'e1',
dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt());
dest.getSimple1().setAString('new value');
assertNotEquals(dest.getSimple1().getAString(),
original.getSimple1().getAString());
assertNotEquals(
dest.getSimple1().getAString(), original.getSimple1().getAString());
if (supportsUint8Array) {
dest.getBytesField()[0] = 7;
assertObjectEquals(bytes1, original.getBytesField());
@ -502,12 +511,12 @@ describe('Message test suite', function() {
assertObjectEquals(bytes1, original.getBytesField());
assertObjectEquals('789', dest.getBytesField());
}
dest.getExtension(proto.jspb.test.CloneExtension.extField).
setExt('new value');
dest.getExtension(proto.jspb.test.CloneExtension.extField)
.setExt('new value');
assertNotEquals(
dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt(),
original.getExtension(
proto.jspb.test.CloneExtension.extField).getExt());
original.getExtension(proto.jspb.test.CloneExtension.extField)
.getExt());
});
it('testCopyInto_notSameType', function() {
@ -525,26 +534,32 @@ describe('Message test suite', function() {
var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2']]);
var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
extension2);
extendable.setExtension(
proto.jspb.test.IndirectExtension.simple, extension2);
extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
['a', 'b']);
extendable.setExtension(
proto.jspb.test.IndirectExtension.repeatedStrList, ['a', 'b']);
var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2']]);
extendable.setExtension(
proto.jspb.test.IndirectExtension.repeatedSimpleList,
[s1, s2]);
assertObjectEquals(extension1,
proto.jspb.test.IndirectExtension.repeatedSimpleList, [s1, s2]);
assertObjectEquals(
extension1,
extendable.getExtension(proto.jspb.test.IsExtension.extField));
assertObjectEquals(extension2,
assertObjectEquals(
extension2,
extendable.getExtension(proto.jspb.test.IndirectExtension.simple));
assertObjectEquals('xyzzy',
assertObjectEquals(
'xyzzy',
extendable.getExtension(proto.jspb.test.IndirectExtension.str));
assertObjectEquals(['a', 'b'], extendable.getExtension(
proto.jspb.test.IndirectExtension.repeatedStrList));
assertObjectEquals([s1, s2], extendable.getExtension(
proto.jspb.test.IndirectExtension.repeatedSimpleList));
assertObjectEquals(
['a', 'b'],
extendable.getExtension(
proto.jspb.test.IndirectExtension.repeatedStrList));
assertObjectEquals(
[s1, s2],
extendable.getExtension(
proto.jspb.test.IndirectExtension.repeatedSimpleList));
// Not supported yet, but it should work...
extendable.setExtension(proto.jspb.test.IndirectExtension.simple, null);
assertNull(
@ -563,18 +578,18 @@ describe('Message test suite', function() {
var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
var extension = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
extendable.setExtension(proto.jspb.test.simple1, extension);
assertObjectEquals(extension,
extendable.getExtension(proto.jspb.test.simple1));
assertObjectEquals(
extension, extendable.getExtension(proto.jspb.test.simple1));
// From _lib mode.
extension = new proto.jspb.test.ExtensionMessage(['s1']);
extendable = new proto.jspb.test.TestExtensionsMessage([16]);
extendable.setExtension(proto.jspb.test.floatingMsgField, extension);
extendable.setExtension(proto.jspb.test.floatingStrField, 's2');
assertObjectEquals(extension,
extendable.getExtension(proto.jspb.test.floatingMsgField));
assertObjectEquals('s2',
extendable.getExtension(proto.jspb.test.floatingStrField));
assertObjectEquals(
extension, extendable.getExtension(proto.jspb.test.floatingMsgField));
assertObjectEquals(
's2', extendable.getExtension(proto.jspb.test.floatingStrField));
assertNotUndefined(proto.jspb.exttest.floatingMsgField);
assertNotUndefined(proto.jspb.exttest.floatingMsgFieldTwo);
assertNotUndefined(proto.jspb.exttest.beta.floatingStrField);
@ -585,60 +600,72 @@ describe('Message test suite', function() {
var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2'], true]);
var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
extension2);
extendable.setExtension(
proto.jspb.test.IndirectExtension.simple, extension2);
extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
['a', 'b']);
extendable.setExtension(
proto.jspb.test.IndirectExtension.repeatedStrList, ['a', 'b']);
var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2'], true]);
var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2'], false]);
extendable.setExtension(
proto.jspb.test.IndirectExtension.repeatedSimpleList,
[s1, s2]);
assertObjectEquals({
str1: 'v1', str2: 'v2', str3: 'v3',
extField: { ext1: 'ext1field' },
simple: {
aString: 'str', aRepeatedStringList: ['s1', 's2'], aBoolean: true
},
str: 'xyzzy',
repeatedStrList: ['a', 'b'],
repeatedSimpleList: [
{ aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true},
{ aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false}
]
}, extendable.toObject());
proto.jspb.test.IndirectExtension.repeatedSimpleList, [s1, s2]);
assertObjectEquals(
{
str1: 'v1',
str2: 'v2',
str3: 'v3',
extField: {ext1: 'ext1field'},
simple: {
aString: 'str',
aRepeatedStringList: ['s1', 's2'],
aBoolean: true
},
str: 'xyzzy',
repeatedStrList: ['a', 'b'],
repeatedSimpleList: [
{aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true},
{aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false}
]
},
extendable.toObject());
// Now, with instances included.
assertObjectEquals({
str1: 'v1', str2: 'v2', str3: 'v3',
extField: {
ext1: 'ext1field',
$jspbMessageInstance:
extendable.getExtension(proto.jspb.test.IsExtension.extField)
},
simple: {
aString: 'str',
aRepeatedStringList: ['s1', 's2'],
aBoolean: true,
$jspbMessageInstance:
extendable.getExtension(proto.jspb.test.IndirectExtension.simple)
},
str: 'xyzzy',
repeatedStrList: ['a', 'b'],
repeatedSimpleList: [{
aString: 'foo',
aRepeatedStringList: ['s1', 's2'],
aBoolean: true,
$jspbMessageInstance: s1
}, {
aString: 'bar',
aRepeatedStringList: ['t1', 't2'],
aBoolean: false,
$jspbMessageInstance: s2
}],
$jspbMessageInstance: extendable
}, extendable.toObject(true /* opt_includeInstance */));
assertObjectEquals(
{
str1: 'v1',
str2: 'v2',
str3: 'v3',
extField: {
ext1: 'ext1field',
$jspbMessageInstance:
extendable.getExtension(proto.jspb.test.IsExtension.extField)
},
simple: {
aString: 'str',
aRepeatedStringList: ['s1', 's2'],
aBoolean: true,
$jspbMessageInstance: extendable.getExtension(
proto.jspb.test.IndirectExtension.simple)
},
str: 'xyzzy',
repeatedStrList: ['a', 'b'],
repeatedSimpleList: [
{
aString: 'foo',
aRepeatedStringList: ['s1', 's2'],
aBoolean: true,
$jspbMessageInstance: s1
},
{
aString: 'bar',
aRepeatedStringList: ['t1', 't2'],
aBoolean: false,
$jspbMessageInstance: s2
}
],
$jspbMessageInstance: extendable
},
extendable.toObject(true /* opt_includeInstance */));
});
it('testInitialization_emptyArray', function() {
@ -690,8 +717,7 @@ describe('Message test suite', function() {
var extensionMessage = new proto.jspb.test.IsExtension(['is_extension']);
data.setExtension(proto.jspb.test.IsExtension.extField, extensionMessage);
var obj = data.toObject();
assertNotNull(
data.getExtension(proto.jspb.test.IsExtension.extField));
assertNotNull(data.getExtension(proto.jspb.test.IsExtension.extField));
assertEquals('is_extension', obj.extField.ext1);
});
@ -708,16 +734,18 @@ describe('Message test suite', function() {
var groups = group.getRepeatedGroupList();
assertEquals('g1', groups[0].getId());
assertObjectEquals([true, false], groups[0].getSomeBoolList());
assertObjectEquals({id: 'g1', someBoolList: [true, false]},
groups[0].toObject());
assertObjectEquals({
repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}],
requiredGroup: {id: undefined},
optionalGroup: undefined,
requiredSimple: {aRepeatedStringList: [], aString: undefined},
optionalSimple: undefined,
id: undefined
}, group.toObject());
assertObjectEquals(
{id: 'g1', someBoolList: [true, false]}, groups[0].toObject());
assertObjectEquals(
{
repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}],
requiredGroup: {id: undefined},
optionalGroup: undefined,
requiredSimple: {aRepeatedStringList: [], aString: undefined},
optionalSimple: undefined,
id: undefined
},
group.toObject());
var group1 = new proto.jspb.test.TestGroup1();
group1.setGroup(someGroup);
assertEquals(someGroup, group1.getGroup());
@ -734,25 +762,26 @@ describe('Message test suite', function() {
message.setExtension$(11);
message.setExtension(proto.jspb.test.TestReservedNamesExtension.foo, 12);
assertEquals(11, message.getExtension$());
assertEquals(12, message.getExtension(
proto.jspb.test.TestReservedNamesExtension.foo));
assertEquals(
12,
message.getExtension(proto.jspb.test.TestReservedNamesExtension.foo));
assertObjectEquals({extension: 11, foo: 12}, message.toObject());
});
it('testInitializeMessageWithUnsetOneof', function() {
var message = new proto.jspb.test.TestMessageWithOneof([]);
assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
PARTIAL_ONEOF_NOT_SET,
proto.jspb.test.TestMessageWithOneof.PartialOneofCase
.PARTIAL_ONEOF_NOT_SET,
message.getPartialOneofCase());
assertEquals(
proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
RECURSIVE_ONEOF_NOT_SET,
proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase
.RECURSIVE_ONEOF_NOT_SET,
message.getRecursiveOneofCase());
});
it('testInitializeMessageWithSingleValueSetInOneof', function() {
var message = new proto.jspb.test.TestMessageWithOneof([,, 'x']);
var message = new proto.jspb.test.TestMessageWithOneof([, , 'x']);
assertEquals('x', message.getPone());
assertEquals('', message.getPthree());
@ -762,7 +791,7 @@ describe('Message test suite', function() {
});
it('testKeepsLastWireValueSetInUnion_multipleValues', function() {
var message = new proto.jspb.test.TestMessageWithOneof([,, 'x',, 'y']);
var message = new proto.jspb.test.TestMessageWithOneof([, , 'x', , 'y']);
assertEquals('', message.getPone());
assertEquals('y', message.getPthree());
@ -819,8 +848,8 @@ describe('Message test suite', function() {
it('testUnsetsOneofCaseWhenFieldIsCleared', function() {
var message = new proto.jspb.test.TestMessageWithOneof;
assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
PARTIAL_ONEOF_NOT_SET,
proto.jspb.test.TestMessageWithOneof.PartialOneofCase
.PARTIAL_ONEOF_NOT_SET,
message.getPartialOneofCase());
message.setPone('hi');
@ -830,8 +859,8 @@ describe('Message test suite', function() {
message.clearPone();
assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
PARTIAL_ONEOF_NOT_SET,
proto.jspb.test.TestMessageWithOneof.PartialOneofCase
.PARTIAL_ONEOF_NOT_SET,
message.getPartialOneofCase());
});
@ -934,39 +963,39 @@ describe('Message test suite', function() {
});
it('testInitializeMessageWithOneofDefaults_defaultNotSetOnFirstField',
function() {
var message;
message =
new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567));
assertEquals(567, message.getBone());
assertEquals(1234, message.getBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
message.getDefaultOneofBCase());
message =
new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890));
assertEquals(0, message.getBone());
assertEquals(890, message.getBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
message.getDefaultOneofBCase());
message = new proto.jspb.test.TestMessageWithOneof(
new Array(11).concat(567, 890));
assertEquals(0, message.getBone());
assertEquals(890, message.getBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
message.getDefaultOneofBCase());
});
function() {
var message;
message =
new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567));
assertEquals(567, message.getBone());
assertEquals(1234, message.getBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
message.getDefaultOneofBCase());
message =
new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890));
assertEquals(0, message.getBone());
assertEquals(890, message.getBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
message.getDefaultOneofBCase());
message = new proto.jspb.test.TestMessageWithOneof(
new Array(11).concat(567, 890));
assertEquals(0, message.getBone());
assertEquals(890, message.getBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
message.getDefaultOneofBCase());
});
it('testOneofContainingAnotherMessage', function() {
var message = new proto.jspb.test.TestMessageWithOneof;
assertEquals(
proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
RECURSIVE_ONEOF_NOT_SET,
proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase
.RECURSIVE_ONEOF_NOT_SET,
message.getRecursiveOneofCase());
var other = new proto.jspb.test.TestMessageWithOneof;
@ -987,25 +1016,25 @@ describe('Message test suite', function() {
it('testQueryingOneofCaseEnsuresOnlyOneFieldIsSetInUnderlyingArray',
function() {
var message = new proto.jspb.test.TestMessageWithOneof;
message.setPone('x');
assertEquals('x', message.getPone());
assertEquals('', message.getPthree());
assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
message.getPartialOneofCase());
var array = message.toArray();
assertEquals('x', array[2]);
assertUndefined(array[4]);
array[4] = 'y';
assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
message.getPartialOneofCase());
assertUndefined(array[2]);
assertEquals('y', array[4]);
});
var message = new proto.jspb.test.TestMessageWithOneof;
message.setPone('x');
assertEquals('x', message.getPone());
assertEquals('', message.getPthree());
assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
message.getPartialOneofCase());
var array = message.toArray();
assertEquals('x', array[2]);
assertUndefined(array[4]);
array[4] = 'y';
assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
message.getPartialOneofCase());
assertUndefined(array[2]);
assertEquals('y', array[4]);
});
it('testFloatingPointFieldsSupportNan', function() {
var assertNan = function(x) {
@ -1015,8 +1044,7 @@ describe('Message test suite', function() {
};
var message = new proto.jspb.test.FloatingPointFields([
'NaN', 'NaN', ['NaN', 'NaN'], 'NaN',
'NaN', 'NaN', ['NaN', 'NaN'], 'NaN'
'NaN', 'NaN', ['NaN', 'NaN'], 'NaN', 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN'
]);
assertNan(message.getOptionalFloatField());
assertNan(message.getRequiredFloatField());
@ -1029,5 +1057,4 @@ describe('Message test suite', function() {
assertNan(message.getRepeatedDoubleFieldList()[1]);
assertNan(message.getDefaultDoubleField());
});
});

@ -53,6 +53,8 @@ goog.require('proto.jspb.test.MapEntryOptionalValuesMessageValue');
goog.require('proto.jspb.test.MapValueMessageNoBinary');
goog.require('proto.jspb.test.TestMapFieldsNoBinary');
goog.requireType('jspb.Map');
/**
* Helper: check that the given map has exactly this set of (sorted) entries.
* @param {!jspb.Map} map
@ -116,7 +118,9 @@ function makeTests(msgInfo, submessageCtor, suffix) {
msg.getMapStringMsgMap().get('k').setFoo(42);
msg.getMapStringMsgMap().get('l').setFoo(84);
msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b');
msg.getMapInt64StringMap().set(0x123456789abc, 'c').set(0xcba987654321, 'd');
msg.getMapInt64StringMap()
.set(0x123456789abc, 'c')
.set(0xcba987654321, 'd');
msg.getMapBoolStringMap().set(false, 'e').set(true, 'f');
};
@ -125,42 +129,24 @@ function makeTests(msgInfo, submessageCtor, suffix) {
* @param {?} msg
*/
var checkMapFields = function(msg) {
checkMapEquals(msg.getMapStringStringMap(), [
['asdf', 'jkl;'],
['key 2', 'hello world']
]);
checkMapEquals(msg.getMapStringInt32Map(), [
['a', 1],
['b', -2]
]);
checkMapEquals(msg.getMapStringInt64Map(), [
['c', 0x100000000],
['d', 0x200000000]
]);
checkMapEquals(msg.getMapStringBoolMap(), [
['e', true],
['f', false]
]);
checkMapEquals(msg.getMapStringDoubleMap(), [
['g', 3.14159],
['h', 2.71828]
]);
checkMapEquals(
msg.getMapStringStringMap(),
[['asdf', 'jkl;'], ['key 2', 'hello world']]);
checkMapEquals(msg.getMapStringInt32Map(), [['a', 1], ['b', -2]]);
checkMapEquals(
msg.getMapStringInt64Map(), [['c', 0x100000000], ['d', 0x200000000]]);
checkMapEquals(msg.getMapStringBoolMap(), [['e', true], ['f', false]]);
checkMapEquals(
msg.getMapStringDoubleMap(), [['g', 3.14159], ['h', 2.71828]]);
checkMapEquals(msg.getMapStringEnumMap(), [
['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
]);
checkMapEquals(msg.getMapInt32StringMap(), [
[-1, 'a'],
[42, 'b']
]);
checkMapEquals(msg.getMapInt64StringMap(), [
[0x123456789abc, 'c'],
[0xcba987654321, 'd']
]);
checkMapEquals(msg.getMapBoolStringMap(), [
[false, 'e'],
[true, 'f']
['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
]);
checkMapEquals(msg.getMapInt32StringMap(), [[-1, 'a'], [42, 'b']]);
checkMapEquals(
msg.getMapInt64StringMap(),
[[0x123456789abc, 'c'], [0xcba987654321, 'd']]);
checkMapEquals(msg.getMapBoolStringMap(), [[false, 'e'], [true, 'f']]);
assertEquals(msg.getMapStringMsgMap().getLength(), 2);
assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42);
@ -205,10 +191,7 @@ function makeTests(msgInfo, submessageCtor, suffix) {
assertElementsEquals(it.next().value, ['asdf', 'hello world']);
assertElementsEquals(it.next().value, ['jkl;', 'key 2']);
assertEquals(it.next().done, true);
checkMapEquals(m, [
['asdf', 'hello world'],
['jkl;', 'key 2']
]);
checkMapEquals(m, [['asdf', 'hello world'], ['jkl;', 'key 2']]);
m.del('jkl;');
assertEquals(m.has('jkl;'), false);
assertEquals(m.get('jkl;'), undefined);
@ -260,11 +243,11 @@ function makeTests(msgInfo, submessageCtor, suffix) {
msg.getMapStringStringMap().set('A', 'a');
var serialized = msg.serializeBinary();
var expectedSerialized = [
0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
0x41, // ASCII 'A'
0x12, 0x1, // field 2 in submessage (value), delimited, length 1
0x61 // ASCII 'a'
0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
0x41, // ASCII 'A'
0x12, 0x1, // field 2 in submessage (value), delimited, length 1
0x61 // ASCII 'a'
];
assertEquals(serialized.length, expectedSerialized.length);
for (var i = 0; i < serialized.length; i++) {
@ -284,34 +267,27 @@ function makeTests(msgInfo, submessageCtor, suffix) {
* binary format.
*/
it('testMapDeserializationForUndefinedKeys', function() {
var testMessageOptionalKeys = new proto.jspb.test.TestMapFieldsOptionalKeys();
var mapEntryStringKey = new proto.jspb.test.MapEntryOptionalKeysStringKey();
mapEntryStringKey.setValue("a");
var testMessageOptionalKeys =
new proto.jspb.test.TestMapFieldsOptionalKeys();
var mapEntryStringKey =
new proto.jspb.test.MapEntryOptionalKeysStringKey();
mapEntryStringKey.setValue('a');
testMessageOptionalKeys.setMapStringString(mapEntryStringKey);
var mapEntryInt32Key = new proto.jspb.test.MapEntryOptionalKeysInt32Key();
mapEntryInt32Key.setValue("b");
mapEntryInt32Key.setValue('b');
testMessageOptionalKeys.setMapInt32String(mapEntryInt32Key);
var mapEntryInt64Key = new proto.jspb.test.MapEntryOptionalKeysInt64Key();
mapEntryInt64Key.setValue("c");
mapEntryInt64Key.setValue('c');
testMessageOptionalKeys.setMapInt64String(mapEntryInt64Key);
var mapEntryBoolKey = new proto.jspb.test.MapEntryOptionalKeysBoolKey();
mapEntryBoolKey.setValue("d");
mapEntryBoolKey.setValue('d');
testMessageOptionalKeys.setMapBoolString(mapEntryBoolKey);
var deserializedMessage = msgInfo.deserializeBinary(
testMessageOptionalKeys.serializeBinary()
);
checkMapEquals(deserializedMessage.getMapStringStringMap(), [
['', 'a']
]);
checkMapEquals(deserializedMessage.getMapInt32StringMap(), [
[0, 'b']
]);
checkMapEquals(deserializedMessage.getMapInt64StringMap(), [
[0, 'c']
]);
checkMapEquals(deserializedMessage.getMapBoolStringMap(), [
[false, 'd']
]);
var deserializedMessage =
msgInfo.deserializeBinary(testMessageOptionalKeys.serializeBinary());
checkMapEquals(deserializedMessage.getMapStringStringMap(), [['', 'a']]);
checkMapEquals(deserializedMessage.getMapInt32StringMap(), [[0, 'b']]);
checkMapEquals(deserializedMessage.getMapInt64StringMap(), [[0, 'c']]);
checkMapEquals(deserializedMessage.getMapBoolStringMap(), [[false, 'd']]);
});
/**
@ -323,56 +299,41 @@ function makeTests(msgInfo, submessageCtor, suffix) {
new proto.jspb.test.TestMapFieldsOptionalValues();
var mapEntryStringValue =
new proto.jspb.test.MapEntryOptionalValuesStringValue();
mapEntryStringValue.setKey("a");
mapEntryStringValue.setKey('a');
testMessageOptionalValues.setMapStringString(mapEntryStringValue);
var mapEntryInt32Value =
new proto.jspb.test.MapEntryOptionalValuesInt32Value();
mapEntryInt32Value.setKey("b");
mapEntryInt32Value.setKey('b');
testMessageOptionalValues.setMapStringInt32(mapEntryInt32Value);
var mapEntryInt64Value =
new proto.jspb.test.MapEntryOptionalValuesInt64Value();
mapEntryInt64Value.setKey("c");
mapEntryInt64Value.setKey('c');
testMessageOptionalValues.setMapStringInt64(mapEntryInt64Value);
var mapEntryBoolValue =
new proto.jspb.test.MapEntryOptionalValuesBoolValue();
mapEntryBoolValue.setKey("d");
mapEntryBoolValue.setKey('d');
testMessageOptionalValues.setMapStringBool(mapEntryBoolValue);
var mapEntryDoubleValue =
new proto.jspb.test.MapEntryOptionalValuesDoubleValue();
mapEntryDoubleValue.setKey("e");
mapEntryDoubleValue.setKey('e');
testMessageOptionalValues.setMapStringDouble(mapEntryDoubleValue);
var mapEntryEnumValue =
new proto.jspb.test.MapEntryOptionalValuesEnumValue();
mapEntryEnumValue.setKey("f");
mapEntryEnumValue.setKey('f');
testMessageOptionalValues.setMapStringEnum(mapEntryEnumValue);
var mapEntryMessageValue =
new proto.jspb.test.MapEntryOptionalValuesMessageValue();
mapEntryMessageValue.setKey("g");
mapEntryMessageValue.setKey('g');
testMessageOptionalValues.setMapStringMsg(mapEntryMessageValue);
var deserializedMessage = msgInfo.deserializeBinary(
testMessageOptionalValues.serializeBinary()
);
checkMapEquals(deserializedMessage.getMapStringStringMap(), [
['a', '']
]);
checkMapEquals(deserializedMessage.getMapStringInt32Map(), [
['b', 0]
]);
checkMapEquals(deserializedMessage.getMapStringInt64Map(), [
['c', 0]
]);
checkMapEquals(deserializedMessage.getMapStringBoolMap(), [
['d', false]
]);
checkMapEquals(deserializedMessage.getMapStringDoubleMap(), [
['e', 0.0]
]);
checkMapEquals(deserializedMessage.getMapStringEnumMap(), [
['f', 0]
]);
checkMapEquals(deserializedMessage.getMapStringMsgMap(), [
['g', []]
]);
testMessageOptionalValues.serializeBinary());
checkMapEquals(deserializedMessage.getMapStringStringMap(), [['a', '']]);
checkMapEquals(deserializedMessage.getMapStringInt32Map(), [['b', 0]]);
checkMapEquals(deserializedMessage.getMapStringInt64Map(), [['c', 0]]);
checkMapEquals(deserializedMessage.getMapStringBoolMap(), [['d', false]]);
checkMapEquals(deserializedMessage.getMapStringDoubleMap(), [['e', 0.0]]);
checkMapEquals(deserializedMessage.getMapStringEnumMap(), [['f', 0]]);
checkMapEquals(deserializedMessage.getMapStringMsgMap(), [['g', []]]);
});
}
@ -382,11 +343,7 @@ function makeTests(msgInfo, submessageCtor, suffix) {
*/
it('testLazyMapSync' + suffix, function() {
// Start with a JSPB array containing a few map entries.
var entries = [
['a', 'entry 1'],
['c', 'entry 2'],
['b', 'entry 3']
];
var entries = [['a', 'entry 1'], ['c', 'entry 2'], ['b', 'entry 3']];
var msg = new msgInfo.constructor([entries]);
assertEquals(entries.length, 3);
assertEquals(entries[0][0], 'a');
@ -394,9 +351,9 @@ function makeTests(msgInfo, submessageCtor, suffix) {
assertEquals(entries[2][0], 'b');
msg.getMapStringStringMap().del('a');
assertEquals(entries.length, 3); // not yet sync'd
msg.toArray(); // force a sync
msg.toArray(); // force a sync
assertEquals(entries.length, 2);
assertEquals(entries[0][0], 'b'); // now in sorted order
assertEquals(entries[0][0], 'b'); // now in sorted order
assertEquals(entries[1][0], 'c');
var a = msg.toArray();

@ -121,6 +121,8 @@ goog.require('proto.jspb.test.TestAllowAliasEnum');
// CommonJS-LoadFromFile: testlargenumbers_pb proto.jspb.test
goog.require('proto.jspb.test.MessageWithLargeFieldNumbers');
goog.require('proto.jspb.test.simple1');
describe('Message test suite', function() {
var stubs = new goog.testing.PropertyReplacer();
@ -185,7 +187,6 @@ describe('Message test suite', function() {
$jspbMessageInstance: foo
},
result);
});
it('testMissingFields', function() {
@ -209,7 +210,6 @@ describe('Message test suite', function() {
aFloatingPointField: undefined,
},
result);
});
it('testNestedComplexMessage', function() {
@ -1108,5 +1108,4 @@ describe('Message test suite', function() {
message.setAInt(42);
assertEquals(42, message.getAInt());
});
});

@ -41,7 +41,7 @@ goog.require('proto.google.protobuf.Any');
goog.require('proto.google.protobuf.Timestamp');
// CommonJS-LoadFromFile: google/protobuf/struct_pb proto.google.protobuf
goog.require('proto.google.protobuf.Struct');
goog.require('jspb.Message');
var BYTES = new Uint8Array([1, 2, 8, 9]);
var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
@ -70,7 +70,6 @@ function bytesCompare(arr, expected) {
describe('proto3Test', function() {
/**
* Test default values don't affect equality test.
*/
@ -182,8 +181,8 @@ describe('proto3Test', function() {
assertEquals(msg.getOptionalBytes_asU8().length, 0);
assertEquals(msg.getOptionalBytes_asB64(), '');
assertEquals(msg.getOptionalForeignEnum(),
proto.jspb.test.Proto3Enum.PROTO3_FOO);
assertEquals(
msg.getOptionalForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_FOO);
assertEquals(msg.getOptionalForeignMessage(), undefined);
assertEquals(msg.getOptionalForeignMessage(), undefined);
@ -309,7 +308,8 @@ describe('proto3Test', function() {
assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES));
assertEquals(msg.getRepeatedForeignMessageList().length, 1);
assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000);
assertElementsEquals(msg.getRepeatedForeignEnumList(),
assertElementsEquals(
msg.getRepeatedForeignEnumList(),
[proto.jspb.test.Proto3Enum.PROTO3_BAR]);
assertEquals(msg.getOneofString(), 'asdf');
@ -374,7 +374,8 @@ describe('proto3Test', function() {
assertEquals(msg.getOneofUint32(), 0);
assertEquals(msg.getOneofForeignMessage(), undefined);
assertEquals(msg.getOneofString(), '');
assertEquals(msg.getOneofBytes_asB64(),
assertEquals(
msg.getOneofBytes_asB64(),
goog.crypt.base64.encodeString('\u00FF\u00FF'));
assertFalse(msg.hasOneofUint32());
@ -454,24 +455,24 @@ describe('proto3Test', function() {
it('testStructWellKnownType', function() {
var jsObj = {
abc: "def",
abc: 'def',
number: 12345.678,
nullKey: null,
boolKey: true,
listKey: [1, null, true, false, "abc"],
structKey: {foo: "bar", somenum: 123},
complicatedKey: [{xyz: {abc: [3, 4, null, false]}}, "zzz"]
listKey: [1, null, true, false, 'abc'],
structKey: {foo: 'bar', somenum: 123},
complicatedKey: [{xyz: {abc: [3, 4, null, false]}}, 'zzz']
};
var struct = proto.google.protobuf.Struct.fromJavaScript(jsObj);
var jsObj2 = struct.toJavaScript();
assertEquals("def", jsObj2.abc);
assertEquals('def', jsObj2.abc);
assertEquals(12345.678, jsObj2.number);
assertEquals(null, jsObj2.nullKey);
assertEquals(true, jsObj2.boolKey);
assertEquals("abc", jsObj2.listKey[4]);
assertEquals("bar", jsObj2.structKey.foo);
assertEquals('abc', jsObj2.listKey[4]);
assertEquals('bar', jsObj2.structKey.foo);
assertEquals(4, jsObj2.complicatedKey[0].xyz.abc[1]);
});
});

@ -3,4 +3,10 @@ Kokoro Infrastructure
----------------------
The files in this directory serve as plumbing for running Protobuf
tests under Kokoro, our internal CI.
tests under Kokoro, our internal CI.
We have shared this part of our CI configuration in hopes that it is
helpful to contributors who want to better understand the details of
our test and release processes. If there are changes, please file an
issue; unfortunately, we may not be able to accept PRs (but feel free
to send one if it helps to explain the issue).

@ -55,6 +55,26 @@ RUN mv composer.phar /usr/local/bin/composer
# Download php source code
RUN git clone https://github.com/php/php-src
# php 5.6
RUN cd php-src \
&& git checkout PHP-5.6.39 \
&& ./buildconf --force
RUN cd php-src \
&& ./configure \
--enable-bcmath \
--enable-mbstring \
--with-gmp \
--with-openssl \
--with-zlib \
--prefix=/usr/local/php-5.6 \
&& make \
&& make install \
&& make clean
RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
&& chmod +x phpunit \
&& mv phpunit /usr/local/php-5.6/bin
# php 7.0
RUN cd php-src \
&& git checkout PHP-7.0.33 \

@ -53,6 +53,25 @@ RUN mv composer.phar /usr/local/bin/composer
# Download php source code
RUN git clone https://github.com/php/php-src
# php 5.6
RUN cd php-src \
&& git checkout PHP-5.6.39 \
&& ./buildconf --force
RUN cd php-src \
&& ./configure \
--enable-bcmath \
--enable-mbstring \
--with-openssl \
--with-zlib \
--prefix=/usr/local/php-5.6 \
&& make \
&& make install \
&& make clean
RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
&& chmod +x phpunit \
&& mv phpunit /usr/local/php-5.6/bin
# php 7.0
RUN wget https://github.com/php/php-src/archive/php-7.0.33.tar.gz -O /var/local/php-7.0.33.tar.gz

@ -0,0 +1,31 @@
FROM python:3.9-buster
# Install dependencies. We start with the basic ones require to build protoc
# and the C++ build
RUN apt-get update && apt-get install -y \
autoconf \
autotools-dev \
build-essential \
bzip2 \
ccache \
curl \
gcc \
git \
libc6 \
libc6-dbg \
libc6-dev \
libgtest-dev \
libtool \
make \
parallel \
time \
wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install Python libraries.
RUN python -m pip install --no-cache-dir --upgrade \
pip \
setuptools \
tox \
wheel

@ -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/python39
export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
export OUTPUT_DIR=testoutput
export TEST_SET="python39"
./kokoro/linux/build_and_run_docker.sh

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

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

@ -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/python39
export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
export OUTPUT_DIR=testoutput
export TEST_SET="python39_cpp"
./kokoro/linux/build_and_run_docker.sh

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

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

@ -11,4 +11,7 @@ set PATH=%LOCALAPPDATA%\Microsoft\dotnet;%PATH%
set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
set DOTNET_CLI_TELEMETRY_OPTOUT=true
@rem Work around https://github.com/dotnet/core/issues/5881
dotnet nuget locals all --clear
call build_packages.bat

@ -54,3 +54,4 @@ build_artifact_version 3.5
build_artifact_version 3.6
build_artifact_version 3.7
build_artifact_version 3.8
build_artifact_version 3.9

@ -55,6 +55,7 @@ build_artifact_version 2.7
build_artifact_version 3.6
build_artifact_version 3.7
build_artifact_version 3.8
build_artifact_version 3.9
# python OSX10.9 does not have python 3.5
export MB_PYTHON_OSX_VER=10.6

@ -72,6 +72,16 @@ SET PYTHON_VERSION=3.8
SET PYTHON_ARCH=64
CALL build_single_artifact.bat || goto :error
SET PYTHON=C:\python39_32bit
SET PYTHON_VERSION=3.9
SET PYTHON_ARCH=32
CALL build_single_artifact.bat || goto :error
SET PYTHON=C:\python39
SET PYTHON_VERSION=3.9
SET PYTHON_ARCH=64
CALL build_single_artifact.bat || goto :error
goto :EOF
:error

@ -24,10 +24,16 @@ if %PYTHON%==C:\python38_32bit set vcplatform=Win32
if %PYTHON%==C:\python38 set generator=Visual Studio 14 Win64
if %PYTHON%==C:\python38 set vcplatform=x64
if %PYTHON%==C:\python39_32bit set generator=Visual Studio 14
if %PYTHON%==C:\python39_32bit set vcplatform=Win32
if %PYTHON%==C:\python39 set generator=Visual Studio 14 Win64
if %PYTHON%==C:\python39 set vcplatform=x64
REM Prepend newly installed Python to the PATH of this build (this cannot be
REM done from inside the powershell script as it would require to restart
REM the parent CMD process).
SET PATH=%PYTHON%;%PYTHON%\Scripts;%OLD_PATH%
SET PATH=C:\Program Files\CMake\bin;%PYTHON%;%PYTHON%\Scripts;%OLD_PATH%
python -m pip install -U pip
pip install wheel

@ -11,4 +11,7 @@ set PATH=%LOCALAPPDATA%\Microsoft\dotnet;%PATH%
set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
set DOTNET_CLI_TELEMETRY_OPTOUT=true
@rem Work around https://github.com/dotnet/core/issues/5881
dotnet nuget locals all --clear
call buildall.bat

@ -6,10 +6,10 @@
"homepage": "https://developers.google.com/protocol-buffers/",
"license": "BSD-3-Clause",
"require": {
"php": ">=7.0.0"
"php": ">=5.5.0"
},
"require-dev": {
"phpunit/phpunit": ">=6.0.0"
"phpunit/phpunit": ">=5.0.0"
},
"autoload": {
"psr-4": {

@ -55,8 +55,7 @@ typedef struct {
zend_object std;
zval arena;
upb_array *array;
upb_fieldtype_t type;
const Descriptor* desc; // When values are messages.
TypeInfo type;
} RepeatedField;
zend_class_entry *RepeatedField_class_entry;
@ -76,7 +75,6 @@ static zend_object* RepeatedField_create(zend_class_entry *class_type) {
intern->std.handlers = &RepeatedField_object_handlers;
Arena_Init(&intern->arena);
intern->array = NULL;
intern->desc = NULL;
// Skip object_properties_init(), we don't allow derived classes.
return &intern->std;
}
@ -106,13 +104,35 @@ static void RepeatedField_destructor(zend_object* obj) {
static int RepeatedField_compare_objects(zval *rf1, zval *rf2) {
RepeatedField* intern1 = (RepeatedField*)Z_OBJ_P(rf1);
RepeatedField* intern2 = (RepeatedField*)Z_OBJ_P(rf2);
upb_fieldtype_t type = intern1->type;
const upb_msgdef *m = intern1->desc ? intern1->desc->msgdef : NULL;
if (type != intern2->type) return 1;
if (intern1->desc != intern2->desc) return 1;
return TypeInfo_Eq(intern1->type, intern2->type) &&
ArrayEq(intern1->array, intern2->array, intern1->type)
? 0
: 1;
}
/**
* RepeatedField_clone_obj()
*
* Object handler for cloning an object in PHP. Called when PHP code does:
*
* $rf2 = clone $rf1;
*/
static zend_object *RepeatedField_clone_obj(PROTO_VAL *object) {
RepeatedField* intern = PROTO_VAL_P(object);
upb_arena *arena = Arena_Get(&intern->arena);
upb_array *clone = upb_array_new(arena, intern->type.type);
size_t n = upb_array_size(intern->array);
size_t i;
for (i = 0; i < n; i++) {
upb_msgval msgval = upb_array_get(intern->array, i);
upb_array_append(clone, msgval, arena);
}
return ArrayEq(intern1->array, intern2->array, type, m) ? 0 : 1;
zval ret;
RepeatedField_GetPhpWrapper(&ret, clone, intern->type, &intern->arena);
return Z_OBJ_P(&ret);
}
static HashTable *RepeatedField_GetProperties(PROTO_VAL *object) {
@ -129,8 +149,8 @@ static zval *RepeatedField_GetPropertyPtrPtr(PROTO_VAL *object,
// These are documented in the header file.
void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr,
const upb_fielddef *f, zval *arena) {
void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr, TypeInfo type,
zval *arena) {
if (!arr) {
ZVAL_NULL(val);
return;
@ -142,15 +162,14 @@ void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr,
intern->std.handlers = &RepeatedField_object_handlers;
ZVAL_COPY(&intern->arena, arena);
intern->array = arr;
intern->type = upb_fielddef_type(f);
intern->desc = Descriptor_GetFromFieldDef(f);
intern->type = type;
// Skip object_properties_init(), we don't allow derived classes.
ObjCache_Add(intern->array, &intern->std);
ZVAL_OBJ(val, &intern->std);
}
}
upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f,
upb_array *RepeatedField_GetUpbArray(zval *val, TypeInfo type,
upb_arena *arena) {
if (Z_ISREF_P(val)) {
ZVAL_DEREF(val);
@ -158,11 +177,9 @@ upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f,
if (Z_TYPE_P(val) == IS_ARRAY) {
// Auto-construct, eg. [1, 2, 3] -> upb_array([1, 2, 3]).
upb_array *arr = upb_array_new(arena, upb_fielddef_type(f));
upb_array *arr = upb_array_new(arena, type.type);
HashTable *table = HASH_OF(val);
HashPosition pos;
upb_fieldtype_t type = upb_fielddef_type(f);
const Descriptor *desc = Descriptor_GetFromFieldDef(f);
zend_hash_internal_pointer_reset_ex(table, &pos);
@ -172,7 +189,7 @@ upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f,
if (!zv) return arr;
if (!Convert_PhpToUpbAutoWrap(zv, &val, type, desc, arena)) {
if (!Convert_PhpToUpbAutoWrap(zv, &val, type, arena)) {
return NULL;
}
@ -183,9 +200,8 @@ upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f,
Z_OBJCE_P(val) == RepeatedField_class_entry) {
// Unwrap existing RepeatedField object to get the upb_array* inside.
RepeatedField *intern = (RepeatedField*)Z_OBJ_P(val);
const Descriptor *desc = Descriptor_GetFromFieldDef(f);
if (intern->type != upb_fielddef_type(f) || intern->desc != desc) {
if (!TypeInfo_Eq(intern->type, type)) {
php_error_docref(NULL, E_USER_ERROR,
"Wrong type for this repeated field.");
}
@ -198,8 +214,7 @@ upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f,
}
}
bool ArrayEq(const upb_array *a1, const upb_array *a2, upb_fieldtype_t type,
const upb_msgdef *m) {
bool ArrayEq(const upb_array *a1, const upb_array *a2, TypeInfo type) {
size_t i;
size_t n;
@ -212,7 +227,7 @@ bool ArrayEq(const upb_array *a1, const upb_array *a2, upb_fieldtype_t type,
for (i = 0; i < n; i++) {
upb_msgval val1 = upb_array_get(a1, i);
upb_msgval val2 = upb_array_get(a2, i);
if (!ValueEq(val1, val2, type, m)) return false;
if (!ValueEq(val1, val2, type)) return false;
}
return true;
@ -238,16 +253,16 @@ PHP_METHOD(RepeatedField, __construct) {
return;
}
intern->type = pbphp_dtype_to_type(type);
intern->desc = Descriptor_GetFromClassEntry(klass);
intern->type.type = pbphp_dtype_to_type(type);
intern->type.desc = Descriptor_GetFromClassEntry(klass);
if (intern->type == UPB_TYPE_MESSAGE && klass == NULL) {
if (intern->type.type == UPB_TYPE_MESSAGE && klass == NULL) {
php_error_docref(NULL, E_USER_ERROR,
"Message/enum type must have concrete class.");
return;
}
intern->array = upb_array_new(arena, intern->type);
intern->array = upb_array_new(arena, intern->type.type);
ObjCache_Add(intern->array, &intern->std);
}
@ -264,7 +279,7 @@ PHP_METHOD(RepeatedField, append) {
upb_msgval msgval;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &php_val) != SUCCESS ||
!Convert_PhpToUpb(php_val, &msgval, intern->type, intern->desc, arena)) {
!Convert_PhpToUpb(php_val, &msgval, intern->type, arena)) {
return;
}
@ -321,7 +336,7 @@ PHP_METHOD(RepeatedField, offsetGet) {
}
msgval = upb_array_get(intern->array, index);
Convert_UpbToPhp(msgval, &ret, intern->type, intern->desc, &intern->arena);
Convert_UpbToPhp(msgval, &ret, intern->type, &intern->arena);
RETURN_ZVAL(&ret, 0, 1);
}
@ -357,7 +372,7 @@ PHP_METHOD(RepeatedField, offsetSet) {
return;
}
if (!Convert_PhpToUpb(val, &msgval, intern->type, intern->desc, arena)) {
if (!Convert_PhpToUpb(val, &msgval, intern->type, arena)) {
return;
}
@ -563,7 +578,7 @@ PHP_METHOD(RepeatedFieldIter, current) {
msgval = upb_array_get(array, index);
Convert_UpbToPhp(msgval, &ret, field->type, field->desc, &field->arena);
Convert_UpbToPhp(msgval, &ret, field->type, &field->arena);
RETURN_ZVAL(&ret, 0, 1);
}
@ -638,6 +653,7 @@ void Array_ModuleInit() {
#else
h->compare = RepeatedField_compare_objects;
#endif
h->clone_obj = RepeatedField_clone_obj;
h->get_properties = RepeatedField_GetProperties;
h->get_property_ptr_ptr = RepeatedField_GetPropertyPtrPtr;

@ -33,6 +33,7 @@
#include <php.h>
#include "def.h"
#include "php-upb.h"
// Registers PHP classes for RepeatedField.
@ -40,27 +41,27 @@ void Array_ModuleInit();
// Gets a upb_array* for the PHP object |val|:
// * If |val| is a RepeatedField object, we first check its type and verify
// that that the elements have the correct type for |f|. If so, we return the
// wrapped upb_array*. We also make sure that this array's arena is fused to
// |arena|, so the returned upb_array is guaranteed to live as long as
// that that the elements have the correct type for |type|. If so, we return
// the wrapped upb_array*. We also make sure that this array's arena is fused
// to |arena|, so the returned upb_array is guaranteed to live as long as
// |arena|.
// * If |val| is a PHP Array, we attempt to create a new upb_array using
// |arena| and add all of the PHP elements to it.
//
// If an error occurs, we raise a PHP error and return NULL.
upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f, upb_arena *arena);
upb_array *RepeatedField_GetUpbArray(zval *val, TypeInfo type,
upb_arena *arena);
// Creates a PHP RepeatedField object for the given upb_array* and |f| and
// Creates a PHP RepeatedField object for the given upb_array* and |type| and
// returns it in |val|. The PHP object will keep a reference to this |arena| to
// ensure the underlying array data stays alive.
//
// If |arr| is NULL, this will return a PHP null object.
void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr,
const upb_fielddef *f, zval *arena);
void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr, TypeInfo type,
zval *arena);
// Returns true if the given arrays are equal. Both arrays must be of this
// |type| and, if the type is |UPB_TYPE_MESSAGE|, must have the same |m|.
bool ArrayEq(const upb_array *a1, const upb_array *a2, upb_fieldtype_t type,
const upb_msgdef *m);
bool ArrayEq(const upb_array *a1, const upb_array *a2, TypeInfo type);
#endif // PHP_PROTOBUF_ARRAY_H_

@ -348,15 +348,15 @@ static bool to_string(zval* from) {
}
}
bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, upb_fieldtype_t type,
const Descriptor *desc, upb_arena *arena) {
bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, TypeInfo type,
upb_arena *arena) {
int64_t i64;
if (Z_ISREF_P(php_val)) {
ZVAL_DEREF(php_val);
}
switch (type) {
switch (type.type) {
case UPB_TYPE_INT64:
return Convert_PhpToInt64(php_val, &upb_val->int64_val);
case UPB_TYPE_INT32:
@ -408,17 +408,17 @@ bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, upb_fieldtype_t type,
return true;
}
case UPB_TYPE_MESSAGE:
PBPHP_ASSERT(desc);
return Message_GetUpbMessage(php_val, desc, arena,
PBPHP_ASSERT(type.desc);
return Message_GetUpbMessage(php_val, type.desc, arena,
(upb_msg **)&upb_val->msg_val);
}
return false;
}
void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, upb_fieldtype_t type,
const Descriptor *desc, zval *arena) {
switch (type) {
void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, TypeInfo type,
zval *arena) {
switch (type.type) {
case UPB_TYPE_INT64:
#if SIZEOF_ZEND_LONG == 8
ZVAL_LONG(php_val, upb_val.int64_val);
@ -467,25 +467,24 @@ void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, upb_fieldtype_t type,
break;
}
case UPB_TYPE_MESSAGE:
PBPHP_ASSERT(desc);
Message_GetPhpWrapper(php_val, desc, (upb_msg*)upb_val.msg_val, arena);
PBPHP_ASSERT(type.desc);
Message_GetPhpWrapper(php_val, type.desc, (upb_msg *)upb_val.msg_val,
arena);
break;
}
}
bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val,
upb_fieldtype_t type, const Descriptor *desc,
bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val, TypeInfo type,
upb_arena *arena) {
const upb_msgdef *subm = desc ? desc->msgdef : NULL;
const upb_msgdef *subm = type.desc ? type.desc->msgdef : NULL;
if (subm && upb_msgdef_iswrapper(subm) && Z_TYPE_P(val) != IS_OBJECT) {
// Assigning a scalar to a wrapper-typed value. We will automatically wrap
// the value, so the user doesn't need to create a FooWrapper(['value': X])
// message manually.
upb_msg *wrapper = upb_msg_new(subm, arena);
const upb_fielddef *val_f = upb_msgdef_itof(subm, 1);
upb_fieldtype_t type_f = upb_fielddef_type(val_f);
upb_msgval msgval;
if (!Convert_PhpToUpb(val, &msgval, type_f, NULL, arena)) return false;
if (!Convert_PhpToUpb(val, &msgval, TypeInfo_Get(val_f), arena)) return false;
upb_msg_set(wrapper, val_f, msgval, arena);
upb_val->msg_val = wrapper;
return true;
@ -495,7 +494,7 @@ bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val,
// ['foo_submsg': new Foo(['a' => 1])]
// not:
// ['foo_submsg': ['a' => 1]]
return Convert_PhpToUpb(val, upb_val, type, desc, arena);
return Convert_PhpToUpb(val, upb_val, type, arena);
}
}

@ -46,8 +46,8 @@ bool Convert_PhpToInt64(const zval *php_val, int64_t *i64);
// UPB_TYPE_MESSAGE, then |desc| must be the Descriptor for this message type.
// If type is string, message, or bytes, then |arena| will be used to copy
// string data or fuse this arena to the given message's arena.
bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, upb_fieldtype_t type,
const Descriptor *desc, upb_arena *arena);
bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, TypeInfo type,
upb_arena *arena);
// Similar to Convert_PhpToUpb, but supports automatically wrapping the wrapper
// types if a primitive is specified:
@ -56,16 +56,15 @@ bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, upb_fieldtype_t type,
//
// We currently allow this implicit conversion in initializers, but not for
// assignment.
bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val,
upb_fieldtype_t type, const Descriptor *desc,
bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val, TypeInfo type,
upb_arena *arena);
// Converts |upb_val| to a PHP zval according to |type|. This may involve
// creating a PHP wrapper object. If type == UPB_TYPE_MESSAGE, then |desc| must
// be the Descriptor for this message type. Any newly created wrapper object
// will reference |arena|.
void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, upb_fieldtype_t type,
const Descriptor *desc, zval *arena);
void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, TypeInfo type,
zval *arena);
// Registers the GPBUtil class.
void Convert_ModuleInit(void);

@ -72,4 +72,27 @@ Descriptor* Descriptor_GetFromClassEntry(zend_class_entry *ce);
Descriptor* Descriptor_GetFromMessageDef(const upb_msgdef *m);
Descriptor* Descriptor_GetFromFieldDef(const upb_fielddef *f);
// Packages up a upb_fieldtype_t with a Descriptor, since many functions need
// both.
typedef struct {
upb_fieldtype_t type;
const Descriptor *desc; // When type == UPB_TYPE_MESSAGE.
} TypeInfo;
static inline TypeInfo TypeInfo_Get(const upb_fielddef *f) {
TypeInfo ret = {upb_fielddef_type(f), Descriptor_GetFromFieldDef(f)};
return ret;
}
static inline TypeInfo TypeInfo_FromType(upb_fieldtype_t type) {
TypeInfo ret = {type};
return ret;
}
static inline bool TypeInfo_Eq(TypeInfo a, TypeInfo b) {
if (a.type != b.type) return false;
if (a.type == UPB_TYPE_MESSAGE && a.desc != b.desc) return false;
return true;
}
#endif // PHP_PROTOBUF_DEF_H_

@ -51,14 +51,31 @@ typedef struct {
zend_object std;
zval arena;
upb_map *map;
upb_fieldtype_t key_type;
upb_fieldtype_t val_type;
const Descriptor* desc; // When values are messages.
MapField_Type type;
} MapField;
zend_class_entry *MapField_class_entry;
static zend_object_handlers MapField_object_handlers;
static bool MapType_Eq(MapField_Type a, MapField_Type b) {
return a.key_type == b.key_type && TypeInfo_Eq(a.val_type, b.val_type);
}
static TypeInfo KeyType(MapField_Type type) {
TypeInfo ret = {type.key_type};
return ret;
}
MapField_Type MapType_Get(const upb_fielddef *f) {
const upb_msgdef *ent = upb_fielddef_msgsubdef(f);
const upb_fielddef *key_f = upb_msgdef_itof(ent, 1);
const upb_fielddef *val_f = upb_msgdef_itof(ent, 2);
MapField_Type type = {
upb_fielddef_type(key_f),
{upb_fielddef_type(val_f), Descriptor_GetFromFieldDef(val_f)}};
return type;
}
// PHP Object Handlers /////////////////////////////////////////////////////////
/**
@ -102,15 +119,36 @@ static void MapField_destructor(zend_object* obj) {
static int MapField_compare_objects(zval *map1, zval *map2) {
MapField* intern1 = (MapField*)Z_OBJ_P(map1);
MapField* intern2 = (MapField*)Z_OBJ_P(map2);
const upb_msgdef *m = intern1->desc ? intern1->desc->msgdef : NULL;
upb_fieldtype_t key_type = intern1->key_type;
upb_fieldtype_t val_type = intern1->val_type;
if (key_type != intern2->key_type) return 1;
if (val_type != intern2->val_type) return 1;
if (intern1->desc != intern2->desc) return 1;
return MapType_Eq(intern1->type, intern2->type) &&
MapEq(intern1->map, intern2->map, intern1->type)
? 0
: 1;
}
/**
* MapField_clone_obj()
*
* Object handler for cloning an object in PHP. Called when PHP code does:
*
* $map2 = clone $map1;
*/
static zend_object *MapField_clone_obj(PROTO_VAL *object) {
MapField* intern = PROTO_VAL_P(object);
upb_arena *arena = Arena_Get(&intern->arena);
upb_map *clone =
upb_map_new(arena, intern->type.key_type, intern->type.val_type.type);
size_t iter = UPB_MAP_BEGIN;
while (upb_mapiter_next(intern->map, &iter)) {
upb_msgval key = upb_mapiter_key(intern->map, iter);
upb_msgval val = upb_mapiter_value(intern->map, iter);
upb_map_set(clone, key, val, arena);
}
return MapEq(intern1->map, intern2->map, key_type, val_type, m) ? 0 : 1;
zval ret;
MapField_GetPhpWrapper(&ret, clone, intern->type, &intern->arena);
return Z_OBJ_P(&ret);
}
static zval *Map_GetPropertyPtrPtr(PROTO_VAL *object, PROTO_STR *member,
@ -126,7 +164,7 @@ static HashTable *Map_GetProperties(PROTO_VAL *object) {
// These are documented in the header file.
void MapField_GetPhpWrapper(zval *val, upb_map *map, const upb_fielddef *f,
void MapField_GetPhpWrapper(zval *val, upb_map *map, MapField_Type type,
zval *arena) {
if (!map) {
ZVAL_NULL(val);
@ -134,37 +172,25 @@ void MapField_GetPhpWrapper(zval *val, upb_map *map, const upb_fielddef *f,
}
if (!ObjCache_Get(map, val)) {
const upb_msgdef *ent = upb_fielddef_msgsubdef(f);
const upb_fielddef *key_f = upb_msgdef_itof(ent, 1);
const upb_fielddef *val_f = upb_msgdef_itof(ent, 2);
MapField *intern = emalloc(sizeof(MapField));
zend_object_std_init(&intern->std, MapField_class_entry);
intern->std.handlers = &MapField_object_handlers;
ZVAL_COPY(&intern->arena, arena);
intern->map = map;
intern->key_type = upb_fielddef_type(key_f);
intern->val_type = upb_fielddef_type(val_f);
intern->desc = Descriptor_GetFromFieldDef(val_f);
intern->type = type;
// Skip object_properties_init(), we don't allow derived classes.
ObjCache_Add(intern->map, &intern->std);
ZVAL_OBJ(val, &intern->std);
}
}
upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena) {
const upb_msgdef *ent = upb_fielddef_msgsubdef(f);
const upb_fielddef *key_f = upb_msgdef_itof(ent, 1);
const upb_fielddef *val_f = upb_msgdef_itof(ent, 2);
upb_fieldtype_t key_type = upb_fielddef_type(key_f);
upb_fieldtype_t val_type = upb_fielddef_type(val_f);
const Descriptor *desc = Descriptor_GetFromFieldDef(val_f);
upb_map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_arena *arena) {
if (Z_ISREF_P(val)) {
ZVAL_DEREF(val);
}
if (Z_TYPE_P(val) == IS_ARRAY) {
upb_map *map = upb_map_new(arena, key_type, val_type);
upb_map *map = upb_map_new(arena, type.key_type, type.val_type.type);
HashTable *table = HASH_OF(val);
HashPosition pos;
@ -181,8 +207,8 @@ upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena)
if (!php_val) return map;
if (!Convert_PhpToUpb(&php_key, &upb_key, key_type, NULL, arena) ||
!Convert_PhpToUpbAutoWrap(php_val, &upb_val, val_type, desc, arena)) {
if (!Convert_PhpToUpb(&php_key, &upb_key, KeyType(type), arena) ||
!Convert_PhpToUpbAutoWrap(php_val, &upb_val, type.val_type, arena)) {
return NULL;
}
@ -194,8 +220,7 @@ upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena)
Z_OBJCE_P(val) == MapField_class_entry) {
MapField *intern = (MapField*)Z_OBJ_P(val);
if (intern->key_type != key_type || intern->val_type != val_type ||
intern->desc != desc) {
if (!MapType_Eq(intern->type, type)) {
php_error_docref(NULL, E_USER_ERROR, "Wrong type for this map field.");
return NULL;
}
@ -208,8 +233,7 @@ upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena)
}
}
bool MapEq(const upb_map *m1, const upb_map *m2, upb_fieldtype_t key_type,
upb_fieldtype_t val_type, const upb_msgdef *m) {
bool MapEq(const upb_map *m1, const upb_map *m2, MapField_Type type) {
size_t iter = UPB_MAP_BEGIN;
if ((m1 == NULL) != (m2 == NULL)) return false;
@ -222,7 +246,7 @@ bool MapEq(const upb_map *m1, const upb_map *m2, upb_fieldtype_t key_type,
upb_msgval val2;
if (!upb_map_get(m2, key, &val2)) return false;
if (!ValueEq(val1, val2, val_type, m)) return false;
if (!ValueEq(val1, val2, type.val_type)) return false;
}
return true;
@ -250,12 +274,12 @@ PHP_METHOD(MapField, __construct) {
return;
}
intern->key_type = pbphp_dtype_to_type(key_type);
intern->val_type = pbphp_dtype_to_type(val_type);
intern->desc = Descriptor_GetFromClassEntry(klass);
intern->type.key_type = pbphp_dtype_to_type(key_type);
intern->type.val_type.type = pbphp_dtype_to_type(val_type);
intern->type.val_type.desc = Descriptor_GetFromClassEntry(klass);
// Check that the key type is an allowed type.
switch (intern->key_type) {
switch (intern->type.key_type) {
case UPB_TYPE_INT32:
case UPB_TYPE_INT64:
case UPB_TYPE_UINT32:
@ -269,13 +293,14 @@ PHP_METHOD(MapField, __construct) {
zend_error(E_USER_ERROR, "Invalid key type for map.");
}
if (intern->val_type == UPB_TYPE_MESSAGE && klass == NULL) {
if (intern->type.val_type.type == UPB_TYPE_MESSAGE && klass == NULL) {
php_error_docref(NULL, E_USER_ERROR,
"Message/enum type must have concrete class.");
return;
}
intern->map = upb_map_new(arena, intern->key_type, intern->val_type);
intern->map =
upb_map_new(arena, intern->type.key_type, intern->type.val_type.type);
ObjCache_Add(intern->map, &intern->std);
}
@ -296,7 +321,7 @@ PHP_METHOD(MapField, offsetExists) {
upb_msgval upb_key;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS ||
!Convert_PhpToUpb(key, &upb_key, intern->key_type, intern->desc, NULL)) {
!Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL)) {
return;
}
@ -322,7 +347,7 @@ PHP_METHOD(MapField, offsetGet) {
upb_msgval upb_key, upb_val;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS ||
!Convert_PhpToUpb(key, &upb_key, intern->key_type, intern->desc, NULL)) {
!Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL)) {
return;
}
@ -331,7 +356,7 @@ PHP_METHOD(MapField, offsetGet) {
return;
}
Convert_UpbToPhp(upb_val, &ret, intern->val_type, intern->desc, &intern->arena);
Convert_UpbToPhp(upb_val, &ret, intern->type.val_type, &intern->arena);
RETURN_ZVAL(&ret, 0, 1);
}
@ -355,8 +380,8 @@ PHP_METHOD(MapField, offsetSet) {
upb_msgval upb_key, upb_val;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &key, &val) != SUCCESS ||
!Convert_PhpToUpb(key, &upb_key, intern->key_type, NULL, NULL) ||
!Convert_PhpToUpb(val, &upb_val, intern->val_type, intern->desc, arena)) {
!Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL) ||
!Convert_PhpToUpb(val, &upb_val, intern->type.val_type, arena)) {
return;
}
@ -380,7 +405,7 @@ PHP_METHOD(MapField, offsetUnset) {
upb_msgval upb_key;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS ||
!Convert_PhpToUpb(key, &upb_key, intern->key_type, NULL, NULL)) {
!Convert_PhpToUpb(key, &upb_key, KeyType(intern->type), NULL)) {
return;
}
@ -543,7 +568,7 @@ PHP_METHOD(MapFieldIter, current) {
MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
upb_msgval upb_val = upb_mapiter_value(field->map, intern->position);
zval ret;
Convert_UpbToPhp(upb_val, &ret, field->val_type, field->desc, &field->arena);
Convert_UpbToPhp(upb_val, &ret, field->type.val_type, &field->arena);
RETURN_ZVAL(&ret, 0, 1);
}
@ -557,7 +582,7 @@ PHP_METHOD(MapFieldIter, key) {
MapField *field = (MapField*)Z_OBJ_P(&intern->map_field);
upb_msgval upb_key = upb_mapiter_key(field->map, intern->position);
zval ret;
Convert_UpbToPhp(upb_key, &ret, field->key_type, NULL, NULL);
Convert_UpbToPhp(upb_key, &ret, KeyType(field->type), NULL);
RETURN_ZVAL(&ret, 0, 1);
}
@ -624,6 +649,7 @@ void Map_ModuleInit() {
#else
h->compare = MapField_compare_objects;
#endif
h->clone_obj = MapField_clone_obj;
h->get_properties = Map_GetProperties;
h->get_property_ptr_ptr = Map_GetPropertyPtrPtr;

@ -33,10 +33,18 @@
#include <php.h>
#include "def.h"
#include "php-upb.h"
void Map_ModuleInit();
typedef struct {
upb_fieldtype_t key_type;
TypeInfo val_type;
} MapField_Type;
MapField_Type MapType_Get(const upb_fielddef *f);
// Gets a upb_map* for the PHP object |val|:
// * If |val| is a RepeatedField object, we first check its type and verify
// that that the elements have the correct type for |f|. If so, we return the
@ -47,17 +55,16 @@ void Map_ModuleInit();
// |arena| and add all of the PHP elements to it.
//
// If an error occurs, we raise a PHP error and return NULL.
upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena);
upb_map *MapField_GetUpbMap(zval *val, MapField_Type type, upb_arena *arena);
// Creates a PHP MapField object for the given upb_map* and |f| and returns it
// in |val|. The PHP object will keep a reference to this |arena| to ensure the
// underlying array data stays alive.
//
// If |map| is NULL, this will return a PHP null object.
void MapField_GetPhpWrapper(zval *val, upb_map *arr, const upb_fielddef *f,
void MapField_GetPhpWrapper(zval *val, upb_map *arr, MapField_Type type,
zval *arena);
bool MapEq(const upb_map *m1, const upb_map *m2, upb_fieldtype_t key_type,
upb_fieldtype_t val_type, const upb_msgdef *m);
bool MapEq(const upb_map *m1, const upb_map *m2, MapField_Type type);
#endif // PHP_PROTOBUF_MAP_H_

@ -60,6 +60,21 @@ typedef struct {
zend_class_entry *message_ce;
static zend_object_handlers message_object_handlers;
static void Message_SuppressDefaultProperties(zend_class_entry *class_type) {
// We suppress all default properties, because all our properties are handled
// by our read_property handler.
//
// This also allows us to put our zend_object member at the beginning of our
// struct -- instead of putting it at the end with pointer fixups to access
// our own data, as recommended in the docs -- because Zend won't add any of
// its own storage directly after the zend_object if default_properties_count
// == 0.
//
// This is not officially supported, but since it simplifies the code, we'll
// do it for as long as it works in practice.
class_type->default_properties_count = 0;
}
// PHP Object Handlers /////////////////////////////////////////////////////////
/**
@ -69,8 +84,7 @@ static zend_object_handlers message_object_handlers;
*/
static zend_object* Message_create(zend_class_entry *class_type) {
Message *intern = emalloc(sizeof(Message));
// XXX(haberman): verify whether we actually want to take this route.
class_type->default_properties_count = 0;
Message_SuppressDefaultProperties(class_type);
zend_object_std_init(&intern->std, class_type);
intern->std.handlers = &message_object_handlers;
Arena_Init(&intern->arena);
@ -114,14 +128,14 @@ static void Message_get(Message *intern, const upb_fielddef *f, zval *rv) {
if (upb_fielddef_ismap(f)) {
upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena);
MapField_GetPhpWrapper(rv, msgval.map, f, &intern->arena);
MapField_GetPhpWrapper(rv, msgval.map, MapType_Get(f), &intern->arena);
} else if (upb_fielddef_isseq(f)) {
upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena);
RepeatedField_GetPhpWrapper(rv, msgval.array, f, &intern->arena);
RepeatedField_GetPhpWrapper(rv, msgval.array, TypeInfo_Get(f),
&intern->arena);
} else {
upb_msgval msgval = upb_msg_get(intern->msg, f);
const Descriptor *subdesc = Descriptor_GetFromFieldDef(f);
Convert_UpbToPhp(msgval, rv, upb_fielddef_type(f), subdesc, &intern->arena);
Convert_UpbToPhp(msgval, rv, TypeInfo_Get(f), &intern->arena);
}
}
@ -130,16 +144,13 @@ static bool Message_set(Message *intern, const upb_fielddef *f, zval *val) {
upb_msgval msgval;
if (upb_fielddef_ismap(f)) {
msgval.map_val = MapField_GetUpbMap(val, f, arena);
msgval.map_val = MapField_GetUpbMap(val, MapType_Get(f), arena);
if (!msgval.map_val) return false;
} else if (upb_fielddef_isseq(f)) {
msgval.array_val = RepeatedField_GetUpbArray(val, f, arena);
msgval.array_val = RepeatedField_GetUpbArray(val, TypeInfo_Get(f), arena);
if (!msgval.array_val) return false;
} else {
upb_fieldtype_t type = upb_fielddef_type(f);
const Descriptor *subdesc = Descriptor_GetFromFieldDef(f);
bool ok = Convert_PhpToUpb(val, &msgval, type, subdesc, arena);
if (!ok) return false;
if (!Convert_PhpToUpb(val, &msgval, TypeInfo_Get(f), arena)) return false;
}
upb_msg_set(intern->msg, f, msgval, arena);
@ -149,11 +160,10 @@ static bool Message_set(Message *intern, const upb_fielddef *f, zval *val) {
static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m);
/**
* ValueEq()()
* ValueEq()
*/
bool ValueEq(upb_msgval val1, upb_msgval val2, upb_fieldtype_t type,
const upb_msgdef *m) {
switch (type) {
bool ValueEq(upb_msgval val1, upb_msgval val2, TypeInfo type) {
switch (type.type) {
case UPB_TYPE_BOOL:
return val1.bool_val == val2.bool_val;
case UPB_TYPE_INT32:
@ -172,7 +182,7 @@ bool ValueEq(upb_msgval val1, upb_msgval val2, upb_fieldtype_t type,
return val1.str_val.size == val2.str_val.size &&
memcmp(val1.str_val.data, val2.str_val.data, val1.str_val.size) == 0;
case UPB_TYPE_MESSAGE:
return MessageEq(val1.msg_val, val2.msg_val, m);
return MessageEq(val1.msg_val, val2.msg_val, type.desc->msgdef);
default:
return false;
}
@ -190,8 +200,6 @@ static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m)
const upb_fielddef *f = upb_msg_iter_field(&i);
upb_msgval val1 = upb_msg_get(m1, f);
upb_msgval val2 = upb_msg_get(m2, f);
upb_fieldtype_t type = upb_fielddef_type(f);
const upb_msgdef *sub_m = upb_fielddef_msgsubdef(f);
if (upb_fielddef_haspresence(f)) {
if (upb_msg_has(m1, f) != upb_msg_has(m2, f)) {
@ -201,18 +209,11 @@ static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m)
}
if (upb_fielddef_ismap(f)) {
const upb_fielddef *key_f = upb_msgdef_itof(sub_m, 1);
const upb_fielddef *val_f = upb_msgdef_itof(sub_m, 2);
upb_fieldtype_t key_type = upb_fielddef_type(key_f);
upb_fieldtype_t val_type = upb_fielddef_type(val_f);
const upb_msgdef *val_m = upb_fielddef_msgsubdef(val_f);
if (!MapEq(val1.map_val, val2.map_val, key_type, val_type, val_m)) {
return false;
}
if (!MapEq(val1.map_val, val2.map_val, MapType_Get(f))) return false;
} else if (upb_fielddef_isseq(f)) {
if (!ArrayEq(val1.array_val, val2.array_val, type, sub_m)) return false;
if (!ArrayEq(val1.array_val, val2.array_val, TypeInfo_Get(f))) return false;
} else {
if (!ValueEq(val1, val2, type, sub_m)) return false;
if (!ValueEq(val1, val2, TypeInfo_Get(f))) return false;
}
}
@ -258,7 +259,7 @@ static int Message_compare_objects(zval *m1, zval *m2) {
static int Message_has_property(PROTO_VAL *obj, PROTO_STR *member,
int has_set_exists,
void **cache_slot) {
Message* intern = PROTO_MSG_P(obj);
Message* intern = PROTO_VAL_P(obj);
const upb_fielddef *f = get_field(intern, member);
if (!f) return 0;
@ -293,7 +294,7 @@ static int Message_has_property(PROTO_VAL *obj, PROTO_STR *member,
*/
static void Message_unset_property(PROTO_VAL *obj, PROTO_STR *member,
void **cache_slot) {
Message* intern = PROTO_MSG_P(obj);
Message* intern = PROTO_VAL_P(obj);
const upb_fielddef *f = get_field(intern, member);
if (!f) return;
@ -330,7 +331,7 @@ static void Message_unset_property(PROTO_VAL *obj, PROTO_STR *member,
*/
static zval *Message_read_property(PROTO_VAL *obj, PROTO_STR *member,
int type, void **cache_slot, zval *rv) {
Message* intern = PROTO_MSG_P(obj);
Message* intern = PROTO_VAL_P(obj);
const upb_fielddef *f = get_field(intern, member);
if (!f) return NULL;
@ -361,7 +362,7 @@ static zval *Message_read_property(PROTO_VAL *obj, PROTO_STR *member,
*/
static PROTO_RETURN_VAL Message_write_property(
PROTO_VAL *obj, PROTO_STR *member, zval *val, void **cache_slot) {
Message* intern = PROTO_MSG_P(obj);
Message* intern = PROTO_VAL_P(obj);
const upb_fielddef *f = get_field(intern, member);
if (f && Message_set(intern, f, val)) {
@ -392,6 +393,25 @@ static zval *Message_get_property_ptr_ptr(PROTO_VAL *object, PROTO_STR *member,
return NULL; // We do not have a properties table.
}
/**
* Message_clone_obj()
*
* Object handler for cloning an object in PHP. Called when PHP code does:
*
* $msg2 = clone $msg;
*/
static zend_object *Message_clone_obj(PROTO_VAL *object) {
Message* intern = PROTO_VAL_P(object);
upb_msg *clone = upb_msg_new(intern->desc->msgdef, Arena_Get(&intern->arena));
// TODO: copy unknown fields?
// TODO: use official upb msg copy function
memcpy(clone, intern->msg, upb_msgdef_layout(intern->desc->msgdef)->size);
zval ret;
Message_GetPhpWrapper(&ret, intern->desc, clone, &intern->arena);
return Z_OBJ_P(&ret);
}
/**
* Message_get_properties()
*
@ -415,8 +435,7 @@ void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg,
if (!ObjCache_Get(msg, val)) {
Message *intern = emalloc(sizeof(Message));
// XXX(haberman): verify whether we actually want to take this route.
desc->class_entry->default_properties_count = 0;
Message_SuppressDefaultProperties(desc->class_entry);
zend_object_std_init(&intern->std, desc->class_entry);
intern->std.handlers = &message_object_handlers;
ZVAL_COPY(&intern->arena, arena);
@ -521,15 +540,13 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init,
}
if (upb_fielddef_ismap(f)) {
msgval.map_val = MapField_GetUpbMap(val, f, arena);
msgval.map_val = MapField_GetUpbMap(val, MapType_Get(f), arena);
if (!msgval.map_val) return false;
} else if (upb_fielddef_isseq(f)) {
msgval.array_val = RepeatedField_GetUpbArray(val, f, arena);
msgval.array_val = RepeatedField_GetUpbArray(val, TypeInfo_Get(f), arena);
if (!msgval.array_val) return false;
} else {
const Descriptor *desc = Descriptor_GetFromFieldDef(f);
upb_fieldtype_t type = upb_fielddef_type(f);
if (!Convert_PhpToUpbAutoWrap(val, &msgval, type, desc, arena)) {
if (!Convert_PhpToUpbAutoWrap(val, &msgval, TypeInfo_Get(f), arena)) {
return false;
}
}
@ -554,10 +571,32 @@ static void Message_Initialize(Message *intern, const Descriptor *desc) {
*/
PHP_METHOD(Message, __construct) {
Message* intern = (Message*)Z_OBJ_P(getThis());
const Descriptor* desc = Descriptor_GetFromClassEntry(Z_OBJCE_P(getThis()));
const Descriptor* desc;
zend_class_entry *ce = Z_OBJCE_P(getThis());
upb_arena *arena = Arena_Get(&intern->arena);
zval *init_arr = NULL;
// This descriptor should always be available, as the generated __construct
// method calls initOnce() to load the descriptor prior to calling us.
//
// However, if the user created their own class derived from Message, this
// will trigger an infinite construction loop and blow the stack. We
// temporarily clear create_object to break this loop (see check in
// NameMap_GetMessage()).
PBPHP_ASSERT(ce->create_object == Message_create);
ce->create_object = NULL;
desc = Descriptor_GetFromClassEntry(ce);
ce->create_object = Message_create;
if (!desc) {
zend_throw_exception_ex(
NULL, 0,
"Couldn't find descriptor. Note only generated code may derive from "
"\\Google\\Protobuf\\Internal\\Message");
return;
}
Message_Initialize(intern, desc);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &init_arr) == FAILURE) {
@ -805,10 +844,9 @@ PHP_METHOD(Message, readWrapperValue) {
const upb_msg *wrapper = upb_msg_get(intern->msg, f).msg_val;
const upb_msgdef *m = upb_fielddef_msgsubdef(f);
const upb_fielddef *val_f = upb_msgdef_itof(m, 1);
const upb_fieldtype_t val_type = upb_fielddef_type(val_f);
upb_msgval msgval = upb_msg_get(wrapper, val_f);
zval ret;
Convert_UpbToPhp(msgval, &ret, val_type, NULL, &intern->arena);
Convert_UpbToPhp(msgval, &ret, TypeInfo_Get(val_f), &intern->arena);
RETURN_ZVAL(&ret, 1, 0);
} else {
RETURN_NULL();
@ -861,10 +899,9 @@ PHP_METHOD(Message, writeWrapperValue) {
} else {
const upb_msgdef *m = upb_fielddef_msgsubdef(f);
const upb_fielddef *val_f = upb_msgdef_itof(m, 1);
upb_fieldtype_t val_type = upb_fielddef_type(val_f);
upb_msg *wrapper;
if (!Convert_PhpToUpb(val, &msgval, val_type, NULL, arena)) {
if (!Convert_PhpToUpb(val, &msgval, TypeInfo_Get(val_f), arena)) {
return; // Error is already set.
}
@ -974,9 +1011,7 @@ PHP_METHOD(Message, readOneof) {
{
upb_msgval msgval = upb_msg_get(intern->msg, f);
const Descriptor *subdesc = Descriptor_GetFromFieldDef(f);
Convert_UpbToPhp(msgval, &ret, upb_fielddef_type(f), subdesc,
&intern->arena);
Convert_UpbToPhp(msgval, &ret, TypeInfo_Get(f), &intern->arena);
}
RETURN_ZVAL(&ret, 1, 0);
@ -1017,8 +1052,7 @@ PHP_METHOD(Message, writeOneof) {
f = upb_msgdef_itof(intern->desc->msgdef, field_num);
if (!Convert_PhpToUpb(val, &msgval, upb_fielddef_type(f),
Descriptor_GetFromFieldDef(f), arena)) {
if (!Convert_PhpToUpb(val, &msgval, TypeInfo_Get(f), arena)) {
return;
}
@ -1225,8 +1259,8 @@ PHP_METHOD(google_protobuf_Timestamp, fromDateTime) {
if (call_user_function(EG(function_table), NULL, &function_name, &retval, 1,
datetime) == FAILURE ||
!Convert_PhpToUpb(&retval, &timestamp_seconds, UPB_TYPE_INT64, NULL,
NULL)) {
!Convert_PhpToUpb(&retval, &timestamp_seconds,
TypeInfo_FromType(UPB_TYPE_INT64), NULL)) {
zend_error(E_ERROR, "Cannot get timestamp from DateTime.");
return;
}
@ -1251,8 +1285,8 @@ PHP_METHOD(google_protobuf_Timestamp, fromDateTime) {
if (call_user_function(EG(function_table), NULL, &function_name, &retval, 2,
params) == FAILURE ||
!Convert_PhpToUpb(&retval, &timestamp_nanos, UPB_TYPE_INT32, NULL,
NULL)) {
!Convert_PhpToUpb(&retval, &timestamp_nanos,
TypeInfo_FromType(UPB_TYPE_INT32), NULL)) {
zend_error(E_ERROR, "Cannot format DateTime.");
return;
}
@ -1338,6 +1372,7 @@ void Message_ModuleInit() {
h->unset_property = Message_unset_property;
h->get_properties = Message_get_properties;
h->get_property_ptr_ptr = Message_get_property_ptr_ptr;
h->clone_obj = Message_clone_obj;
WellKnownTypes_ModuleInit(); /* From wkt.inc. */
}

@ -56,7 +56,6 @@ bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena,
void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg,
zval *arena);
bool ValueEq(upb_msgval val1, upb_msgval val2, upb_fieldtype_t type,
const upb_msgdef *m);
bool ValueEq(upb_msgval val1, upb_msgval val2, TypeInfo type);
#endif // PHP_PROTOBUF_MESSAGE_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -58,13 +58,13 @@ const zval *get_generated_pool();
#if PHP_VERSION_ID < 80000
#define PROTO_VAL zval
#define PROTO_STR zval
#define PROTO_MSG_P(obj) (Message*)Z_OBJ_P(obj)
#define PROTO_VAL_P(obj) Z_OBJ_P(obj)
#define PROTO_STRVAL_P(obj) Z_STRVAL_P(obj)
#define PROTO_STRLEN_P(obj) Z_STRLEN_P(obj)
#else
#define PROTO_VAL zend_object
#define PROTO_STR zend_string
#define PROTO_MSG_P(obj) (Message*)(obj)
#define PROTO_VAL_P(obj) (void*)(obj)
#define PROTO_STRVAL_P(obj) ZSTR_VAL(obj)
#define PROTO_STRLEN_P(obj) ZSTR_LEN(obj)
#endif

@ -49,6 +49,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message
* This option does nothing.
*
* Generated from protobuf field <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
* @deprecated
*/
protected $java_generate_equals_and_hash = null;
/**
@ -412,19 +413,23 @@ class FileOptions extends \Google\Protobuf\Internal\Message
*
* Generated from protobuf field <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
* @return bool
* @deprecated
*/
public function getJavaGenerateEqualsAndHash()
{
@trigger_error('java_generate_equals_and_hash is deprecated.', E_USER_DEPRECATED);
return isset($this->java_generate_equals_and_hash) ? $this->java_generate_equals_and_hash : false;
}
public function hasJavaGenerateEqualsAndHash()
{
@trigger_error('java_generate_equals_and_hash is deprecated.', E_USER_DEPRECATED);
return isset($this->java_generate_equals_and_hash);
}
public function clearJavaGenerateEqualsAndHash()
{
@trigger_error('java_generate_equals_and_hash is deprecated.', E_USER_DEPRECATED);
unset($this->java_generate_equals_and_hash);
}
@ -434,9 +439,11 @@ class FileOptions extends \Google\Protobuf\Internal\Message
* Generated from protobuf field <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
* @param bool $var
* @return $this
* @deprecated
*/
public function setJavaGenerateEqualsAndHash($var)
{
@trigger_error('java_generate_equals_and_hash is deprecated.', E_USER_DEPRECATED);
GPBUtil::checkBool($var);
$this->java_generate_equals_and_hash = $var;

@ -50,8 +50,8 @@ class GPBWire
public static function getTagFieldNumber($tag)
{
return ($tag >> self::TAG_TYPE_BITS) &
(1 << ((PHP_INT_SIZE * 8) - self::TAG_TYPE_BITS)) - 1;
// We have to mask because PHP has no arithmetic shift.
return ($tag >> self::TAG_TYPE_BITS) & 0x1fffffff;
}
public static function getTagWireType($tag)

@ -93,8 +93,9 @@ class Message
$pool = DescriptorPool::getGeneratedPool();
$this->desc = $pool->getDescriptorByClassName(get_class($this));
if (is_null($this->desc)) {
user_error(get_class($this) . " is not found in descriptor pool.");
return;
throw new \InvalidArgumentException(
get_class($this) ." is not found in descriptor pool. " .
'Only generated classes may derive from Message.');
}
foreach ($this->desc->getField() as $field) {
$setter = $field->getSetter();

@ -624,4 +624,16 @@ class ArrayTest extends TestBase
new RepeatedField(GPBType::MESSAGE, TestMessage::class) ==
new RepeatedField(GPBType::MESSAGE, Sub::class));
}
#########################################################
# Test clone
#########################################################
public function testClone()
{
$arr = new RepeatedField(GPBType::MESSAGE, TestMessage::class);
$arr[] = new TestMessage;
$arr2 = clone $arr;
$this->assertSame($arr[0], $arr2[0]);
}
}

@ -14,6 +14,7 @@ use Foo\TestStringValue;
use Foo\TestBytesValue;
use Foo\TestAny;
use Foo\TestEnum;
use Foo\TestLargeFieldNumber;
use Foo\TestMessage;
use Foo\TestMessage\Sub;
use Foo\TestPackedMessage;
@ -529,6 +530,15 @@ class EncodeDecodeTest extends TestBase
$this->assertSame("", $data);
}
public function testLargeFieldNumber()
{
$m = new TestLargeFieldNumber(['large_field_number' => 5]);
$data = $m->serializeToString();
$m2 = new TestLargeFieldNumber();
$m2->mergeFromString($data);
$this->assertSame(5, $m2->getLargeFieldNumber());
}
public function testDecodeInvalidInt32()
{
$this->expectException(Exception::class);

@ -24,6 +24,13 @@ use Foo\testLowerCaseEnum;
use PBEmpty\PBEcho\TestEmptyPackage;
use Php\Test\TestNamespace;
# This is not allowed, but we at least shouldn't crash.
class C extends \Google\Protobuf\Internal\Message {
public function __construct($data = null) {
parent::__construct($data);
}
}
class GeneratedClassTest extends TestBase
{
@ -71,6 +78,33 @@ class GeneratedClassTest extends TestBase
$this->assertSame(MIN_INT32, $m->getOptionalInt32());
}
#########################################################
# Test deprecated int32 field.
#########################################################
public function testDeprecatedInt32Field()
{
$m = new TestMessage();
// temporarily change error handler to capture the deprecated errors
$deprecationCount = 0;
set_error_handler(function ($errno, $errstr) use (&$deprecationCount) {
if ($errstr === 'deprecated_optional_int32 is deprecated.') {
$deprecationCount++;
}
}, E_USER_DEPRECATED);
// default test set
$m->setDeprecatedOptionalInt32(MAX_INT32);
$this->assertSame(MAX_INT32, $m->getDeprecatedOptionalInt32());
$m->setDeprecatedOptionalInt32(MIN_INT32);
$this->assertSame(MIN_INT32, $m->getDeprecatedOptionalInt32());
restore_error_handler();
$this->assertSame(4, $deprecationCount);
}
#########################################################
# Test optional int32 field.
#########################################################
@ -1491,6 +1525,28 @@ class GeneratedClassTest extends TestBase
$this->assertTrue(true);
}
#########################################################
# Test clone.
#########################################################
public function testClone()
{
$m = new TestMessage([
'optional_int32' => -42,
'optional_int64' => -43,
'optional_message' => new Sub([
'a' => 33
]),
'map_int32_message' => [1 => new Sub(['a' => 36])],
]);
$m2 = clone $m;
$this->assertEquals($m->getOptionalInt32(), $m2->getOptionalInt32());
$this->assertEquals($m->getOptionalInt64(), $m2->getOptionalInt64());
$this->assertSame($m->getOptionalMessage(), $m2->getOptionalMessage());
$this->assertSame($m->getMapInt32Message()[1], $m2->getMapInt32Message()[1]);
$this->assertEquals($m->serializeToJsonString(), $m2->serializeToJsonString());
}
#########################################################
# Test message equals.
#########################################################
@ -1696,6 +1752,16 @@ class GeneratedClassTest extends TestBase
$this->assertFalse($m->hasOneofString());
}
#########################################################
# Test that we don't crash if users create their own messages.
#########################################################
public function testUserDefinedClass() {
# This is not allowed, but at least we shouldn't crash.
$this->expectException(Exception::class);
$p = new C();
}
#########################################################
# Test no segfault when error happens
#########################################################

@ -340,6 +340,13 @@ class GeneratedPhpdocTest extends TestBase
],
'@param \NoNamespaceMessage $var'
],
[
[
'setDeprecatedOptionalInt32',
'getDeprecatedOptionalInt32',
],
'@deprecated'
],
];
}
}

@ -511,6 +511,24 @@ class MapFieldTest extends TestBase {
new MapField(GPBType::INT32, GPBType::MESSAGE, Sub::class));
}
#########################################################
# Test clone
#########################################################
public function testClone()
{
$map = new MapField(GPBType::INT32,
GPBType::MESSAGE, Sub::class);
// Test append.
$sub_m = new Sub();
$sub_m->setA(1);
$map[0] = $sub_m;
$map2 = clone $map;
$this->assertSame($map[0], $map2[0]);
}
#########################################################
# Test memory leak
#########################################################

@ -147,6 +147,9 @@ message TestMessage {
map<string, google.protobuf.Any> map_string_any = 122;
map<string, google.protobuf.ListValue> map_string_list = 123;
map<string, google.protobuf.Struct> map_string_struct = 124;
// deprecated field
int32 deprecated_optional_int32 = 125 [deprecated=true];
}
enum TestEnum {
@ -220,6 +223,10 @@ message TestRandomFieldOrder {
string tag14 = 160;
}
message TestLargeFieldNumber {
int32 large_field_number = 536870911;
}
message TestReverseFieldOrder {
repeated int32 a = 2;
string b = 1;

@ -1,6 +0,0 @@
FROM quay.io/pypa/manylinux1_x86_64
RUN yum install -y libtool
RUN /opt/python/cp27-cp27mu/bin/pip install twine
COPY protobuf_optimized_pip.sh /

@ -1,17 +0,0 @@
Description
------------------------------
This directory is used to build released wheels according to PEP513 and upload
them to pypi.
Usage
------------------------------
For example, to release 3.3.0:
./protobuf_optimized_pip.sh 3.3.0 PYPI_USERNAME PYPI_PASSWORD
Structure
------------------------------
| Source | Source |
|--------------------------------------|---------------------------------------------------|
| protobuf_optimized_pip.sh | Entry point. Calling Dockerfile and build_wheel_manylinux.sh |
| Dockerfile | Build docker image according to PEP513. |
| build_wheel_manylinux.sh | Build wheel packages in the docker container. |

@ -1,27 +0,0 @@
#!/bin/bash
# Print usage and fail.
function usage() {
echo "Usage: protobuf_optimized_pip.sh PROTOBUF_VERSION PYPI_USERNAME PYPI_PASSWORD" >&2
exit 1 # Causes caller to exit because we use -e.
}
# Validate arguments.
if [ $0 != ./build_wheel_manylinux.sh ]; then
echo "Please run this script from the directory in which it is located." >&2
exit 1
fi
if [ $# -lt 3 ]; then
usage
exit 1
fi
PROTOBUF_VERSION=$1
PYPI_USERNAME=$2
PYPI_PASSWORD=$3
docker rmi protobuf-python-wheel
docker build . -t protobuf-python-wheel
docker run --rm protobuf-python-wheel ./protobuf_optimized_pip.sh $PROTOBUF_VERSION $PYPI_USERNAME $PYPI_PASSWORD
docker rmi protobuf-python-wheel

@ -1,66 +0,0 @@
#!/usr/bin/env bash
# DO NOT use this script manually! Called by docker.
set -ex
# Print usage and fail.
function usage() {
echo "Usage: protobuf_optimized_pip.sh PROTOBUF_VERSION" >&2
exit 1 # Causes caller to exit because we use -e.
}
# Build wheel
function build_wheel() {
PYTHON_VERSION=$1
PYTHON_BIN=/opt/python/${PYTHON_VERSION}/bin/python
$PYTHON_BIN setup.py bdist_wheel --cpp_implementation --compile_static_extension
auditwheel repair dist/protobuf-${PROTOBUF_VERSION}-${PYTHON_VERSION}-linux_x86_64.whl
}
# Validate arguments.
if [ $0 != ./protobuf_optimized_pip.sh ]; then
echo "Please run this script from the directory in which it is located." >&2
exit 1
fi
if [ $# -lt 1 ]; then
usage
exit 1
fi
PROTOBUF_VERSION=$1
PYPI_USERNAME=$2
PYPI_PASSWORD=$3
DIR=${PWD}/'protobuf-python-build'
PYTHON_VERSIONS=('cp27-cp27mu' 'cp33-cp33m' 'cp34-cp34m' 'cp35-cp35m' 'cp36-cp36m')
mkdir -p ${DIR}
cd ${DIR}
curl -SsL -O https://github.com/protocolbuffers/protobuf/archive/v${PROTOBUF_VERSION}.tar.gz
tar xzf v${PROTOBUF_VERSION}.tar.gz
cd $DIR/protobuf-${PROTOBUF_VERSION}
# Autoconf on centos 5.11 cannot recognize AC_PROG_OBJC.
sed -i '/AC_PROG_OBJC/d' configure.ac
sed -i 's/conformance\/Makefile//g' configure.ac
# Use the /usr/bin/autoconf and related tools to pick the correct aclocal macros
export PATH="/usr/bin:$PATH"
# Build protoc
./autogen.sh
CXXFLAGS="-fPIC -g -O2" ./configure
make -j8
export PROTOC=$DIR/src/protoc
cd python
for PYTHON_VERSION in "${PYTHON_VERSIONS[@]}"
do
build_wheel $PYTHON_VERSION
done
/opt/python/cp27-cp27mu/bin/twine upload wheelhouse/*

@ -207,7 +207,7 @@ if __name__ == '__main__':
# C++ projects must now migrate to libc++ and are recommended to set a
# deployment target of macOS 10.9 or later, or iOS 7 or later.
if sys.platform == 'darwin':
mac_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
mac_target = str(sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET'))
if mac_target and (pkg_resources.parse_version(mac_target) <
pkg_resources.parse_version('10.9.0')):
os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.9'
@ -254,7 +254,7 @@ if __name__ == '__main__':
os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
# Keep this list of dependencies in sync with tox.ini.
install_requires = ['six>=1.9', 'setuptools']
install_requires = ['six>=1.9']
if sys.version_info <= (2,7):
install_requires.append('ordereddict')
install_requires.append('unittest2')

@ -1,6 +1,6 @@
[tox]
envlist =
py{27,33,34,35,36}-{cpp,python}
py{27,33,34,35,36,37,38,39}-{cpp,python}
[testenv]
usedevelop=true

@ -7793,7 +7793,8 @@ static void jsondec_timestamp(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
{
/* [+-]08:00 or Z */
int ofs = 0;
int ofs_hour = 0;
int ofs_min = 0;
bool neg = false;
if (ptr == end) goto malformed;
@ -7804,9 +7805,10 @@ static void jsondec_timestamp(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
/* fallthrough */
case '+':
if ((end - ptr) != 5) goto malformed;
ofs = jsondec_tsdigits(d, &ptr, 2, ":00");
ofs *= 60 * 60;
seconds.int64_val += (neg ? ofs : -ofs);
ofs_hour = jsondec_tsdigits(d, &ptr, 2, ":");
ofs_min = jsondec_tsdigits(d, &ptr, 2, NULL);
ofs_min = ((ofs_hour * 60) + ofs_min) * 60;
seconds.int64_val += (neg ? ofs_min : -ofs_min);
break;
case 'Z':
if (ptr != end) goto malformed;

@ -4161,7 +4161,6 @@ const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i);
const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i);
const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i);
const upb_symtab *upb_filedef_symtab(const upb_filedef *f);
upb_arena *_upb_symtab_arena(const upb_symtab *s);
/* upb_symtab *****************************************************************/
@ -4179,6 +4178,7 @@ const upb_filedef *upb_symtab_addfile(
upb_symtab *s, const google_protobuf_FileDescriptorProto *file,
upb_status *status);
size_t _upb_symtab_bytesloaded(const upb_symtab *s);
upb_arena *_upb_symtab_arena(const upb_symtab *s);
/* For generated code only: loads a generated descriptor. */
typedef struct upb_def_init {

@ -341,6 +341,7 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/cpp/cpp_message_field.cc \
google/protobuf/compiler/cpp/cpp_message_field.h \
google/protobuf/compiler/cpp/cpp_message_layout_helper.h \
google/protobuf/compiler/cpp/cpp_names.h \
google/protobuf/compiler/cpp/cpp_options.h \
google/protobuf/compiler/cpp/cpp_padding_optimizer.cc \
google/protobuf/compiler/cpp/cpp_padding_optimizer.h \

@ -327,7 +327,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
template <typename T>
PROTOBUF_NDEBUG_INLINE static T* CreateArray(Arena* arena,
size_t num_elements) {
static_assert(std::is_pod<T>::value,
static_assert(std::is_trivially_default_constructible<T>::value,
"CreateArray requires a trivially constructible type");
static_assert(std::is_trivially_destructible<T>::value,
"CreateArray requires a trivially destructible type");

@ -1216,21 +1216,9 @@ PopulateSingleSimpleDescriptorDatabase(const std::string& descriptor_set_name) {
bool CommandLineInterface::AllowProto3Optional(
const FileDescriptor& file) const {
// If the --experimental_allow_proto3_optional flag was set, we allow.
if (allow_proto3_optional_) return true;
// Whitelist all ads protos. Ads is an early adopter of this feature.
if (file.name().find("google/ads/googleads") != std::string::npos) {
return true;
}
// Whitelist all protos testing proto3 optional.
if (file.name().find("test_proto3_optional") != std::string::npos) {
return true;
}
return false;
// Proto3 optional is enabled by default now, the experimental flag is no
// longer required.
return true;
}

@ -2378,48 +2378,6 @@ TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) {
ExpectErrorText("Missing value for flag: --test_out\n");
}
TEST_F(CommandLineInterfaceTest, Proto3OptionalDisallowed) {
CreateTempFile("google/foo.proto",
"syntax = \"proto3\";\n"
"message Foo {\n"
" optional int32 i = 1;\n"
"}\n");
Run("protocol_compiler --proto_path=$tmpdir google/foo.proto "
"-odescriptor.pb");
ExpectErrorSubstring("--experimental_allow_proto3_optional was not set");
}
TEST_F(CommandLineInterfaceTest, Proto3OptionalDisallowedDescriptor) {
CreateTempFile("google/foo.proto",
"syntax = \"proto3\";\n"
"message Foo {\n"
" optional int32 i = 1;\n"
"}\n");
Run("protocol_compiler --experimental_allow_proto3_optional "
"--proto_path=$tmpdir google/foo.proto "
" -o$tmpdir/descriptor.pb");
ExpectNoErrors();
Run("protocol_compiler --descriptor_set_in=$tmpdir/descriptor.pb"
" google/foo.proto --test_out=$tmpdir");
ExpectErrorSubstring("--experimental_allow_proto3_optional was not set");
}
TEST_F(CommandLineInterfaceTest, Proto3OptionalDisallowedGenCode) {
CreateTempFile("google/foo.proto",
"syntax = \"proto3\";\n"
"message Foo {\n"
" optional int32 i = 1;\n"
"}\n");
Run("protocol_compiler --proto_path=$tmpdir google/foo.proto "
"--test_out=$tmpdir");
ExpectErrorSubstring("--experimental_allow_proto3_optional was not set");
}
TEST_F(CommandLineInterfaceTest, Proto3OptionalDisallowedNoCodegenSupport) {
CreateTempFile("google/foo.proto",

@ -165,7 +165,7 @@ class FieldGenerator {
}
// Generate initialization code for private members declared by
// GeneratePrivateMembers(), specifically for the constexpr construtor.
// GeneratePrivateMembers(), specifically for the constexpr constructor.
// These go into the constructor's initializer list and must follow that
// syntax (eg `field_(args)`). Does not include `:` or `,` separators.
virtual void GenerateConstinitInitializer(io::Printer* printer) const {}

@ -75,11 +75,6 @@ std::string GetSortKey<FileDescriptor>(const FileDescriptor& val) {
return val.name();
}
template <>
std::string GetSortKey<SCC>(const SCC& val) {
return val.GetRepresentative()->full_name();
}
template <class T>
bool CompareSortKeys(const T* a, const T* b) {
return GetSortKey(*a) < GetSortKey(*b);

@ -90,17 +90,6 @@ const std::unordered_set<std::string>* kReservedNames =
"transient", "try", "void", "volatile", "while",
});
// Names that should be avoided as field names in Kotlin.
// All Kotlin hard keywords are in this list.
const std::unordered_set<std::string>* kKotlinForbiddenNames =
new std::unordered_set<std::string>({
"as", "as?", "break", "class", "continue", "do", "else",
"false", "for", "fun", "if", "in", "!in", "interface",
"is", "!is", "null", "object", "package", "return", "super",
"this", "throw", "true", "try", "typealias", "typeof", "val",
"var", "when", "while",
});
bool IsForbidden(const std::string& field_name) {
for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) {
if (field_name == kForbiddenWordList[i]) {

@ -49,6 +49,7 @@ namespace protobuf {
namespace compiler {
namespace java {
namespace {
void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,

@ -28,9 +28,19 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assert.h>
#include <google/protobuf/compiler/js/js_generator.h>
#include <google/protobuf/compiler/js/well_known_types_embed.h>
#include <google/protobuf/compiler/scc.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/stubs/strutil.h>
#include <assert.h>
#include <algorithm>
#include <limits>
#include <map>
@ -39,17 +49,6 @@
#include <utility>
#include <vector>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/scc.h>
#include <google/protobuf/compiler/js/well_known_types_embed.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
namespace compiler {
@ -173,8 +172,8 @@ std::string GetNestedMessageName(const Descriptor* descriptor) {
if (descriptor == NULL) {
return "";
}
std::string result = StripPrefixString(
descriptor->full_name(), descriptor->file()->package());
std::string result =
StripPrefixString(descriptor->full_name(), descriptor->file()->package());
// Add a leading dot if one is not already present.
if (!result.empty() && result[0] != '.') {
result = "." + result;
@ -411,7 +410,7 @@ std::string GetMessagesFileName(const GeneratorOptions& options, const SCC* scc,
GetSnakeFilename(scc->GetRepresentative()->file()->name()));
(*long_name_dict)[scc->GetRepresentative()] =
StrCat(snake_name, "_long_sccs_",
static_cast<uint64>((*long_name_dict).size()));
static_cast<uint64>((*long_name_dict).size()));
}
filename_base = (*long_name_dict)[scc->GetRepresentative()];
}
@ -431,9 +430,7 @@ std::string GetEnumFileName(const GeneratorOptions& options,
}
// Returns the message/response ID, if set.
std::string GetMessageId(const Descriptor* desc) {
return std::string();
}
std::string GetMessageId(const Descriptor* desc) { return std::string(); }
bool IgnoreExtensionField(const FieldDescriptor* field) {
// Exclude descriptor extensions from output "to avoid clutter" (from original
@ -444,7 +441,6 @@ bool IgnoreExtensionField(const FieldDescriptor* field) {
file->name() == "google/protobuf/descriptor.proto";
}
// Used inside Google only -- do not remove.
bool IsResponse(const Descriptor* desc) { return false; }
@ -452,7 +448,6 @@ bool IgnoreField(const FieldDescriptor* field) {
return IgnoreExtensionField(field);
}
// Do we ignore this message type?
bool IgnoreMessage(const Descriptor* d) { return d->options().map_entry(); }
@ -537,7 +532,6 @@ std::string JSGetterName(const GeneratorOptions& options,
return name;
}
std::string JSOneofName(const OneofDescriptor* oneof) {
return ToUpperCamel(ParseLowerUnderscore(oneof->name()));
}
@ -818,23 +812,19 @@ std::string JSFieldDefault(const FieldDescriptor* field) {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
return MaybeNumberString(field,
StrCat(field->default_value_int32()));
return MaybeNumberString(field, StrCat(field->default_value_int32()));
case FieldDescriptor::CPPTYPE_UINT32:
// The original codegen is in Java, and Java protobufs store unsigned
// integer values as signed integer values. In order to exactly match the
// output, we need to reinterpret as base-2 signed. Ugh.
return MaybeNumberString(
field,
StrCat(static_cast<int32>(field->default_value_uint32())));
field, StrCat(static_cast<int32>(field->default_value_uint32())));
case FieldDescriptor::CPPTYPE_INT64:
return MaybeNumberString(field,
StrCat(field->default_value_int64()));
return MaybeNumberString(field, StrCat(field->default_value_int64()));
case FieldDescriptor::CPPTYPE_UINT64:
// See above note for uint32 -- reinterpreting as signed.
return MaybeNumberString(
field,
StrCat(static_cast<int64>(field->default_value_uint64())));
field, StrCat(static_cast<int64>(field->default_value_uint64())));
case FieldDescriptor::CPPTYPE_ENUM:
return StrCat(field->default_value_enum()->number());
case FieldDescriptor::CPPTYPE_BOOL:
@ -849,9 +839,10 @@ std::string JSFieldDefault(const FieldDescriptor* field) {
bool is_valid = EscapeJSString(field->default_value_string(), &out);
if (!is_valid) {
// TODO(b/115551870): Decide whether this should be a hard error.
GOOGLE_LOG(WARNING) << "The default value for field " << field->full_name()
<< " was truncated since it contained invalid UTF-8 or"
" codepoints outside the basic multilingual plane.";
GOOGLE_LOG(WARNING)
<< "The default value for field " << field->full_name()
<< " was truncated since it contained invalid UTF-8 or"
" codepoints outside the basic multilingual plane.";
}
return "\"" + out + "\"";
} else { // Bytes
@ -1114,7 +1105,6 @@ std::string JSBinaryWriterMethodName(const GeneratorOptions& options,
JSBinaryReadWriteMethodName(field, /* is_writer = */ true);
}
std::string JSTypeTag(const FieldDescriptor* desc) {
switch (desc->type()) {
case FieldDescriptor::TYPE_DOUBLE:
@ -1149,7 +1139,6 @@ std::string JSTypeTag(const FieldDescriptor* desc) {
return "";
}
bool HasRepeatedFields(const GeneratorOptions& options,
const Descriptor* desc) {
for (int i = 0; i < desc->field_count(); i++) {
@ -1638,6 +1627,8 @@ void Generator::GenerateHeader(const GeneratorOptions& options,
"/**\n"
" * @fileoverview\n"
" * @enhanceable\n"
// TODO(b/152440355): requireType/requires diverged from internal version.
" * @suppress {missingRequire} reports error on implict type usages.\n"
" * @suppress {messageConventions} JS Compiler reports an "
"error if a variable or\n"
" * field starts with 'MSG_' and isn't a translatable "
@ -1902,16 +1893,13 @@ void Generator::GenerateRequiresImpl(const GeneratorOptions& options,
}
}
bool NamespaceOnly(const Descriptor* desc) {
return false;
}
bool NamespaceOnly(const Descriptor* desc) { return false; }
void Generator::FindRequiresForMessage(const GeneratorOptions& options,
const Descriptor* desc,
std::set<std::string>* required,
std::set<std::string>* forwards,
bool* have_message) const {
if (!NamespaceOnly(desc)) {
*have_message = true;
for (int i = 0; i < desc->field_count(); i++) {
@ -1960,7 +1948,8 @@ void Generator::FindRequiresForField(const GeneratorOptions& options,
void Generator::FindRequiresForExtension(
const GeneratorOptions& options, const FieldDescriptor* field,
std::set<std::string>* required, std::set<std::string>* forwards) const {
if (field->containing_type()->full_name() != "google.protobuf.bridge.MessageSet") {
if (field->containing_type()->full_name() !=
"google.protobuf.bridge.MessageSet") {
required->insert(GetMessagePath(options, field->containing_type()));
}
FindRequiresForField(options, field, required, forwards);
@ -2000,7 +1989,6 @@ void Generator::GenerateClass(const GeneratorOptions& options,
printer->Print("\n");
GenerateClassFieldInfo(options, printer, desc);
GenerateClassToObject(options, printer, desc);
// These must come *before* the extension-field info generation in
// GenerateClassRegistration so that references to the binary
@ -2084,7 +2072,8 @@ void Generator::GenerateClassConstructorAndDeclareExtensionFieldInfo(
const Descriptor* desc) const {
if (!NamespaceOnly(desc)) {
GenerateClassConstructor(options, printer, desc);
if (IsExtendable(desc) && desc->full_name() != "google.protobuf.bridge.MessageSet") {
if (IsExtendable(desc) &&
desc->full_name() != "google.protobuf.bridge.MessageSet") {
GenerateClassExtensionFieldInfo(options, printer, desc);
}
}
@ -2524,7 +2513,6 @@ void Generator::GenerateClassRegistration(const GeneratorOptions& options,
GenerateExtension(options, printer, extension);
}
}
}
void Generator::GenerateClassFields(const GeneratorOptions& options,
@ -2687,8 +2675,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
}
} else {
bool untyped =
false;
bool untyped = false;
// Simple (primitive) field, either singular or repeated.
@ -3037,7 +3024,6 @@ void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
}
}
void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options,
io::Printer* printer,
const Descriptor* desc) const {
@ -3067,36 +3053,36 @@ void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options,
"$class$.deserializeBinaryFromReader = function(msg, reader) {\n"
" while (reader.nextField()) {\n",
"class", GetMessagePath(options, desc));
printer->Print(
" if (reader.isEndGroup()) {\n"
" break;\n"
" }\n"
" var field = reader.getFieldNumber();\n"
" switch (field) {\n");
printer->Print(
" if (reader.isEndGroup()) {\n"
" break;\n"
" }\n"
" var field = reader.getFieldNumber();\n"
" switch (field) {\n");
for (int i = 0; i < desc->field_count(); i++) {
if (!IgnoreField(desc->field(i))) {
GenerateClassDeserializeBinaryField(options, printer, desc->field(i));
}
for (int i = 0; i < desc->field_count(); i++) {
if (!IgnoreField(desc->field(i))) {
GenerateClassDeserializeBinaryField(options, printer, desc->field(i));
}
}
printer->Print(" default:\n");
if (IsExtendable(desc)) {
printer->Print(
" jspb.Message.readBinaryExtension(msg, reader,\n"
" $extobj$Binary,\n"
" $class$.prototype.getExtension,\n"
" $class$.prototype.setExtension);\n"
" break;\n"
" }\n",
"extobj", JSExtensionsObjectName(options, desc->file(), desc),
"class", GetMessagePath(options, desc));
} else {
printer->Print(
" reader.skipField();\n"
" break;\n"
" }\n");
}
printer->Print(" default:\n");
if (IsExtendable(desc)) {
printer->Print(
" jspb.Message.readBinaryExtension(msg, reader,\n"
" $extobj$Binary,\n"
" $class$.prototype.getExtension,\n"
" $class$.prototype.setExtension);\n"
" break;\n"
" }\n",
"extobj", JSExtensionsObjectName(options, desc->file(), desc), "class",
GetMessagePath(options, desc));
} else {
printer->Print(
" reader.skipField();\n"
" break;\n"
" }\n");
}
printer->Print(
" }\n"
@ -3381,9 +3367,8 @@ void Generator::GenerateEnum(const GeneratorOptions& options,
for (auto i : valid_index) {
const EnumValueDescriptor* value = enumdesc->value(i);
printer->Print(" $name$: $value$$comma$\n", "name",
ToEnumCase(value->name()), "value",
StrCat(value->number()), "comma",
(i == valid_index.back()) ? "" : ",");
ToEnumCase(value->name()), "value", StrCat(value->number()),
"comma", (i == valid_index.back()) ? "" : ",");
printer->Annotate("name", value);
}
@ -3424,8 +3409,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
"!Object} */ (\n"
" $toObject$),\n"
" $repeated$);\n",
"index", StrCat(field->number()), "name", extension_object_name,
"ctor",
"index", StrCat(field->number()), "name", extension_object_name, "ctor",
(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
? SubmessageTypeRef(options, field)
: std::string("null")),
@ -3732,7 +3716,6 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
return false;
}
if (options.output_mode() == GeneratorOptions::kEverythingInOneFile) {
// All output should go in a single file.
std::string filename = options.output_dir + "/" + options.library +

@ -644,43 +644,50 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options,
// Generate getter.
GenerateFieldDocComment(printer, field, options, kFieldGetter);
// deprecation
std::string deprecation_trigger = (field->options().deprecated()) ? "@trigger_error('" +
field->name() + " is deprecated.', E_USER_DEPRECATED);\n " : "";
if (oneof != NULL) {
printer->Print(
"public function get^camel_name^()\n"
"{\n"
" return $this->readOneof(^number^);\n"
" ^deprecation_trigger^return $this->readOneof(^number^);\n"
"}\n\n"
"public function has^camel_name^()\n"
"{\n"
" return $this->hasOneof(^number^);\n"
" ^deprecation_trigger^return $this->hasOneof(^number^);\n"
"}\n\n",
"camel_name", UnderscoresToCamelCase(field->name(), true),
"number", IntToString(field->number()));
"number", IntToString(field->number()),
"deprecation_trigger", deprecation_trigger);
} else if (field->has_presence()) {
printer->Print(
"public function get^camel_name^()\n"
"{\n"
" return isset($this->^name^) ? $this->^name^ : ^default_value^;\n"
" ^deprecation_trigger^return isset($this->^name^) ? $this->^name^ : ^default_value^;\n"
"}\n\n"
"public function has^camel_name^()\n"
"{\n"
" return isset($this->^name^);\n"
" ^deprecation_trigger^return isset($this->^name^);\n"
"}\n\n"
"public function clear^camel_name^()\n"
"{\n"
" unset($this->^name^);\n"
" ^deprecation_trigger^unset($this->^name^);\n"
"}\n\n",
"camel_name", UnderscoresToCamelCase(field->name(), true),
"name", field->name(),
"default_value", DefaultForField(field));
"default_value", DefaultForField(field),
"deprecation_trigger", deprecation_trigger);
} else {
printer->Print(
"public function get^camel_name^()\n"
"{\n"
" return $this->^name^;\n"
" ^deprecation_trigger^return $this->^name^;\n"
"}\n\n",
"camel_name", UnderscoresToCamelCase(field->name(), true), "name",
field->name());
"camel_name", UnderscoresToCamelCase(field->name(), true),
"name", field->name(),
"deprecation_trigger", deprecation_trigger);
}
// For wrapper types, generate an additional getXXXUnwrapped getter
@ -692,10 +699,11 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options,
printer->Print(
"public function get^camel_name^Unwrapped()\n"
"{\n"
" return $this->readWrapperValue(\"^field_name^\");\n"
" ^deprecation_trigger^return $this->readWrapperValue(\"^field_name^\");\n"
"}\n\n",
"camel_name", UnderscoresToCamelCase(field->name(), true),
"field_name", field->name());
"field_name", field->name(),
"deprecation_trigger", deprecation_trigger);
}
// Generate setter.
@ -707,6 +715,13 @@ void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options,
Indent(printer);
if (field->options().deprecated()) {
printer->Print(
"^deprecation_trigger^",
"deprecation_trigger", deprecation_trigger
);
}
// Type check.
if (field->is_map()) {
const Descriptor* map_entry = field->message_type();
@ -1741,6 +1756,9 @@ void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field,
"php_type", PhpGetterTypeName(field, options),
"maybe_null", can_return_null ? "|null" : "");
}
if (field->options().deprecated()) {
printer->Print(" * @deprecated\n");
}
printer->Print(" */\n");
}

@ -198,44 +198,6 @@ int FieldSpaceUsed(const FieldDescriptor* field) {
return 0;
}
// Compute the byte size of in-memory representation of the oneof fields
// in default oneof instance.
int OneofFieldSpaceUsed(const FieldDescriptor* field) {
typedef FieldDescriptor FD; // avoid line wrapping
switch (field->cpp_type()) {
case FD::CPPTYPE_INT32:
return sizeof(int32);
case FD::CPPTYPE_INT64:
return sizeof(int64);
case FD::CPPTYPE_UINT32:
return sizeof(uint32);
case FD::CPPTYPE_UINT64:
return sizeof(uint64);
case FD::CPPTYPE_DOUBLE:
return sizeof(double);
case FD::CPPTYPE_FLOAT:
return sizeof(float);
case FD::CPPTYPE_BOOL:
return sizeof(bool);
case FD::CPPTYPE_ENUM:
return sizeof(int);
case FD::CPPTYPE_MESSAGE:
return sizeof(Message*);
case FD::CPPTYPE_STRING:
switch (field->options().ctype()) {
default:
case FieldOptions::STRING:
return sizeof(ArenaStringPtr);
}
break;
}
GOOGLE_LOG(DFATAL) << "Can't get here.";
return 0;
}
inline int DivideRoundingUp(int i, int j) { return (i + (j - 1)) / j; }
static const int kSafeAlignment = sizeof(uint64);

@ -87,7 +87,7 @@ inline ExtensionSet* GetExtensionSet(MessageLite* msg, int64 extension_offset) {
template <typename Type>
inline Type* AddField(MessageLite* msg, int64 offset) {
static_assert(std::is_pod<Type>::value,
static_assert(std::is_trivially_copy_assignable<Type>::value,
"Do not assign");
RepeatedField<Type>* repeated = Raw<RepeatedField<Type>>(msg, offset);
@ -104,7 +104,7 @@ inline std::string* AddField<std::string>(MessageLite* msg, int64 offset) {
template <typename Type>
inline void AddField(MessageLite* msg, int64 offset, Type value) {
static_assert(std::is_pod<Type>::value,
static_assert(std::is_trivially_copy_assignable<Type>::value,
"Do not assign");
*AddField<Type>(msg, offset) = value;
}
@ -126,7 +126,7 @@ inline Type* MutableField(MessageLite* msg, uint32* has_bits,
template <typename Type>
inline void SetField(MessageLite* msg, uint32* has_bits, uint32 has_bit_index,
int64 offset, Type value) {
static_assert(std::is_pod<Type>::value,
static_assert(std::is_trivially_copy_assignable<Type>::value,
"Do not assign");
*MutableField<Type>(msg, has_bits, has_bit_index, offset) = value;
}

@ -529,6 +529,23 @@ void GenericTypeHandler<std::string>::Merge(const std::string& from,
*to = from;
}
// Non-inline variants of std::string specializations for
// various InternalMetadata routines.
template <>
void InternalMetadata::DoClear<std::string>() {
mutable_unknown_fields<std::string>()->clear();
}
template <>
void InternalMetadata::DoMergeFrom<std::string>(const std::string& other) {
mutable_unknown_fields<std::string>()->append(other);
}
template <>
void InternalMetadata::DoSwap<std::string>(std::string* other) {
mutable_unknown_fields<std::string>()->swap(*other);
}
} // namespace internal

@ -146,7 +146,7 @@ class ExplicitlyConstructed {
private:
// Prefer c++14 aligned_storage, but for compatibility this will do.
union AlignedUnion {
char space[sizeof(T)];
alignas(T) char space[sizeof(T)];
int64 align_to_int64;
void* align_to_ptr;
} union_;

@ -552,6 +552,34 @@ TEST(MESSAGE_TEST_NAME, IsInitialized) {
EXPECT_TRUE(msg.IsInitialized());
}
TEST(MESSAGE_TEST_NAME, IsInitializedSplitBytestream) {
UNITTEST::TestRequired ab, c;
ab.set_a(1);
ab.set_b(2);
c.set_c(3);
// The protobuf represented by the concatenated string has all required
// fields (a,b,c) set.
std::string bytes =
ab.SerializePartialAsString() + c.SerializePartialAsString();
UNITTEST::TestRequired concatenated;
EXPECT_TRUE(concatenated.ParsePartialFromString(bytes));
EXPECT_TRUE(concatenated.IsInitialized());
UNITTEST::TestRequiredForeign fab, fc;
fab.mutable_optional_message()->set_a(1);
fab.mutable_optional_message()->set_b(2);
fc.mutable_optional_message()->set_c(3);
bytes =
fab.SerializePartialAsString() + fc.SerializePartialAsString();
UNITTEST::TestRequiredForeign fconcatenated;
EXPECT_TRUE(fconcatenated.ParsePartialFromString(bytes));
EXPECT_TRUE(fconcatenated.IsInitialized());
}
TEST(MESSAGE_FACTORY_TEST_NAME, GeneratedFactoryLookup) {
EXPECT_EQ(MessageFactory::generated_factory()->GetPrototype(
UNITTEST::TestAllTypes::descriptor()),

@ -68,7 +68,7 @@ class InternalMetadata {
void Delete() {
// Note that Delete<> should be called not more than once.
if (have_unknown_fields() && arena() == NULL) {
delete PtrValue<Container<T>>();
DeleteOutOfLineHelper<T>();
}
}
@ -202,6 +202,11 @@ class InternalMetadata {
T unknown_fields;
};
template <typename T>
PROTOBUF_NOINLINE void DeleteOutOfLineHelper() {
delete PtrValue<Container<T>>();
}
template <typename T>
PROTOBUF_NOINLINE T* mutable_unknown_fields_slow() {
Arena* my_arena = arena();
@ -221,17 +226,17 @@ class InternalMetadata {
// Templated functions.
template <typename T>
void DoClear() {
PROTOBUF_NOINLINE void DoClear() {
mutable_unknown_fields<T>()->Clear();
}
template <typename T>
void DoMergeFrom(const T& other) {
PROTOBUF_NOINLINE void DoMergeFrom(const T& other) {
mutable_unknown_fields<T>()->MergeFrom(other);
}
template <typename T>
void DoSwap(T* other) {
PROTOBUF_NOINLINE void DoSwap(T* other) {
mutable_unknown_fields<T>()->Swap(other);
}
};
@ -239,20 +244,12 @@ class InternalMetadata {
// String Template specializations.
template <>
inline void InternalMetadata::DoClear<std::string>() {
mutable_unknown_fields<std::string>()->clear();
}
PROTOBUF_EXPORT void InternalMetadata::DoClear<std::string>();
template <>
inline void InternalMetadata::DoMergeFrom<std::string>(
const std::string& other) {
mutable_unknown_fields<std::string>()->append(other);
}
PROTOBUF_EXPORT void InternalMetadata::DoMergeFrom<std::string>(
const std::string& other);
template <>
inline void InternalMetadata::DoSwap<std::string>(std::string* other) {
mutable_unknown_fields<std::string>()->swap(*other);
}
PROTOBUF_EXPORT void InternalMetadata::DoSwap<std::string>(std::string* other);
// This helper RAII class is needed to efficiently parse unknown fields. We
// should only call mutable_unknown_fields if there are actual unknown fields.

@ -438,7 +438,7 @@ class RepeatedField final {
//
// The first version executes at 7 cycles per iteration while the second
// version near 1 or 2 cycles.
template <int = 0, bool = std::is_pod<Element>::value>
template <int = 0, bool = std::is_trivial<Element>::value>
class FastAdderImpl {
public:
explicit FastAdderImpl(RepeatedField* rf) : repeated_field_(rf) {
@ -501,7 +501,7 @@ namespace internal {
// effectively.
template <typename Element,
bool HasTrivialCopy =
std::is_pod<Element>::value>
std::is_trivially_copy_constructible<Element>::value>
struct ElementCopier {
void operator()(Element* to, const Element* from, int array_size);
};

@ -39,7 +39,6 @@
namespace google {
namespace protobuf {
namespace util {
using util::Status;
namespace converter {
namespace {

@ -52,7 +52,6 @@ namespace util {
// Allow these symbols to be referenced as util::Status, util::error::* in
// this file.
using util::Status;
namespace error {
using util::error::CANCELLED;
using util::error::INTERNAL;

@ -42,13 +42,11 @@
namespace google {
namespace protobuf {
namespace util {
using util::Status;
namespace error {
using util::error::INVALID_ARGUMENT;
} // namespace error
namespace converter {
using util::Status;
// Tests for the JSON Stream Parser. These tests are intended to be
// comprehensive and cover the following:

@ -54,7 +54,6 @@ namespace converter {
using io::CodedOutputStream;
using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
using util::Status;
using util::error::INVALID_ARGUMENT;

@ -59,7 +59,6 @@
namespace google {
namespace protobuf {
namespace util {
using util::Status;
namespace error {
using util::error::Code;
using util::error::INTERNAL;
@ -67,7 +66,6 @@ using util::error::INTERNAL;
namespace converter {
using ::PROTOBUF_NAMESPACE_ID::internal::WireFormat;
using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
using util::Status;
namespace {

@ -74,69 +74,58 @@ class TypeInfo;
class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
public:
struct RenderOptions {
RenderOptions() {}
RenderOptions() = default;
RenderOptions(const RenderOptions&) = default;
// whether to render enums using lowercamelcase.
// Sets whether or not to use lowerCamelCase casing for enum values. If set
// to false, enum values are output without any case conversions.
//
// For example, if we have an enum:
// enum Type {
// ACTION_AND_ADVENTURE = 1;
// }
// Type type = 20;
//
// And this option is set to true. Then the rendered "type" field will have
// the string "actionAndAdventure".
// {
// ...
// "type": "actionAndAdventure",
// ...
// }
//
// If set to false, the rendered "type" field will have the string
// "ACTION_AND_ADVENTURE".
// {
// ...
// "type": "ACTION_AND_ADVENTURE",
// ...
// }
bool use_lower_camel_for_enums = false;
// whether to render enums as ints always. defaults to false.
// Sets whether to always output enums as ints, by default this is off, and
// enums are rendered as strings.
bool use_ints_for_enums = false;
// whether to preserve proto field names
// Whether to preserve proto field names
bool preserve_proto_field_names = false;
};
ProtoStreamObjectSource(io::CodedInputStream* stream,
TypeResolver* type_resolver,
const google::protobuf::Type& type)
: ProtoStreamObjectSource(stream, type_resolver, type, RenderOptions()) {}
ProtoStreamObjectSource(io::CodedInputStream* stream,
TypeResolver* type_resolver,
const google::protobuf::Type& type,
const RenderOptions& render_options = {});
const RenderOptions& render_options);
~ProtoStreamObjectSource() override;
util::Status NamedWriteTo(StringPiece name,
ObjectWriter* ow) const override;
// Sets whether or not to use lowerCamelCase casing for enum values. If set to
// false, enum values are output without any case conversions.
//
// For example, if we have an enum:
// enum Type {
// ACTION_AND_ADVENTURE = 1;
// }
// Type type = 20;
//
// And this option is set to true. Then the rendered "type" field will have
// the string "actionAndAdventure".
// {
// ...
// "type": "actionAndAdventure",
// ...
// }
//
// If set to false, the rendered "type" field will have the string
// "ACTION_AND_ADVENTURE".
// {
// ...
// "type": "ACTION_AND_ADVENTURE",
// ...
// }
void set_use_lower_camel_for_enums(bool value) {
render_options_.use_lower_camel_for_enums = value;
}
// Sets whether to always output enums as ints, by default this is off, and
// enums are rendered as strings.
void set_use_ints_for_enums(bool value) {
render_options_.use_ints_for_enums = value;
}
// Sets whether to use original proto field names
void set_preserve_proto_field_names(bool value) {
render_options_.preserve_proto_field_names = value;
}
// Sets the max recursion depth of proto message to be deserialized. Proto
// messages over this depth will fail to be deserialized.
// Default value is 64.
@ -144,7 +133,6 @@ class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
max_recursion_depth_ = max_depth;
}
protected:
// Writes a proto2 Message to the ObjectWriter. When the given end_tag is
// found this method will complete, allowing it to be used for parsing both
@ -317,7 +305,7 @@ class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
const google::protobuf::Type& type_;
RenderOptions render_options_;
const RenderOptions render_options_;
// Tracks current recursion depth.
mutable int recursion_depth_;

@ -79,7 +79,6 @@ using proto_util_converter::testing::Proto3Message;
using proto_util_converter::testing::StructType;
using proto_util_converter::testing::TimestampDuration;
using ::testing::_;
using util::Status;
namespace {
@ -117,12 +116,13 @@ class ProtostreamObjectSourceTest
ArrayInputStream arr_stream(proto.data(), proto.size());
CodedInputStream in_stream(&arr_stream);
ProtoStreamObjectSource::RenderOptions render_options;
render_options.use_lower_camel_for_enums = use_lower_camel_for_enums_;
render_options.use_ints_for_enums = use_ints_for_enums_;
render_options.preserve_proto_field_names = use_preserve_proto_field_names_;
std::unique_ptr<ProtoStreamObjectSource> os(
helper_.NewProtoSource(&in_stream, GetTypeUrl(descriptor)));
if (use_lower_camel_for_enums_) os->set_use_lower_camel_for_enums(true);
if (use_ints_for_enums_) os->set_use_ints_for_enums(true);
if (use_preserve_proto_field_names_)
os->set_preserve_proto_field_names(true);
helper_.NewProtoSource(&in_stream, GetTypeUrl(descriptor),
render_options));
os->set_max_recursion_depth(64);
return os->WriteTo(&mock_);
}

@ -86,12 +86,13 @@ void TypeInfoTestHelper::ResetTypeInfo(const Descriptor* descriptor1,
TypeInfo* TypeInfoTestHelper::GetTypeInfo() { return typeinfo_.get(); }
ProtoStreamObjectSource* TypeInfoTestHelper::NewProtoSource(
io::CodedInputStream* coded_input, const std::string& type_url) {
io::CodedInputStream* coded_input, const std::string& type_url,
ProtoStreamObjectSource::RenderOptions render_options) {
const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(type_url);
switch (type_) {
case USE_TYPE_RESOLVER: {
return new ProtoStreamObjectSource(coded_input, type_resolver_.get(),
*type);
*type, render_options);
}
}
GOOGLE_LOG(FATAL) << "Can not reach here.";

@ -71,8 +71,9 @@ class TypeInfoTestHelper {
// Returns the TypeInfo created after ResetTypeInfo.
TypeInfo* GetTypeInfo();
ProtoStreamObjectSource* NewProtoSource(io::CodedInputStream* coded_input,
const std::string& type_url);
ProtoStreamObjectSource* NewProtoSource(
io::CodedInputStream* coded_input, const std::string& type_url,
ProtoStreamObjectSource::RenderOptions render_options = {});
ProtoStreamObjectWriter* NewProtoWriter(
const std::string& type_url, strings::ByteSink* output,

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

Loading…
Cancel
Save