Merge pull request #2234 from TeBoring/master

Merge 3.1.x branch into master.
pull/2244/head
Paul Yang 9 years ago committed by GitHub
commit fd046f6263
  1. 1
      .travis.yml
  2. 2
      BUILD
  3. 80
      CHANGES.txt
  4. 58
      Makefile.am
  5. 2
      Protobuf.podspec
  6. 6
      appveyor.yml
  7. 1
      cmake/extract_includes.bat.in
  8. 2
      cmake/tests.cmake
  9. 4
      configure.ac
  10. 16
      conformance/Makefile.am
  11. 8
      conformance/conformance_python.py
  12. 668
      conformance/conformance_test.cc
  13. 53
      conformance/conformance_test.h
  14. 12
      conformance/conformance_test_runner.cc
  15. 89
      conformance/failure_list_cpp.txt
  16. 10
      conformance/failure_list_csharp.txt
  17. 88
      conformance/failure_list_java.txt
  18. 65
      conformance/failure_list_python.txt
  19. 97
      conformance/failure_list_python_cpp.txt
  20. 422
      conformance/failure_list_ruby.txt
  21. 2
      csharp/Google.Protobuf.Tools.nuspec
  22. 52
      csharp/build_tools.sh
  23. 132
      csharp/src/Google.Protobuf/Reflection/Descriptor.cs
  24. 6
      csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
  25. 6
      csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
  26. 8
      csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
  27. 8
      csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
  28. 12
      csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
  29. 6
      csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
  30. 2
      csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
  31. 16
      csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
  32. 2
      csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
  33. 6
      csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
  34. 2
      csharp/src/Google.Protobuf/project.json
  35. 2
      java/core/pom.xml
  36. 14
      java/core/src/main/java/com/google/protobuf/ByteString.java
  37. 3593
      java/core/src/main/java/com/google/protobuf/CodedInputStream.java
  38. 400
      java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
  39. 31
      java/core/src/main/java/com/google/protobuf/Descriptors.java
  40. 166
      java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
  41. 10
      java/core/src/main/java/com/google/protobuf/Internal.java
  42. 16
      java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
  43. 9
      java/core/src/main/java/com/google/protobuf/MapEntry.java
  44. 9
      java/core/src/main/java/com/google/protobuf/NioByteString.java
  45. 1
      java/core/src/main/java/com/google/protobuf/RopeByteString.java
  46. 22
      java/core/src/main/java/com/google/protobuf/TextFormat.java
  47. 3
      java/core/src/main/java/com/google/protobuf/TextFormatParseInfoTree.java
  48. 31
      java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java
  49. 119
      java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
  50. 4
      java/core/src/main/java/com/google/protobuf/WireFormat.java
  51. 4
      java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
  52. 3
      java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
  53. 3
      java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java
  54. 4
      java/core/src/test/java/com/google/protobuf/ByteStringTest.java
  55. 802
      java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
  56. 55
      java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
  57. 4
      java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
  58. 15
      java/core/src/test/java/com/google/protobuf/DescriptorsTest.java
  59. 3
      java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
  60. 4
      java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java
  61. 47
      java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java
  62. 3
      java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
  63. 4
      java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
  64. 3
      java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
  65. 4
      java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
  66. 4
      java/core/src/test/java/com/google/protobuf/LazyFieldTest.java
  67. 4
      java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
  68. 3
      java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
  69. 4
      java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
  70. 9
      java/core/src/test/java/com/google/protobuf/LiteTest.java
  71. 3
      java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java
  72. 3
      java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
  73. 4
      java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
  74. 10
      java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
  75. 170
      java/core/src/test/java/com/google/protobuf/MapTest.java
  76. 4
      java/core/src/test/java/com/google/protobuf/MessageTest.java
  77. 4
      java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java
  78. 3
      java/core/src/test/java/com/google/protobuf/NioByteStringTest.java
  79. 8
      java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java
  80. 4
      java/core/src/test/java/com/google/protobuf/ParserTest.java
  81. 3
      java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
  82. 4
      java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java
  83. 8
      java/core/src/test/java/com/google/protobuf/ServiceTest.java
  84. 3
      java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java
  85. 11
      java/core/src/test/java/com/google/protobuf/TestUtil.java
  86. 29
      java/core/src/test/java/com/google/protobuf/TextFormatTest.java
  87. 4
      java/core/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java
  88. 4
      java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
  89. 3
      java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
  90. 4
      java/core/src/test/java/com/google/protobuf/WireFormatTest.java
  91. 1
      java/core/src/test/proto/com/google/protobuf/field_presence_test.proto
  92. 37
      java/core/src/test/proto/com/google/protobuf/map_for_proto2_lite_test.proto
  93. 37
      java/core/src/test/proto/com/google/protobuf/map_for_proto2_test.proto
  94. 39
      java/core/src/test/proto/com/google/protobuf/map_test.proto
  95. 1
      java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto
  96. 2
      java/pom.xml
  97. 2
      java/util/pom.xml
  98. 182
      java/util/src/main/java/com/google/protobuf/util/Durations.java
  99. 15
      java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
  100. 207
      java/util/src/main/java/com/google/protobuf/util/Timestamps.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -31,6 +31,7 @@ env:
- CONFIG=ruby21
- CONFIG=ruby22
- CONFIG=jruby
- CONFIG=php5.6_mac
matrix:
exclude:
# It's nontrivial to programmatically install a new JDK from the command

@ -391,8 +391,10 @@ RELATIVE_TEST_PROTOS = [
"google/protobuf/util/internal/testdata/field_mask.proto",
"google/protobuf/util/internal/testdata/maps.proto",
"google/protobuf/util/internal/testdata/oneofs.proto",
"google/protobuf/util/internal/testdata/proto3.proto",
"google/protobuf/util/internal/testdata/struct.proto",
"google/protobuf/util/internal/testdata/timestamp_duration.proto",
"google/protobuf/util/internal/testdata/wrappers.proto",
"google/protobuf/util/json_format_proto3.proto",
"google/protobuf/util/message_differencer_unittest.proto",
]

@ -1,3 +1,83 @@
2016-09-23 version 3.1.0 (C++/Java/Python/PHP/Ruby/Objective-C/C#/JavaScript/Lite)
General
* Proto3 support in PHP (alpha).
* Various bug fixes.
C++
* Added MessageLite::ByteSizeLong() that’s equivalent to
MessageLite::ByteSize() but returns the value in size_t. Useful to check
whether a message is over the 2G size limit that protobuf can support.
* Moved default_instances to global variables. This allows default_instance
addresses to be known at compile time.
* Adding missing generic gcc 64-bit atomicops.
* Restore New*Callback into google::protobuf namespace since these are used
by the service stubs code
* JSON support.
* Fixed some conformance issues.
* Fixed a JSON serialization bug for bytes fields.
Java
* Fixed a bug in TextFormat that doesn’t accept empty repeated fields (i.e.,
“field: [ ]”).
* JSON support
* Fixed JsonFormat to do correct snake_case-to-camelCase conversion for
non-style-conforming field names.
* Fixed JsonFormat to parse empty Any message correctly.
* Added an option to JsonFormat.Parser to ignore unknown fields.
* Experimental API
* Added UnsafeByteOperations.unsafeWrap(byte[]) to wrap a byte array into
ByteString without copy.
Python
* JSON support
* Fixed some conformance issues.
PHP (Alpha)
* We have added the proto3 support for PHP via both a pure PHP package and a
native c extension. The pure PHP package is intended to provide usability
to wider range of PHP platforms, while the c extension is intended to
provide higher performance. Both implementations provide the same runtime
APIs and share the same generated code. Users don’t need to re-generate
code for the same proto definition when they want to switch the
implementation later. The pure PHP package is included in the php/src
directory, and the c extension is included in the php/ext directory.
Both implementations provide idiomatic PHP APIs:
* All messages and enums are defined as PHP classes.
* All message fields can only be accessed via getter/setter.
* Both repeated field elements and map elements are stored in containers
that act like a normal PHP array.
Unlike several existing third-party PHP implementations for protobuf, our
implementations are built on a "strongly-typed" philosophy: message fields
and array/map containers will throw exceptions eagerly when values of the
incorrect type (not including those that can be type converted, e.g.,
double <-> integer <-> numeric string) are inserted.
Currently, pure PHP runtime supports php5.5, 5.6 and 7 on linux. C
extension runtime supports php5.5 and 5.6 on linux.
See php/README.md for more details about installment. See
https://developers.google.com/protocol-buffers/docs/phptutorial for more
details about APIs.
Objective-C
* Helpers are now provided for working the the Any well known type (see
GPBWellKnownTypes.h for the api additions).
* Some improvements in startup code (especially when extensions aren’t used).
Javascript
* Fixed missing import of jspb.Map
* Fixed valueWriterFn variable name
Ruby
* Fixed hash computation for JRuby's RubyMessage
* Make sure map parsing frames are GC-rooted.
* Added API support for well-known types.
C#
* Removed check on dependency in the C# reflection API.
2016-09-06 version 3.0.2 (C++/Java/Python/Ruby/Objective-C/C#/JavaScript/Lite)
General
* Various bug fixes.

@ -54,6 +54,7 @@ csharp_EXTRA_DIST= \
csharp/Google.Protobuf.Tools.nuspec \
csharp/README.md \
csharp/build_packages.bat \
csharp/build_tools.sh \
csharp/buildall.sh \
csharp/generate_protos.sh \
csharp/keys/Google.Protobuf.public.snk \
@ -571,6 +572,57 @@ objectivec_EXTRA_DIST= \
objectivec/Tests/UnitTests-Info.plist \
Protobuf.podspec
php_EXTRA_DIST= \
php/src/phpdoc.dist.xml \
php/src/Google/Protobuf/Internal/DescriptorPool.php \
php/src/Google/Protobuf/Internal/OneofField.php \
php/src/Google/Protobuf/Internal/MapEntry.php \
php/src/Google/Protobuf/Internal/Type.php \
php/src/Google/Protobuf/Internal/InputStream.php \
php/src/Google/Protobuf/Internal/OutputStream.php \
php/src/Google/Protobuf/Internal/MessageBuilderContext.php \
php/src/Google/Protobuf/Internal/MapField.php \
php/src/Google/Protobuf/Internal/RepeatedField.php \
php/src/Google/Protobuf/Internal/Message.php \
php/src/Google/Protobuf/Internal/GPBWire.php \
php/src/Google/Protobuf/Internal/GPBType.php \
php/src/Google/Protobuf/Internal/GPBLabel.php \
php/src/Google/Protobuf/Internal/EnumBuilderContext.php \
php/src/Google/Protobuf/Internal/GPBUtil.php \
php/src/Google/Protobuf/descriptor_internal.pb.php \
php/src/Google/Protobuf/descriptor.php \
php/tests/encode_decode_test.php \
php/tests/test.sh \
php/tests/generated_class_test.php \
php/tests/array_test.php \
php/tests/php_implementation_test.php \
php/tests/test_include.proto \
php/tests/test_include.pb.php \
php/tests/map_field_test.php \
php/tests/test_base.php \
php/tests/test_util.php \
php/tests/test.proto \
php/tests/test.pb.php \
php/tests/memory_leak_test.php \
php/README.md \
php/ext/google/protobuf/utf8.h \
php/ext/google/protobuf/message.c \
php/ext/google/protobuf/utf8.c \
php/ext/google/protobuf/package.xml \
php/ext/google/protobuf/upb.h \
php/ext/google/protobuf/array.c \
php/ext/google/protobuf/encode_decode.c \
php/ext/google/protobuf/protobuf.h \
php/ext/google/protobuf/type_check.c \
php/ext/google/protobuf/def.c \
php/ext/google/protobuf/storage.c \
php/ext/google/protobuf/map.c \
php/ext/google/protobuf/config.m4 \
php/ext/google/protobuf/upb.c \
php/ext/google/protobuf/protobuf.c \
phpunit.xml \
composer.json
python_EXTRA_DIST= \
python/MANIFEST.in \
python/google/__init__.py \
@ -617,6 +669,7 @@ python_EXTRA_DIST= \
python/google/protobuf/internal/symbol_database_test.py \
python/google/protobuf/internal/test_bad_identifiers.proto \
python/google/protobuf/internal/test_util.py \
python/google/protobuf/internal/testing_refleaks.py \
python/google/protobuf/internal/text_encoding_test.py \
python/google/protobuf/internal/text_format_test.py \
python/google/protobuf/internal/type_checkers.py \
@ -648,6 +701,8 @@ python_EXTRA_DIST= \
python/google/protobuf/pyext/map_container.h \
python/google/protobuf/pyext/message.cc \
python/google/protobuf/pyext/message.h \
python/google/protobuf/pyext/message_factory.cc \
python/google/protobuf/pyext/message_factory.h \
python/google/protobuf/pyext/message_module.cc \
python/google/protobuf/pyext/proto2_api_test.proto \
python/google/protobuf/pyext/python.proto \
@ -748,6 +803,7 @@ js_EXTRA_DIST= \
js/gulpfile.js \
js/jasmine.json \
js/map.js \
js/maps_test.js \
js/message.js \
js/message_test.js \
js/node_loader.js \
@ -763,7 +819,7 @@ js_EXTRA_DIST= \
js/testbinary.proto \
js/testempty.proto
all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(javanano_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) $(js_EXTRA_DIST)
all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(javanano_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) $(js_EXTRA_DIST)
EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
autogen.sh \

@ -5,7 +5,7 @@
# dependent projects use the :git notation to refer to the library.
Pod::Spec.new do |s|
s.name = 'Protobuf'
s.version = '3.0.2'
s.version = '3.1.0'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/google/protobuf'
s.license = 'New BSD'

@ -20,16 +20,16 @@ environment:
test: off
install:
- ps: Start-FileDownload https://github.com/google/googlemock/archive/release-1.7.0.zip
- curl -L -o release-1.7.0.zip https://github.com/google/googlemock/archive/release-1.7.0.zip
- 7z x release-1.7.0.zip
- del /Q release-1.7.0.zip
- rename googlemock-release-1.7.0 gmock
- ps: Start-FileDownload https://github.com/google/googletest/archive/release-1.7.0.zip
- curl -L -o release-1.7.0.zip "https://github.com/google/googletest/archive/release-1.7.0.zip"
- 7z x release-1.7.0.zip
- del /Q release-1.7.0.zip
- rename googletest-release-1.7.0 gtest
- move gtest gmock
- ps: Start-FileDownload https://go.microsoft.com/fwlink/?LinkID=809122 -FileName dotnetsdk.exe
- curl -L -o dotnetsdk.exe "https://go.microsoft.com/fwlink/?LinkID=809122"
- dotnetsdk.exe /install /quiet /norestart
before_build:

@ -49,6 +49,7 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflect
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h include\google\protobuf\generated_enum_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h include\google\protobuf\generated_message_reflection.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h include\google\protobuf\generated_message_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h include\google\protobuf\has_bits.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h include\google\protobuf\io\coded_stream.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h include\google\protobuf\io\gzip_stream.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\printer.h include\google\protobuf\io\printer.h

@ -63,8 +63,10 @@ set(tests_protos
google/protobuf/util/internal/testdata/field_mask.proto
google/protobuf/util/internal/testdata/maps.proto
google/protobuf/util/internal/testdata/oneofs.proto
google/protobuf/util/internal/testdata/proto3.proto
google/protobuf/util/internal/testdata/struct.proto
google/protobuf/util/internal/testdata/timestamp_duration.proto
google/protobuf/util/internal/testdata/wrappers.proto
google/protobuf/util/json_format_proto3.proto
google/protobuf/util/message_differencer_unittest.proto
)

@ -17,7 +17,7 @@ AC_PREREQ(2.59)
# In the SVN trunk, the version should always be the next anticipated release
# version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed
# the size of one file name in the dist tarfile over the 99-char limit.)
AC_INIT([Protocol Buffers],[3.0.2],[protobuf@googlegroups.com],[protobuf])
AC_INIT([Protocol Buffers],[3.1.0],[protobuf@googlegroups.com],[protobuf])
AM_MAINTAINER_MODE([enable])
@ -31,7 +31,7 @@ AC_CONFIG_MACRO_DIR([m4])
AC_ARG_VAR(DIST_LANG, [language to include in the distribution package (i.e., make dist)])
case "$DIST_LANG" in
"") DIST_LANG=all ;;
all | cpp | csharp | java | python | javanano | objectivec | ruby | js) ;;
all | cpp | csharp | java | python | javanano | objectivec | ruby | js | php) ;;
*) AC_MSG_FAILURE([unknown language: $DIST_LANG]) ;;
esac
AC_SUBST(DIST_LANG)

@ -251,31 +251,31 @@ conformance-csharp: $(other_language_protoc_outputs)
# Targets for actually running tests.
test_cpp: protoc_middleman conformance-test-runner conformance-cpp
./conformance-test-runner --failure_list failure_list_cpp.txt ./conformance-cpp
./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt ./conformance-cpp
test_java: protoc_middleman conformance-test-runner conformance-java
./conformance-test-runner --failure_list failure_list_java.txt ./conformance-java
./conformance-test-runner --enforce_recommended --failure_list failure_list_java.txt ./conformance-java
test_java_lite: protoc_middleman conformance-test-runner conformance-java-lite
./conformance-test-runner ./conformance-java-lite
./conformance-test-runner --enforce_recommended ./conformance-java-lite
test_csharp: protoc_middleman conformance-test-runner conformance-csharp
./conformance-test-runner --failure_list failure_list_csharp.txt ./conformance-csharp
./conformance-test-runner --enforce_recommended --failure_list failure_list_csharp.txt ./conformance-csharp
test_ruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs)
RUBYLIB=../ruby/lib:. ./conformance-test-runner --failure_list failure_list_ruby.txt ./conformance_ruby.rb
RUBYLIB=../ruby/lib:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_ruby.txt ./conformance_ruby.rb
# These depend on library paths being properly set up. The easiest way to
# run them is to just use "tox" from the python dir.
test_python: protoc_middleman conformance-test-runner
./conformance-test-runner --failure_list failure_list_python.txt ./conformance_python.py
./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt ./conformance_python.py
test_python_cpp: protoc_middleman conformance-test-runner
./conformance-test-runner --failure_list failure_list_python_cpp.txt ./conformance_python.py
./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt ./conformance_python.py
if OBJC_CONFORMANCE_TEST
test_objc: protoc_middleman conformance-test-runner conformance-objc
./conformance-test-runner --failure_list failure_list_objc.txt ./conformance-objc
./conformance-test-runner --enforce_recommended --failure_list failure_list_objc.txt ./conformance-objc
endif

@ -67,7 +67,7 @@ def do_test(request):
elif request.WhichOneof('payload') == 'json_payload':
try:
json_format.Parse(request.json_payload, test_message)
except json_format.ParseError as e:
except Exception as e:
response.parse_error = str(e)
return response
@ -81,7 +81,11 @@ def do_test(request):
response.protobuf_payload = test_message.SerializeToString()
elif request.requested_output_format == conformance_pb2.JSON:
response.json_payload = json_format.MessageToJson(test_message)
try:
response.json_payload = json_format.MessageToJson(test_message)
except Exception as e:
response.serialize_error = str(e)
return response
except Exception as e:
response.runtime_error = str(e)

File diff suppressed because it is too large Load Diff

@ -91,7 +91,7 @@ class ConformanceTestRunner {
//
class ConformanceTestSuite {
public:
ConformanceTestSuite() : verbose_(false) {}
ConformanceTestSuite() : verbose_(false), enforce_recommended_(false) {}
void SetVerbose(bool verbose) { verbose_ = verbose; }
@ -104,6 +104,18 @@ class ConformanceTestSuite {
void SetFailureList(const std::string& filename,
const std::vector<std::string>& failure_list);
// Whether to require the testee to pass RECOMMENDED tests. By default failing
// a RECOMMENDED test case will not fail the entire suite but will only
// generated a warning. If this flag is set to true, RECOMMENDED tests will
// be treated the same way as REQUIRED tests and failing a RECOMMENDED test
// case will cause the entire test suite to fail as well. An implementation
// can enable this if it wants to be strictly conforming to protobuf spec.
// See the comments about ConformanceLevel below to learn more about the
// difference between REQUIRED and RECOMMENDED test cases.
void SetEnforceRecommended(bool value) {
enforce_recommended_ = value;
}
// Run all the conformance tests against the given test runner.
// Test output will be stored in "output".
//
@ -113,8 +125,27 @@ class ConformanceTestSuite {
bool RunSuite(ConformanceTestRunner* runner, std::string* output);
private:
// Test cases are classified into a few categories:
// REQUIRED: the test case must be passed for an implementation to be
// interoperable with other implementations. For example, a
// parser implementaiton must accept both packed and unpacked
// form of repeated primitive fields.
// RECOMMENDED: the test case is not required for the implementation to
// be interoperable with other implementations, but is
// recommended for best performance and compatibility. For
// example, a proto3 serializer should serialize repeated
// primitive fields in packed form, but an implementation
// failing to do so will still be able to communicate with
// other implementations.
enum ConformanceLevel {
REQUIRED = 0,
RECOMMENDED = 1,
};
string ConformanceLevelToString(ConformanceLevel level);
void ReportSuccess(const std::string& test_name);
void ReportFailure(const string& test_name,
ConformanceLevel level,
const conformance::ConformanceRequest& request,
const conformance::ConformanceResponse& response,
const char* fmt, ...);
@ -124,31 +155,42 @@ class ConformanceTestSuite {
void RunTest(const std::string& test_name,
const conformance::ConformanceRequest& request,
conformance::ConformanceResponse* response);
void RunValidInputTest(const string& test_name, const string& input,
void RunValidInputTest(const string& test_name,
ConformanceLevel level,
const string& input,
conformance::WireFormat input_format,
const string& equivalent_text_format,
conformance::WireFormat requested_output);
void RunValidJsonTest(const string& test_name, const string& input_json,
void RunValidJsonTest(const string& test_name,
ConformanceLevel level,
const string& input_json,
const string& equivalent_text_format);
void RunValidJsonTestWithProtobufInput(const string& test_name,
ConformanceLevel level,
const conformance::TestAllTypes& input,
const string& equivalent_text_format);
void RunValidProtobufTest(const string& test_name,
ConformanceLevel level,
const conformance::TestAllTypes& input,
const string& equivalent_text_format);
typedef std::function<bool(const Json::Value&)> Validator;
void RunValidJsonTestWithValidator(const string& test_name,
ConformanceLevel level,
const string& input_json,
const Validator& validator);
void ExpectParseFailureForJson(const string& test_name,
ConformanceLevel level,
const string& input_json);
void ExpectSerializeFailureForJson(const string& test_name,
ConformanceLevel level,
const string& text_format);
void ExpectParseFailureForProto(const std::string& proto,
const std::string& test_name);
const std::string& test_name,
ConformanceLevel level);
void ExpectHardParseFailureForProto(const std::string& proto,
const std::string& test_name);
const std::string& test_name,
ConformanceLevel level);
void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
bool CheckSetEmpty(const set<string>& set_to_check,
const std::string& write_to_file, const std::string& msg);
@ -156,6 +198,7 @@ class ConformanceTestSuite {
int successes_;
int expected_failures_;
bool verbose_;
bool enforce_recommended_;
std::string output_;
std::string failure_list_filename_;

@ -251,6 +251,16 @@ void UsageError() {
" should contain one test name per\n");
fprintf(stderr,
" line. Use '#' for comments.\n");
fprintf(stderr,
" --enforce_recommended Enforce that recommended test\n");
fprintf(stderr,
" cases are also passing. Specify\n");
fprintf(stderr,
" this flag if you want to be\n");
fprintf(stderr,
" strictly conforming to protobuf\n");
fprintf(stderr,
" spec.\n");
exit(1);
}
@ -290,6 +300,8 @@ int main(int argc, char *argv[]) {
ParseFailureList(argv[arg], &failure_list);
} else if (strcmp(argv[arg], "--verbose") == 0) {
suite.SetVerbose(true);
} else if (strcmp(argv[arg], "--enforce_recommended") == 0) {
suite.SetEnforceRecommended(true);
} else if (argv[arg][0] == '-') {
fprintf(stderr, "Unknown option: %s\n", argv[arg]);
UsageError();

@ -7,48 +7,47 @@
# TODO(haberman): insert links to corresponding bugs tracking the issue.
# Should we use GitHub issues or the Google-internal bug tracker?
FieldMaskNumbersDontRoundTrip.JsonOutput
FieldMaskPathsDontRoundTrip.JsonOutput
FieldMaskTooManyUnderscore.JsonOutput
JsonInput.AnyUnorderedTypeTag.JsonOutput
JsonInput.AnyUnorderedTypeTag.ProtobufOutput
JsonInput.BoolFieldDoubleQuotedFalse
JsonInput.BoolFieldDoubleQuotedTrue
JsonInput.BytesFieldNoPadding
JsonInput.DoubleFieldTooSmall
JsonInput.DurationHasZeroFractionalDigit.Validator
JsonInput.EnumFieldUnknownValue.Validator
JsonInput.FieldMaskInvalidCharacter
JsonInput.FieldNameDuplicate
JsonInput.FieldNameDuplicateDifferentCasing1
JsonInput.FieldNameDuplicateDifferentCasing2
JsonInput.FieldNameNotQuoted
JsonInput.MapFieldValueIsNull
JsonInput.RepeatedFieldMessageElementIsNull
JsonInput.RepeatedFieldPrimitiveElementIsNull
JsonInput.RepeatedFieldTrailingComma
JsonInput.RepeatedFieldTrailingCommaWithNewlines
JsonInput.RepeatedFieldTrailingCommaWithSpace
JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
JsonInput.StringFieldSingleQuoteBoth
JsonInput.StringFieldSingleQuoteKey
JsonInput.StringFieldSingleQuoteValue
JsonInput.StringFieldUppercaseEscapeLetter
JsonInput.TrailingCommaInAnObject
JsonInput.TrailingCommaInAnObjectWithNewlines
JsonInput.TrailingCommaInAnObjectWithSpace
JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
JsonInput.WrapperTypesWithNullValue.JsonOutput
JsonInput.WrapperTypesWithNullValue.ProtobufOutput
ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInPackedField.BOOL
ProtobufInput.PrematureEofInPackedField.ENUM
ProtobufInput.PrematureEofInPackedField.INT32
ProtobufInput.PrematureEofInPackedField.INT64
ProtobufInput.PrematureEofInPackedField.SINT32
ProtobufInput.PrematureEofInPackedField.SINT64
ProtobufInput.PrematureEofInPackedField.UINT32
ProtobufInput.PrematureEofInPackedField.UINT64
ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.JsonInput.FieldMaskInvalidCharacter
Recommended.JsonInput.FieldNameDuplicate
Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
Recommended.JsonInput.FieldNameNotQuoted
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
Recommended.JsonInput.MapFieldValueIsNull
Recommended.JsonInput.RepeatedFieldMessageElementIsNull
Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
Recommended.JsonInput.RepeatedFieldTrailingComma
Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines
Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace
Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
Recommended.JsonInput.StringFieldSingleQuoteBoth
Recommended.JsonInput.StringFieldSingleQuoteKey
Recommended.JsonInput.StringFieldSingleQuoteValue
Recommended.JsonInput.StringFieldUppercaseEscapeLetter
Recommended.JsonInput.TrailingCommaInAnObject
Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
Required.JsonInput.DoubleFieldTooSmall
Required.JsonInput.FieldNameInLowerCamelCase.Validator
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInPackedField.BOOL
Required.ProtobufInput.PrematureEofInPackedField.ENUM
Required.ProtobufInput.PrematureEofInPackedField.INT32
Required.ProtobufInput.PrematureEofInPackedField.INT64
Required.ProtobufInput.PrematureEofInPackedField.SINT32
Required.ProtobufInput.PrematureEofInPackedField.SINT64
Required.ProtobufInput.PrematureEofInPackedField.UINT32
Required.ProtobufInput.PrematureEofInPackedField.UINT64
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE

@ -1,4 +1,6 @@
JsonInput.FieldNameWithMixedCases.JsonOutput
JsonInput.FieldNameWithMixedCases.ProtobufOutput
JsonInput.FieldNameWithMixedCases.Validator
JsonInput.OriginalProtoFieldName.JsonOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
Required.JsonInput.FieldNameWithMixedCases.JsonOutput
Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput
Required.JsonInput.FieldNameWithMixedCases.Validator
Required.JsonInput.OriginalProtoFieldName.JsonOutput

@ -4,48 +4,46 @@
# By listing them here we can keep tabs on which ones are failing and be sure
# that we don't introduce regressions in other tests.
FieldMaskNumbersDontRoundTrip.JsonOutput
FieldMaskPathsDontRoundTrip.JsonOutput
FieldMaskTooManyUnderscore.JsonOutput
JsonInput.BoolFieldAllCapitalFalse
JsonInput.BoolFieldAllCapitalTrue
JsonInput.BoolFieldCamelCaseFalse
JsonInput.BoolFieldCamelCaseTrue
JsonInput.BoolFieldDoubleQuotedFalse
JsonInput.BoolFieldDoubleQuotedTrue
JsonInput.BoolMapFieldKeyNotQuoted
JsonInput.DoubleFieldInfinityNotQuoted
JsonInput.DoubleFieldNanNotQuoted
JsonInput.DoubleFieldNegativeInfinityNotQuoted
JsonInput.EnumFieldNotQuoted
JsonInput.FieldMaskInvalidCharacter
JsonInput.FieldNameDuplicate
JsonInput.FieldNameInLowerCamelCase.Validator
JsonInput.FieldNameInSnakeCase.JsonOutput
JsonInput.FieldNameInSnakeCase.ProtobufOutput
JsonInput.FieldNameNotQuoted
JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
JsonInput.FieldNameWithDoubleUnderscores.Validator
JsonInput.FloatFieldInfinityNotQuoted
JsonInput.FloatFieldNanNotQuoted
JsonInput.FloatFieldNegativeInfinityNotQuoted
JsonInput.Int32FieldLeadingZero
JsonInput.Int32FieldNegativeWithLeadingZero
JsonInput.Int32FieldPlusSign
JsonInput.Int32MapFieldKeyNotQuoted
JsonInput.Int64MapFieldKeyNotQuoted
JsonInput.JsonWithComments
JsonInput.OriginalProtoFieldName.JsonOutput
JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
JsonInput.StringFieldNotAString
JsonInput.StringFieldSingleQuoteBoth
JsonInput.StringFieldSingleQuoteKey
JsonInput.StringFieldSingleQuoteValue
JsonInput.StringFieldSurrogateInWrongOrder
JsonInput.StringFieldUnpairedHighSurrogate
JsonInput.StringFieldUnpairedLowSurrogate
JsonInput.StringFieldUppercaseEscapeLetter
JsonInput.Uint32MapFieldKeyNotQuoted
JsonInput.Uint64MapFieldKeyNotQuoted
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.JsonInput.BoolFieldAllCapitalFalse
Recommended.JsonInput.BoolFieldAllCapitalTrue
Recommended.JsonInput.BoolFieldCamelCaseFalse
Recommended.JsonInput.BoolFieldCamelCaseTrue
Recommended.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.JsonInput.BoolMapFieldKeyNotQuoted
Recommended.JsonInput.DoubleFieldInfinityNotQuoted
Recommended.JsonInput.DoubleFieldNanNotQuoted
Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
Recommended.JsonInput.FieldMaskInvalidCharacter
Recommended.JsonInput.FieldNameDuplicate
Recommended.JsonInput.FieldNameNotQuoted
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
Recommended.JsonInput.FloatFieldInfinityNotQuoted
Recommended.JsonInput.FloatFieldNanNotQuoted
Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
Recommended.JsonInput.Int32MapFieldKeyNotQuoted
Recommended.JsonInput.Int64MapFieldKeyNotQuoted
Recommended.JsonInput.JsonWithComments
Recommended.JsonInput.StringFieldSingleQuoteBoth
Recommended.JsonInput.StringFieldSingleQuoteKey
Recommended.JsonInput.StringFieldSingleQuoteValue
Recommended.JsonInput.StringFieldSurrogateInWrongOrder
Recommended.JsonInput.StringFieldUnpairedHighSurrogate
Recommended.JsonInput.StringFieldUnpairedLowSurrogate
Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
Required.JsonInput.EnumFieldNotQuoted
Required.JsonInput.FieldNameInLowerCamelCase.Validator
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
Required.JsonInput.Int32FieldLeadingZero
Required.JsonInput.Int32FieldNegativeWithLeadingZero
Required.JsonInput.Int32FieldPlusSign
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
Required.JsonInput.StringFieldNotAString

@ -1,46 +1,19 @@
DurationProtoInputTooLarge.JsonOutput
DurationProtoInputTooSmall.JsonOutput
FieldMaskNumbersDontRoundTrip.JsonOutput
FieldMaskPathsDontRoundTrip.JsonOutput
FieldMaskTooManyUnderscore.JsonOutput
JsonInput.AnyWithFieldMask.ProtobufOutput
JsonInput.BytesFieldInvalidBase64Characters
JsonInput.DoubleFieldInfinityNotQuoted
JsonInput.DoubleFieldNanNotQuoted
JsonInput.DoubleFieldNegativeInfinityNotQuoted
JsonInput.DoubleFieldTooSmall
JsonInput.DurationJsonInputTooLarge
JsonInput.DurationJsonInputTooSmall
JsonInput.DurationMissingS
JsonInput.EnumFieldNumericValueNonZero.JsonOutput
JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
JsonInput.EnumFieldNumericValueZero.JsonOutput
JsonInput.EnumFieldNumericValueZero.ProtobufOutput
JsonInput.EnumFieldUnknownValue.Validator
JsonInput.FieldMask.ProtobufOutput
JsonInput.FieldMaskInvalidCharacter
JsonInput.FloatFieldInfinityNotQuoted
JsonInput.FloatFieldNanNotQuoted
JsonInput.FloatFieldNegativeInfinityNotQuoted
JsonInput.FloatFieldTooLarge
JsonInput.FloatFieldTooSmall
JsonInput.Int32FieldExponentialFormat.JsonOutput
JsonInput.Int32FieldExponentialFormat.ProtobufOutput
JsonInput.Int32FieldFloatTrailingZero.JsonOutput
JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
JsonInput.Int32FieldMaxFloatValue.JsonOutput
JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
JsonInput.Int32FieldMinFloatValue.JsonOutput
JsonInput.Int32FieldMinFloatValue.ProtobufOutput
JsonInput.OneofZeroMessage.JsonOutput
JsonInput.OneofZeroMessage.ProtobufOutput
JsonInput.OriginalProtoFieldName.JsonOutput
JsonInput.OriginalProtoFieldName.ProtobufOutput
JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
JsonInput.TimestampJsonInputLowercaseT
JsonInput.Uint32FieldMaxFloatValue.JsonOutput
JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
JsonInput.ValueAcceptNull.JsonOutput
JsonInput.ValueAcceptNull.ProtobufOutput
TimestampProtoInputTooLarge.JsonOutput
TimestampProtoInputTooSmall.JsonOutput
Recommended.JsonInput.DoubleFieldInfinityNotQuoted
Recommended.JsonInput.DoubleFieldNanNotQuoted
Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
Recommended.JsonInput.FloatFieldInfinityNotQuoted
Recommended.JsonInput.FloatFieldNanNotQuoted
Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
Required.JsonInput.BytesFieldInvalidBase64Characters
Required.JsonInput.DoubleFieldTooSmall
Required.JsonInput.EnumFieldUnknownValue.Validator
Required.JsonInput.FieldNameInLowerCamelCase.Validator
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
Required.JsonInput.FloatFieldTooLarge
Required.JsonInput.FloatFieldTooSmall
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
Required.JsonInput.TimestampJsonInputLowercaseT

@ -7,65 +7,38 @@
# TODO(haberman): insert links to corresponding bugs tracking the issue.
# Should we use GitHub issues or the Google-internal bug tracker?
DurationProtoInputTooLarge.JsonOutput
DurationProtoInputTooSmall.JsonOutput
FieldMaskNumbersDontRoundTrip.JsonOutput
FieldMaskPathsDontRoundTrip.JsonOutput
FieldMaskTooManyUnderscore.JsonOutput
JsonInput.AnyWithFieldMask.ProtobufOutput
JsonInput.BytesFieldInvalidBase64Characters
JsonInput.DoubleFieldInfinityNotQuoted
JsonInput.DoubleFieldNanNotQuoted
JsonInput.DoubleFieldNegativeInfinityNotQuoted
JsonInput.DoubleFieldTooSmall
JsonInput.DurationJsonInputTooLarge
JsonInput.DurationJsonInputTooSmall
JsonInput.DurationMissingS
JsonInput.EnumFieldNumericValueNonZero.JsonOutput
JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
JsonInput.EnumFieldNumericValueZero.JsonOutput
JsonInput.EnumFieldNumericValueZero.ProtobufOutput
JsonInput.EnumFieldUnknownValue.Validator
JsonInput.FieldMask.ProtobufOutput
JsonInput.FieldMaskInvalidCharacter
JsonInput.FloatFieldInfinityNotQuoted
JsonInput.FloatFieldNanNotQuoted
JsonInput.FloatFieldNegativeInfinityNotQuoted
JsonInput.FloatFieldTooLarge
JsonInput.FloatFieldTooSmall
JsonInput.Int32FieldExponentialFormat.JsonOutput
JsonInput.Int32FieldExponentialFormat.ProtobufOutput
JsonInput.Int32FieldFloatTrailingZero.JsonOutput
JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
JsonInput.Int32FieldMaxFloatValue.JsonOutput
JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
JsonInput.Int32FieldMinFloatValue.JsonOutput
JsonInput.Int32FieldMinFloatValue.ProtobufOutput
JsonInput.OneofZeroMessage.JsonOutput
JsonInput.OneofZeroMessage.ProtobufOutput
JsonInput.OriginalProtoFieldName.JsonOutput
JsonInput.OriginalProtoFieldName.ProtobufOutput
JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
JsonInput.TimestampJsonInputLowercaseT
JsonInput.Uint32FieldMaxFloatValue.JsonOutput
JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
JsonInput.ValueAcceptNull.JsonOutput
JsonInput.ValueAcceptNull.ProtobufOutput
ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInPackedField.BOOL
ProtobufInput.PrematureEofInPackedField.DOUBLE
ProtobufInput.PrematureEofInPackedField.ENUM
ProtobufInput.PrematureEofInPackedField.FIXED32
ProtobufInput.PrematureEofInPackedField.FIXED64
ProtobufInput.PrematureEofInPackedField.FLOAT
ProtobufInput.PrematureEofInPackedField.INT32
ProtobufInput.PrematureEofInPackedField.INT64
ProtobufInput.PrematureEofInPackedField.SFIXED32
ProtobufInput.PrematureEofInPackedField.SFIXED64
ProtobufInput.PrematureEofInPackedField.SINT32
ProtobufInput.PrematureEofInPackedField.SINT64
ProtobufInput.PrematureEofInPackedField.UINT32
ProtobufInput.PrematureEofInPackedField.UINT64
TimestampProtoInputTooLarge.JsonOutput
TimestampProtoInputTooSmall.JsonOutput
Recommended.JsonInput.DoubleFieldInfinityNotQuoted
Recommended.JsonInput.DoubleFieldNanNotQuoted
Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
Recommended.JsonInput.FloatFieldInfinityNotQuoted
Recommended.JsonInput.FloatFieldNanNotQuoted
Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
Required.JsonInput.BytesFieldInvalidBase64Characters
Required.JsonInput.DoubleFieldTooSmall
Required.JsonInput.EnumFieldUnknownValue.Validator
Required.JsonInput.FieldNameInLowerCamelCase.Validator
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
Required.JsonInput.FloatFieldTooLarge
Required.JsonInput.FloatFieldTooSmall
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
Required.JsonInput.TimestampJsonInputLowercaseT
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
Required.ProtobufInput.PrematureEofInPackedField.BOOL
Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
Required.ProtobufInput.PrematureEofInPackedField.ENUM
Required.ProtobufInput.PrematureEofInPackedField.FIXED32
Required.ProtobufInput.PrematureEofInPackedField.FIXED64
Required.ProtobufInput.PrematureEofInPackedField.FLOAT
Required.ProtobufInput.PrematureEofInPackedField.INT32
Required.ProtobufInput.PrematureEofInPackedField.INT64
Required.ProtobufInput.PrematureEofInPackedField.SFIXED32
Required.ProtobufInput.PrematureEofInPackedField.SFIXED64
Required.ProtobufInput.PrematureEofInPackedField.SINT32
Required.ProtobufInput.PrematureEofInPackedField.SINT64
Required.ProtobufInput.PrematureEofInPackedField.UINT32
Required.ProtobufInput.PrematureEofInPackedField.UINT64

@ -1,213 +1,209 @@
DurationProtoInputTooLarge.JsonOutput
DurationProtoInputTooSmall.JsonOutput
FieldMaskNumbersDontRoundTrip.JsonOutput
FieldMaskPathsDontRoundTrip.JsonOutput
FieldMaskTooManyUnderscore.JsonOutput
JsonInput.Any.JsonOutput
JsonInput.Any.ProtobufOutput
JsonInput.AnyNested.JsonOutput
JsonInput.AnyNested.ProtobufOutput
JsonInput.AnyUnorderedTypeTag.JsonOutput
JsonInput.AnyUnorderedTypeTag.ProtobufOutput
JsonInput.AnyWithDuration.JsonOutput
JsonInput.AnyWithDuration.ProtobufOutput
JsonInput.AnyWithFieldMask.JsonOutput
JsonInput.AnyWithFieldMask.ProtobufOutput
JsonInput.AnyWithInt32ValueWrapper.JsonOutput
JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
JsonInput.AnyWithStruct.JsonOutput
JsonInput.AnyWithStruct.ProtobufOutput
JsonInput.AnyWithTimestamp.JsonOutput
JsonInput.AnyWithTimestamp.ProtobufOutput
JsonInput.AnyWithValueForInteger.JsonOutput
JsonInput.AnyWithValueForInteger.ProtobufOutput
JsonInput.AnyWithValueForJsonObject.JsonOutput
JsonInput.AnyWithValueForJsonObject.ProtobufOutput
JsonInput.BoolFieldIntegerOne
JsonInput.BoolFieldIntegerZero
JsonInput.DoubleFieldInfinity.JsonOutput
JsonInput.DoubleFieldInfinity.ProtobufOutput
JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
JsonInput.DoubleFieldMinNegativeValue.JsonOutput
JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
JsonInput.DoubleFieldMinPositiveValue.JsonOutput
JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
JsonInput.DoubleFieldNan.JsonOutput
JsonInput.DoubleFieldNan.ProtobufOutput
JsonInput.DoubleFieldNegativeInfinity.JsonOutput
JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
JsonInput.DoubleFieldQuotedValue.JsonOutput
JsonInput.DoubleFieldQuotedValue.ProtobufOutput
JsonInput.DurationHas3FractionalDigits.Validator
JsonInput.DurationHas6FractionalDigits.Validator
JsonInput.DurationHas9FractionalDigits.Validator
JsonInput.DurationHasZeroFractionalDigit.Validator
JsonInput.DurationMaxValue.JsonOutput
JsonInput.DurationMaxValue.ProtobufOutput
JsonInput.DurationMinValue.JsonOutput
JsonInput.DurationMinValue.ProtobufOutput
JsonInput.DurationRepeatedValue.JsonOutput
JsonInput.DurationRepeatedValue.ProtobufOutput
JsonInput.EnumFieldNumericValueNonZero.JsonOutput
JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
JsonInput.EnumFieldNumericValueZero.JsonOutput
JsonInput.EnumFieldNumericValueZero.ProtobufOutput
JsonInput.EnumFieldUnknownValue.Validator
JsonInput.FieldMask.JsonOutput
JsonInput.FieldMask.ProtobufOutput
JsonInput.FieldNameInLowerCamelCase.Validator
JsonInput.FieldNameInSnakeCase.JsonOutput
JsonInput.FieldNameInSnakeCase.ProtobufOutput
JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
JsonInput.FieldNameWithDoubleUnderscores.Validator
JsonInput.FieldNameWithMixedCases.JsonOutput
JsonInput.FieldNameWithMixedCases.ProtobufOutput
JsonInput.FieldNameWithMixedCases.Validator
JsonInput.FloatFieldInfinity.JsonOutput
JsonInput.FloatFieldInfinity.ProtobufOutput
JsonInput.FloatFieldNan.JsonOutput
JsonInput.FloatFieldNan.ProtobufOutput
JsonInput.FloatFieldNegativeInfinity.JsonOutput
JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
JsonInput.FloatFieldQuotedValue.JsonOutput
JsonInput.FloatFieldQuotedValue.ProtobufOutput
JsonInput.FloatFieldTooLarge
JsonInput.FloatFieldTooSmall
JsonInput.Int32FieldExponentialFormat.JsonOutput
JsonInput.Int32FieldExponentialFormat.ProtobufOutput
JsonInput.Int32FieldFloatTrailingZero.JsonOutput
JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
JsonInput.Int32FieldMaxFloatValue.JsonOutput
JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
JsonInput.Int32FieldMinFloatValue.JsonOutput
JsonInput.Int32FieldMinFloatValue.ProtobufOutput
JsonInput.Int32FieldStringValue.JsonOutput
JsonInput.Int32FieldStringValue.ProtobufOutput
JsonInput.Int32FieldStringValueEscaped.JsonOutput
JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
JsonInput.Int32MapEscapedKey.JsonOutput
JsonInput.Int32MapEscapedKey.ProtobufOutput
JsonInput.Int32MapField.JsonOutput
JsonInput.Int32MapField.ProtobufOutput
JsonInput.Int64FieldBeString.Validator
JsonInput.Int64FieldMaxValue.JsonOutput
JsonInput.Int64FieldMaxValue.ProtobufOutput
JsonInput.Int64FieldMinValue.JsonOutput
JsonInput.Int64FieldMinValue.ProtobufOutput
JsonInput.Int64MapEscapedKey.JsonOutput
JsonInput.Int64MapEscapedKey.ProtobufOutput
JsonInput.Int64MapField.JsonOutput
JsonInput.Int64MapField.ProtobufOutput
JsonInput.MessageField.JsonOutput
JsonInput.MessageField.ProtobufOutput
JsonInput.MessageMapField.JsonOutput
JsonInput.MessageMapField.ProtobufOutput
JsonInput.MessageRepeatedField.JsonOutput
JsonInput.MessageRepeatedField.ProtobufOutput
JsonInput.OneofZeroDouble.JsonOutput
JsonInput.OneofZeroDouble.ProtobufOutput
JsonInput.OneofZeroFloat.JsonOutput
JsonInput.OneofZeroFloat.ProtobufOutput
JsonInput.OneofZeroUint32.JsonOutput
JsonInput.OneofZeroUint32.ProtobufOutput
JsonInput.OneofZeroUint64.JsonOutput
JsonInput.OneofZeroUint64.ProtobufOutput
JsonInput.OptionalBoolWrapper.JsonOutput
JsonInput.OptionalBoolWrapper.ProtobufOutput
JsonInput.OptionalBytesWrapper.JsonOutput
JsonInput.OptionalBytesWrapper.ProtobufOutput
JsonInput.OptionalDoubleWrapper.JsonOutput
JsonInput.OptionalDoubleWrapper.ProtobufOutput
JsonInput.OptionalFloatWrapper.JsonOutput
JsonInput.OptionalFloatWrapper.ProtobufOutput
JsonInput.OptionalInt32Wrapper.JsonOutput
JsonInput.OptionalInt32Wrapper.ProtobufOutput
JsonInput.OptionalInt64Wrapper.JsonOutput
JsonInput.OptionalInt64Wrapper.ProtobufOutput
JsonInput.OptionalStringWrapper.JsonOutput
JsonInput.OptionalStringWrapper.ProtobufOutput
JsonInput.OptionalUint32Wrapper.JsonOutput
JsonInput.OptionalUint32Wrapper.ProtobufOutput
JsonInput.OptionalUint64Wrapper.JsonOutput
JsonInput.OptionalUint64Wrapper.ProtobufOutput
JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
JsonInput.OriginalProtoFieldName.JsonOutput
JsonInput.PrimitiveRepeatedField.JsonOutput
JsonInput.PrimitiveRepeatedField.ProtobufOutput
JsonInput.RepeatedBoolWrapper.JsonOutput
JsonInput.RepeatedBoolWrapper.ProtobufOutput
JsonInput.RepeatedBytesWrapper.JsonOutput
JsonInput.RepeatedBytesWrapper.ProtobufOutput
JsonInput.RepeatedDoubleWrapper.JsonOutput
JsonInput.RepeatedDoubleWrapper.ProtobufOutput
JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
JsonInput.RepeatedFloatWrapper.JsonOutput
JsonInput.RepeatedFloatWrapper.ProtobufOutput
JsonInput.RepeatedInt32Wrapper.JsonOutput
JsonInput.RepeatedInt32Wrapper.ProtobufOutput
JsonInput.RepeatedInt64Wrapper.JsonOutput
JsonInput.RepeatedInt64Wrapper.ProtobufOutput
JsonInput.RepeatedStringWrapper.JsonOutput
JsonInput.RepeatedStringWrapper.ProtobufOutput
JsonInput.RepeatedUint32Wrapper.JsonOutput
JsonInput.RepeatedUint32Wrapper.ProtobufOutput
JsonInput.RepeatedUint64Wrapper.JsonOutput
JsonInput.RepeatedUint64Wrapper.ProtobufOutput
JsonInput.StringEndsWithEscapeChar
JsonInput.StringFieldNotAString
JsonInput.StringFieldSurrogateInWrongOrder
JsonInput.StringFieldSurrogatePair.JsonOutput
JsonInput.StringFieldSurrogatePair.ProtobufOutput
JsonInput.StringFieldUnpairedHighSurrogate
JsonInput.StringFieldUnpairedLowSurrogate
JsonInput.Struct.JsonOutput
JsonInput.Struct.ProtobufOutput
JsonInput.TimestampHas3FractionalDigits.Validator
JsonInput.TimestampHas6FractionalDigits.Validator
JsonInput.TimestampHas9FractionalDigits.Validator
JsonInput.TimestampHasZeroFractionalDigit.Validator
JsonInput.TimestampMaxValue.JsonOutput
JsonInput.TimestampMaxValue.ProtobufOutput
JsonInput.TimestampMinValue.JsonOutput
JsonInput.TimestampMinValue.ProtobufOutput
JsonInput.TimestampRepeatedValue.JsonOutput
JsonInput.TimestampRepeatedValue.ProtobufOutput
JsonInput.TimestampWithNegativeOffset.JsonOutput
JsonInput.TimestampWithNegativeOffset.ProtobufOutput
JsonInput.TimestampWithPositiveOffset.JsonOutput
JsonInput.TimestampWithPositiveOffset.ProtobufOutput
JsonInput.TimestampZeroNormalized.Validator
JsonInput.Uint32FieldMaxFloatValue.JsonOutput
JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
JsonInput.Uint32MapField.JsonOutput
JsonInput.Uint32MapField.ProtobufOutput
JsonInput.Uint64FieldBeString.Validator
JsonInput.Uint64FieldMaxValue.JsonOutput
JsonInput.Uint64FieldMaxValue.ProtobufOutput
JsonInput.Uint64MapField.JsonOutput
JsonInput.Uint64MapField.ProtobufOutput
JsonInput.ValueAcceptBool.JsonOutput
JsonInput.ValueAcceptBool.ProtobufOutput
JsonInput.ValueAcceptFloat.JsonOutput
JsonInput.ValueAcceptFloat.ProtobufOutput
JsonInput.ValueAcceptInteger.JsonOutput
JsonInput.ValueAcceptInteger.ProtobufOutput
JsonInput.ValueAcceptList.JsonOutput
JsonInput.ValueAcceptList.ProtobufOutput
JsonInput.ValueAcceptNull.JsonOutput
JsonInput.ValueAcceptNull.ProtobufOutput
JsonInput.ValueAcceptObject.JsonOutput
JsonInput.ValueAcceptObject.ProtobufOutput
JsonInput.ValueAcceptString.JsonOutput
JsonInput.ValueAcceptString.ProtobufOutput
ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
TimestampProtoInputTooLarge.JsonOutput
TimestampProtoInputTooSmall.JsonOutput
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.JsonInput.BoolFieldIntegerOne
Recommended.JsonInput.BoolFieldIntegerZero
Recommended.JsonInput.DurationHas3FractionalDigits.Validator
Recommended.JsonInput.DurationHas6FractionalDigits.Validator
Recommended.JsonInput.DurationHas9FractionalDigits.Validator
Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
Recommended.JsonInput.Int64FieldBeString.Validator
Recommended.JsonInput.OneofZeroDouble.JsonOutput
Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
Recommended.JsonInput.OneofZeroFloat.JsonOutput
Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
Recommended.JsonInput.OneofZeroUint32.JsonOutput
Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
Recommended.JsonInput.OneofZeroUint64.JsonOutput
Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
Recommended.JsonInput.StringEndsWithEscapeChar
Recommended.JsonInput.StringFieldSurrogateInWrongOrder
Recommended.JsonInput.StringFieldUnpairedHighSurrogate
Recommended.JsonInput.StringFieldUnpairedLowSurrogate
Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
Recommended.JsonInput.TimestampZeroNormalized.Validator
Recommended.JsonInput.Uint64FieldBeString.Validator
Required.DurationProtoInputTooLarge.JsonOutput
Required.DurationProtoInputTooSmall.JsonOutput
Required.JsonInput.Any.JsonOutput
Required.JsonInput.Any.ProtobufOutput
Required.JsonInput.AnyNested.JsonOutput
Required.JsonInput.AnyNested.ProtobufOutput
Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
Required.JsonInput.AnyWithDuration.JsonOutput
Required.JsonInput.AnyWithDuration.ProtobufOutput
Required.JsonInput.AnyWithFieldMask.JsonOutput
Required.JsonInput.AnyWithFieldMask.ProtobufOutput
Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
Required.JsonInput.AnyWithStruct.JsonOutput
Required.JsonInput.AnyWithStruct.ProtobufOutput
Required.JsonInput.AnyWithTimestamp.JsonOutput
Required.JsonInput.AnyWithTimestamp.ProtobufOutput
Required.JsonInput.AnyWithValueForInteger.JsonOutput
Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
Required.JsonInput.DoubleFieldInfinity.JsonOutput
Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
Required.JsonInput.DoubleFieldNan.JsonOutput
Required.JsonInput.DoubleFieldNan.ProtobufOutput
Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
Required.JsonInput.DurationMaxValue.JsonOutput
Required.JsonInput.DurationMaxValue.ProtobufOutput
Required.JsonInput.DurationMinValue.JsonOutput
Required.JsonInput.DurationMinValue.ProtobufOutput
Required.JsonInput.DurationRepeatedValue.JsonOutput
Required.JsonInput.DurationRepeatedValue.ProtobufOutput
Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
Required.JsonInput.EnumFieldUnknownValue.Validator
Required.JsonInput.FieldMask.JsonOutput
Required.JsonInput.FieldMask.ProtobufOutput
Required.JsonInput.FieldNameInLowerCamelCase.Validator
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
Required.JsonInput.FloatFieldInfinity.JsonOutput
Required.JsonInput.FloatFieldInfinity.ProtobufOutput
Required.JsonInput.FloatFieldNan.JsonOutput
Required.JsonInput.FloatFieldNan.ProtobufOutput
Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
Required.JsonInput.FloatFieldQuotedValue.JsonOutput
Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
Required.JsonInput.FloatFieldTooLarge
Required.JsonInput.FloatFieldTooSmall
Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
Required.JsonInput.Int32FieldStringValue.JsonOutput
Required.JsonInput.Int32FieldStringValue.ProtobufOutput
Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
Required.JsonInput.Int32MapEscapedKey.JsonOutput
Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
Required.JsonInput.Int32MapField.JsonOutput
Required.JsonInput.Int32MapField.ProtobufOutput
Required.JsonInput.Int64FieldMaxValue.JsonOutput
Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
Required.JsonInput.Int64FieldMinValue.JsonOutput
Required.JsonInput.Int64FieldMinValue.ProtobufOutput
Required.JsonInput.Int64MapEscapedKey.JsonOutput
Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
Required.JsonInput.Int64MapField.JsonOutput
Required.JsonInput.Int64MapField.ProtobufOutput
Required.JsonInput.MessageField.JsonOutput
Required.JsonInput.MessageField.ProtobufOutput
Required.JsonInput.MessageMapField.JsonOutput
Required.JsonInput.MessageMapField.ProtobufOutput
Required.JsonInput.MessageRepeatedField.JsonOutput
Required.JsonInput.MessageRepeatedField.ProtobufOutput
Required.JsonInput.OptionalBoolWrapper.JsonOutput
Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
Required.JsonInput.OptionalBytesWrapper.JsonOutput
Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
Required.JsonInput.OptionalDoubleWrapper.JsonOutput
Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
Required.JsonInput.OptionalFloatWrapper.JsonOutput
Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
Required.JsonInput.OptionalInt32Wrapper.JsonOutput
Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
Required.JsonInput.OptionalInt64Wrapper.JsonOutput
Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
Required.JsonInput.OptionalStringWrapper.JsonOutput
Required.JsonInput.OptionalStringWrapper.ProtobufOutput
Required.JsonInput.OptionalUint32Wrapper.JsonOutput
Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
Required.JsonInput.OptionalUint64Wrapper.JsonOutput
Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
Required.JsonInput.PrimitiveRepeatedField.JsonOutput
Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
Required.JsonInput.RepeatedBoolWrapper.JsonOutput
Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
Required.JsonInput.RepeatedBytesWrapper.JsonOutput
Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
Required.JsonInput.RepeatedFloatWrapper.JsonOutput
Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
Required.JsonInput.RepeatedStringWrapper.JsonOutput
Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
Required.JsonInput.StringFieldNotAString
Required.JsonInput.StringFieldSurrogatePair.JsonOutput
Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
Required.JsonInput.Struct.JsonOutput
Required.JsonInput.Struct.ProtobufOutput
Required.JsonInput.TimestampMaxValue.JsonOutput
Required.JsonInput.TimestampMaxValue.ProtobufOutput
Required.JsonInput.TimestampMinValue.JsonOutput
Required.JsonInput.TimestampMinValue.ProtobufOutput
Required.JsonInput.TimestampRepeatedValue.JsonOutput
Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
Required.JsonInput.Uint32MapField.JsonOutput
Required.JsonInput.Uint32MapField.ProtobufOutput
Required.JsonInput.Uint64FieldMaxValue.JsonOutput
Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
Required.JsonInput.Uint64MapField.JsonOutput
Required.JsonInput.Uint64MapField.ProtobufOutput
Required.JsonInput.ValueAcceptBool.JsonOutput
Required.JsonInput.ValueAcceptBool.ProtobufOutput
Required.JsonInput.ValueAcceptFloat.JsonOutput
Required.JsonInput.ValueAcceptFloat.ProtobufOutput
Required.JsonInput.ValueAcceptInteger.JsonOutput
Required.JsonInput.ValueAcceptInteger.ProtobufOutput
Required.JsonInput.ValueAcceptList.JsonOutput
Required.JsonInput.ValueAcceptList.ProtobufOutput
Required.JsonInput.ValueAcceptNull.JsonOutput
Required.JsonInput.ValueAcceptNull.ProtobufOutput
Required.JsonInput.ValueAcceptObject.JsonOutput
Required.JsonInput.ValueAcceptObject.ProtobufOutput
Required.JsonInput.ValueAcceptString.JsonOutput
Required.JsonInput.ValueAcceptString.ProtobufOutput
Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
Required.TimestampProtoInputTooLarge.JsonOutput
Required.TimestampProtoInputTooSmall.JsonOutput

@ -5,7 +5,7 @@
<title>Google Protocol Buffers tools</title>
<summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
<description>See project site for more info.</description>
<version>3.0.2</version>
<version>3.1.0</version>
<authors>Google Inc.</authors>
<owners>protobuf-packages</owners>
<licenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</licenseUrl>

@ -0,0 +1,52 @@
#!/bin/bash
if [ $# -ne 1 ]; then
cat <<EOF
Usage: $0 <VERSION_NUMBER>
Example:
$ $0 3.0.0
This script will download pre-built protoc binaries from maven repository and
create the Google.Protobuf.Tools package. Well-known type .proto files will also
be included.
EOF
exit 1
fi
VERSION_NUMBER=$1
# <directory name> <binary file name> pairs.
declare -a FILE_NAMES=( \
windows_x86 windows-x86_32.exe \
windows_x64 windows-x86_64.exe \
macosx_x86 osx-x86_32.exe \
macosx_x64 osx-x86_64.exe \
linux_x86 linux-x86_32.exe \
linux_x64 linux-x86_64.exe \
)
set -e
mkdir -p protoc
# Create a zip file for each binary.
for((i=0;i<${#FILE_NAMES[@]};i+=2));do
DIR_NAME=${FILE_NAMES[$i]}
mkdir -p protoc/$DIR_NAME
if [ ${DIR_NAME:0:3} = "win" ]; then
TARGET_BINARY="protoc.exe"
else
TARGET_BINARY="protoc"
fi
BINARY_NAME=${FILE_NAMES[$(($i+1))]}
BINARY_URL=http://repo1.maven.org/maven2/com/google/protobuf/protoc/${VERSION_NUMBER}/protoc-${VERSION_NUMBER}-${BINARY_NAME}
if ! wget ${BINARY_URL} -O protoc/$DIR_NAME/$TARGET_BINARY &> /dev/null; then
echo "[ERROR] Failed to download ${BINARY_URL}" >&2
echo "[ERROR] Skipped $protoc-${VERSION_NAME}-${DIR_NAME}" >&2
continue
fi
done
nuget pack Google.Protobuf.Tools.nuspec

@ -80,66 +80,66 @@ namespace Google.Protobuf.Reflection {
"ASgJEhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5n",
"b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFt",
"aW5nGAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVm",
"YWxzZSKHBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK",
"YWxzZSKEBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK",
"FGphdmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVf",
"ZmlsZXMYCiABKAg6BWZhbHNlEiwKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2Fu",
"ZF9oYXNoGBQgASgIOgVmYWxzZRIlChZqYXZhX3N0cmluZ19jaGVja191dGY4",
"GBsgASgIOgVmYWxzZRJGCgxvcHRpbWl6ZV9mb3IYCSABKA4yKS5nb29nbGUu",
"cHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlOgVTUEVFRBISCgpn",
"b19wYWNrYWdlGAsgASgJEiIKE2NjX2dlbmVyaWNfc2VydmljZXMYECABKAg6",
"BWZhbHNlEiQKFWphdmFfZ2VuZXJpY19zZXJ2aWNlcxgRIAEoCDoFZmFsc2US",
"IgoTcHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVj",
"YXRlZBgXIAEoCDoFZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoF",
"ZmFsc2USGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25h",
"bWVzcGFjZRglIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsy",
"JC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRp",
"bWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JV",
"TlRJTUUQAyoJCOgHEICAgIACSgQIJhAnIuYBCg5NZXNzYWdlT3B0aW9ucxIm",
"ChdtZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9f",
"c3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoK",
"ZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMK",
"FHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1",
"Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAMKDEZpZWxkT3B0",
"aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9w",
"dGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoGanN0eXBl",
"GAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGU6",
"CUpTX05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVk",
"GAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1bmludGVy",
"cHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRl",
"cnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAES",
"EAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0K",
"CUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAIiXgoMT25l",
"b2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv",
"b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi",
"jQEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFzGAIgASgIEhkKCmRlcHJl",
"Y2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcH",
"ZmlsZXMYCiABKAg6BWZhbHNlEikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2Fu",
"ZF9oYXNoGBQgASgIQgIYARIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg",
"ASgIOgVmYWxzZRJGCgxvcHRpbWl6ZV9mb3IYCSABKA4yKS5nb29nbGUucHJv",
"dG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlOgVTUEVFRBISCgpnb19w",
"YWNrYWdlGAsgASgJEiIKE2NjX2dlbmVyaWNfc2VydmljZXMYECABKAg6BWZh",
"bHNlEiQKFWphdmFfZ2VuZXJpY19zZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoT",
"cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl",
"ZBgXIAEoCDoFZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFs",
"c2USGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVz",
"cGFjZRglIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
"b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6",
"ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJ",
"TUUQAyoJCOgHEICAgIACSgQIJhAnIuwBCg5NZXNzYWdlT3B0aW9ucxImChdt",
"ZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9fc3Rh",
"bmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoKZGVw",
"cmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMKFHVu",
"aW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5V",
"bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgIEAkingMKDEZpZWxk",
"T3B0aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVs",
"ZE9wdGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoGanN0",
"eXBlGAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5",
"cGU6CUpTX05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpkZXByZWNh",
"dGVkGAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1bmlu",
"dGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5p",
"bnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JE",
"EAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAA",
"Eg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAJKBAgE",
"EAUiXgoMT25lb2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcH",
"IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI",
"6AcQgICAgAIifQoQRW51bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNhdGVkGAEg",
"ASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
"b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIAC",
"InsKDlNlcnZpY2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNl",
"EkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90",
"b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiegoNTWV0aG9k",
"T3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVy",
"cHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRl",
"cnByZXRlZE9wdGlvbioJCOgHEICAgIACIp4CChNVbmludGVycHJldGVkT3B0",
"aW9uEjsKBG5hbWUYAiADKAsyLS5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy",
"ZXRlZE9wdGlvbi5OYW1lUGFydBIYChBpZGVudGlmaWVyX3ZhbHVlGAMgASgJ",
"EhoKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBBIaChJuZWdhdGl2ZV9pbnRf",
"dmFsdWUYBSABKAMSFAoMZG91YmxlX3ZhbHVlGAYgASgBEhQKDHN0cmluZ192",
"YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAkaMwoITmFtZVBh",
"cnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVuc2lvbhgCIAIoCCLV",
"AQoOU291cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASADKAsyKC5nb29nbGUu",
"cHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEKCExvY2F0aW9u",
"EhAKBHBhdGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhABEhgKEGxlYWRp",
"bmdfY29tbWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVudHMYBCABKAkS",
"IQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKnAQoRR2VuZXJh",
"dGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdvb2dsZS5wcm90",
"b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFubm90YXRp",
"b24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkSDQoF",
"YmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQlsKE2NvbS5nb29nbGUucHJvdG9i",
"dWZCEERlc2NyaXB0b3JQcm90b3NIAVoKZGVzY3JpcHRvcqABAaICA0dQQqoC",
"Gkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9u"));
"6AcQgICAgAIijQEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFzGAIgASgI",
"EhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRf",
"b3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVk",
"T3B0aW9uKgkI6AcQgICAgAIifQoQRW51bVZhbHVlT3B0aW9ucxIZCgpkZXBy",
"ZWNhdGVkGAEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjn",
"ByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJ",
"COgHEICAgIACInsKDlNlcnZpY2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISAB",
"KAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv",
"b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi",
"egoNTWV0aG9kT3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJD",
"ChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9i",
"dWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIp4CChNVbmludGVy",
"cHJldGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5nb29nbGUucHJvdG9idWYu",
"VW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIYChBpZGVudGlmaWVyX3Zh",
"bHVlGAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBBIaChJuZWdh",
"dGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91YmxlX3ZhbHVlGAYgASgBEhQK",
"DHN0cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAka",
"MwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVuc2lv",
"bhgCIAIoCCLVAQoOU291cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASADKAsy",
"KC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEK",
"CExvY2F0aW9uEhAKBHBhdGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhAB",
"EhgKEGxlYWRpbmdfY29tbWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVu",
"dHMYBCABKAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKn",
"AQoRR2VuZXJhdGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdv",
"b2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8K",
"CkFubm90YXRpb24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUY",
"AiABKAkSDQoFYmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQlgKE2NvbS5nb29n",
"bGUucHJvdG9idWZCEERlc2NyaXB0b3JQcm90b3NIAVoKZGVzY3JpcHRvcqIC",
"A0dQQqoCGkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9u"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@ -2865,19 +2865,9 @@ namespace Google.Protobuf.Reflection {
public const int JavaGenerateEqualsAndHashFieldNumber = 20;
private bool javaGenerateEqualsAndHash_;
/// <summary>
/// If set true, then the Java code generator will generate equals() and
/// hashCode() methods for all messages defined in the .proto file.
/// This increases generated code size, potentially substantially for large
/// protos, which may harm a memory-constrained application.
/// - In the full runtime this is a speed optimization, as the
/// AbstractMessage base class includes reflection-based implementations of
/// these methods.
/// - In the lite runtime, setting this option changes the semantics of
/// equals() and hashCode() to more closely match those of the full runtime;
/// the generated methods compute their results based on field values rather
/// than object identity. (Implementations should not assume that hashcodes
/// will be consistent across runtimes or versions of the protocol compiler.)
/// This option does nothing.
/// </summary>
[global::System.ObsoleteAttribute]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool JavaGenerateEqualsAndHash {
get { return javaGenerateEqualsAndHash_; }
@ -3764,7 +3754,7 @@ namespace Google.Protobuf.Reflection {
/// to require exclusive access.
///
/// Note that implementations may choose not to check required fields within
/// a lazy sub-message. That is, calling IsInitialized() on the outher message
/// a lazy sub-message. That is, calling IsInitialized() on the outer message
/// may return true even if the inner message has missing required fields.
/// This is necessary because otherwise the inner message would have to be
/// parsed in order to perform the check, defeating the purpose of lazy

@ -23,10 +23,10 @@ namespace Google.Protobuf.WellKnownTypes {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYi",
"JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQnIKE2Nv",
"JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQm8KE2Nv",
"bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaJWdpdGh1Yi5jb20vZ29s",
"YW5nL3Byb3RvYnVmL3B0eXBlcy9hbnmgAQGiAgNHUEKqAh5Hb29nbGUuUHJv",
"dG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
"YW5nL3Byb3RvYnVmL3B0eXBlcy9hbnmiAgNHUEKqAh5Hb29nbGUuUHJvdG9i",
"dWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {

@ -35,9 +35,9 @@ namespace Google.Protobuf.WellKnownTypes {
"ChFyZXNwb25zZV90eXBlX3VybBgEIAEoCRIaChJyZXNwb25zZV9zdHJlYW1p",
"bmcYBSABKAgSKAoHb3B0aW9ucxgGIAMoCzIXLmdvb2dsZS5wcm90b2J1Zi5P",
"cHRpb24SJwoGc3ludGF4GAcgASgOMhcuZ29vZ2xlLnByb3RvYnVmLlN5bnRh",
"eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCSwoTY29t",
"Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAaABAaICA0dQQqoCHkdvb2ds",
"ZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
"eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCSAoTY29t",
"Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAaICA0dQQqoCHkdvb2dsZS5Q",
"cm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {

@ -25,7 +25,7 @@ namespace Google.Protobuf.WellKnownTypes {
"Ch5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8SD2dvb2dsZS5wcm90",
"b2J1ZiIqCghEdXJhdGlvbhIPCgdzZWNvbmRzGAEgASgDEg0KBW5hbm9zGAIg",
"ASgFQnwKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoq",
"Z2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL2R1cmF0aW9uoAEB",
"Z2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL2R1cmF0aW9u+AEB",
"ogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90",
"bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
@ -79,6 +79,12 @@ namespace Google.Protobuf.WellKnownTypes {
/// end.seconds += 1;
/// end.nanos -= 1000000000;
/// }
///
/// Example 3: Compute Duration from datetime.timedelta in Python.
///
/// td = datetime.timedelta(days=3, minutes=10)
/// duration = Duration()
/// duration.FromTimedelta(td)
/// </summary>
public sealed partial class Duration : pb::IMessage<Duration> {
private static readonly pb::MessageParser<Duration> _parser = new pb::MessageParser<Duration>(() => new Duration());

@ -23,10 +23,10 @@ namespace Google.Protobuf.WellKnownTypes {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Chtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1",
"ZiIHCgVFbXB0eUJ5ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
"UAFaJ2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy9lbXB0eaAB",
"AfgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
"cHJvdG8z"));
"ZiIHCgVFbXB0eUJ2ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
"UAFaJ2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy9lbXB0efgB",
"AaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJv",
"dG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {

@ -23,9 +23,9 @@ namespace Google.Protobuf.WellKnownTypes {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CiBnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90bxIPZ29vZ2xlLnBy",
"b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUJRChNjb20uZ29v",
"Z2xlLnByb3RvYnVmQg5GaWVsZE1hc2tQcm90b1ABoAEBogIDR1BCqgIeR29v",
"Z2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM="));
"b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUJOChNjb20uZ29v",
"Z2xlLnByb3RvYnVmQg5GaWVsZE1hc2tQcm90b1ABogIDR1BCqgIeR29vZ2xl",
"LlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@ -79,7 +79,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// }
///
/// A repeated field is not allowed except at the last position of a
/// field mask.
/// paths string.
///
/// If a FieldMask object is not present in a get operation, the
/// operation applies to all fields (as if a FieldMask of all fields
@ -106,8 +106,8 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// If a repeated field is specified for an update operation, the existing
/// repeated values in the target resource will be overwritten by the new values.
/// Note that a repeated field is only allowed in the last position of a field
/// mask.
/// Note that a repeated field is only allowed in the last position of a `paths`
/// string.
///
/// If a sub-message is specified in the last position of the field mask for an
/// update operation, then the existing sub-message in the target resource is

@ -24,9 +24,9 @@ namespace Google.Protobuf.WellKnownTypes {
string.Concat(
"CiRnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucHJvdG8SD2dvb2ds",
"ZS5wcm90b2J1ZiIiCg1Tb3VyY2VDb250ZXh0EhEKCWZpbGVfbmFtZRgBIAEo",
"CUJVChNjb20uZ29vZ2xlLnByb3RvYnVmQhJTb3VyY2VDb250ZXh0UHJvdG9Q",
"AaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
"cHJvdG8z"));
"CUJSChNjb20uZ29vZ2xlLnByb3RvYnVmQhJTb3VyY2VDb250ZXh0UHJvdG9Q",
"AaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJv",
"dG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {

@ -35,7 +35,7 @@ namespace Google.Protobuf.WellKnownTypes {
"Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSobCglOdWxsVmFsdWUSDgoKTlVMTF9W",
"QUxVRRAAQoEBChNjb20uZ29vZ2xlLnByb3RvYnVmQgtTdHJ1Y3RQcm90b1AB",
"WjFnaXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wdHlwZXMvc3RydWN0O3N0",
"cnVjdHBioAEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5",
"cnVjdHBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5",
"cGVzYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },

@ -24,10 +24,10 @@ namespace Google.Protobuf.WellKnownTypes {
string.Concat(
"Ch9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJv",
"dG9idWYiKwoJVGltZXN0YW1wEg8KB3NlY29uZHMYASABKAMSDQoFbmFub3MY",
"AiABKAVCgQEKE2NvbS5nb29nbGUucHJvdG9idWZCDlRpbWVzdGFtcFByb3Rv",
"UAFaK2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy90aW1lc3Rh",
"bXCgAQH4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw",
"ZXNiBnByb3RvMw=="));
"AiABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIOVGltZXN0YW1wUHJvdG9Q",
"AVorZ2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL3RpbWVzdGFt",
"cPgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
"cHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@ -87,10 +87,8 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// Example 5: Compute Timestamp from current time in Python.
///
/// now = time.time()
/// seconds = int(now)
/// nanos = int((now - seconds) * 10**9)
/// timestamp = Timestamp(seconds=seconds, nanos=nanos)
/// timestamp = Timestamp()
/// timestamp.GetCurrentTime()
/// </summary>
public sealed partial class Timestamp : pb::IMessage<Timestamp> {
private static readonly pb::MessageParser<Timestamp> _parser = new pb::MessageParser<Timestamp>(() => new Timestamp());
@ -130,7 +128,7 @@ namespace Google.Protobuf.WellKnownTypes {
private long seconds_;
/// <summary>
/// Represents seconds of UTC time since Unix epoch
/// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
/// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
/// 9999-12-31T23:59:59Z inclusive.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]

@ -55,7 +55,7 @@ namespace Google.Protobuf.WellKnownTypes {
"IjsKBk9wdGlvbhIMCgRuYW1lGAEgASgJEiMKBXZhbHVlGAIgASgLMhQuZ29v",
"Z2xlLnByb3RvYnVmLkFueSouCgZTeW50YXgSEQoNU1lOVEFYX1BST1RPMhAA",
"EhEKDVNZTlRBWF9QUk9UTzMQAUJMChNjb20uZ29vZ2xlLnByb3RvYnVmQglU",
"eXBlUHJvdG9QAaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25v",
"eXBlUHJvdG9QAfgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25v",
"d25UeXBlc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, },

@ -28,10 +28,10 @@ namespace Google.Protobuf.WellKnownTypes {
"KAMiHAoLVUludDY0VmFsdWUSDQoFdmFsdWUYASABKAQiGwoKSW50MzJWYWx1",
"ZRINCgV2YWx1ZRgBIAEoBSIcCgtVSW50MzJWYWx1ZRINCgV2YWx1ZRgBIAEo",
"DSIaCglCb29sVmFsdWUSDQoFdmFsdWUYASABKAgiHAoLU3RyaW5nVmFsdWUS",
"DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJ/",
"DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJ8",
"ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAFaKmdpdGh1",
"Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy93cmFwcGVyc6ABAfgBAaIC",
"A0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
"Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy93cmFwcGVyc/gBAaICA0dQ",
"QqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {

@ -1,5 +1,5 @@
{
"version": "3.0.2",
"version": "3.1.0",
"title": "Google Protocol Buffers",
"description": "See project site for more info.",
"authors": [ "Google Inc." ],

@ -6,7 +6,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.0.2</version>
<version>3.1.0</version>
</parent>
<artifactId>protobuf-java</artifactId>

@ -310,6 +310,18 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
return copyFrom(bytes, 0, bytes.length);
}
/**
* Wraps the given bytes into a {@code ByteString}. Intended for internal only usage.
*/
static ByteString wrap(ByteBuffer buffer) {
if (buffer.hasArray()) {
final int offset = buffer.arrayOffset();
return ByteString.wrap(buffer.array(), offset + buffer.position(), buffer.remaining());
} else {
return new NioByteString(buffer);
}
}
/**
* Wraps the given bytes into a {@code ByteString}. Intended for internal only
* usage to force a classload of ByteString before LiteralByteString.
@ -679,6 +691,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*/
abstract void writeTo(ByteOutput byteOutput) throws IOException;
/**
* Constructs a read-only {@code java.nio.ByteBuffer} whose content
* is equal to the contents of this byte string.
@ -820,6 +833,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
return true;
}
/**
* Check equality of the substring of given length of this object starting at
* zero with another {@code ByteString} substring starting at offset.

@ -30,10 +30,12 @@
package com.google.protobuf;
import static com.google.protobuf.WireFormat.FIXED_32_SIZE;
import static com.google.protobuf.WireFormat.FIXED_64_SIZE;
import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;
import static java.lang.Math.max;
import com.google.protobuf.Utf8.UnpairedSurrogateException;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
@ -59,10 +61,6 @@ public abstract class CodedOutputStream extends ByteOutput {
private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = UnsafeUtil.hasUnsafeArrayOperations();
private static final long ARRAY_BASE_OFFSET = UnsafeUtil.getArrayBaseOffset();
private static final int FIXED_32_SIZE = 4;
private static final int FIXED_64_SIZE = 8;
private static final int MAX_VARINT_SIZE = 10;
/**
* @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead.
*/
@ -134,14 +132,27 @@ public abstract class CodedOutputStream extends ByteOutput {
return new ArrayEncoder(flatArray, offset, length);
}
/**
* Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}.
*/
public static CodedOutputStream newInstance(ByteBuffer byteBuffer) {
if (byteBuffer.hasArray()) {
return new NioHeapEncoder(byteBuffer);
/** Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}. */
public static CodedOutputStream newInstance(ByteBuffer buffer) {
if (buffer.hasArray()) {
return new HeapNioEncoder(buffer);
}
return new NioEncoder(byteBuffer);
if (buffer.isDirect() && !buffer.isReadOnly()) {
return UnsafeDirectNioEncoder.isSupported()
? newUnsafeInstance(buffer)
: newSafeInstance(buffer);
}
throw new IllegalArgumentException("ByteBuffer is read-only");
}
/** For testing purposes only. */
static CodedOutputStream newUnsafeInstance(ByteBuffer buffer) {
return new UnsafeDirectNioEncoder(buffer);
}
/** For testing purposes only. */
static CodedOutputStream newSafeInstance(ByteBuffer buffer) {
return new SafeDirectNioEncoder(buffer);
}
/**
@ -979,6 +990,10 @@ public abstract class CodedOutputStream extends ByteOutput {
super(MESSAGE);
}
OutOfSpaceException(String explanationMessage) {
super(MESSAGE + ": " + explanationMessage);
}
OutOfSpaceException(Throwable cause) {
super(MESSAGE, cause);
}
@ -1486,11 +1501,11 @@ public abstract class CodedOutputStream extends ByteOutput {
* A {@link CodedOutputStream} that writes directly to a heap {@link ByteBuffer}. Writes are
* done directly to the underlying array. The buffer position is only updated after a flush.
*/
private static final class NioHeapEncoder extends ArrayEncoder {
private static final class HeapNioEncoder extends ArrayEncoder {
private final ByteBuffer byteBuffer;
private int initialPosition;
NioHeapEncoder(ByteBuffer byteBuffer) {
HeapNioEncoder(ByteBuffer byteBuffer) {
super(byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position(),
byteBuffer.remaining());
this.byteBuffer = byteBuffer;
@ -1505,14 +1520,15 @@ public abstract class CodedOutputStream extends ByteOutput {
}
/**
* A {@link CodedOutputStream} that writes directly to a {@link ByteBuffer}.
* A {@link CodedOutputStream} that writes directly to a direct {@link ByteBuffer}, using only
* safe operations..
*/
private static final class NioEncoder extends CodedOutputStream {
private static final class SafeDirectNioEncoder extends CodedOutputStream {
private final ByteBuffer originalBuffer;
private final ByteBuffer buffer;
private final int initialPosition;
NioEncoder(ByteBuffer buffer) {
SafeDirectNioEncoder(ByteBuffer buffer) {
this.originalBuffer = buffer;
this.buffer = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN);
initialPosition = buffer.position();
@ -1814,6 +1830,356 @@ public abstract class CodedOutputStream extends ByteOutput {
}
}
/**
* A {@link CodedOutputStream} that writes directly to a direct {@link ByteBuffer} using {@code
* sun.misc.Unsafe}.
*/
private static final class UnsafeDirectNioEncoder extends CodedOutputStream {
private final ByteBuffer originalBuffer;
private final ByteBuffer buffer;
private final long address;
private final long initialPosition;
private final long limit;
private final long oneVarintLimit;
private long position;
UnsafeDirectNioEncoder(ByteBuffer buffer) {
this.originalBuffer = buffer;
this.buffer = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN);
address = UnsafeUtil.addressOffset(buffer);
initialPosition = address + buffer.position();
limit = address + buffer.limit();
oneVarintLimit = limit - MAX_VARINT_SIZE;
position = initialPosition;
}
static boolean isSupported() {
return UnsafeUtil.hasUnsafeByteBufferOperations();
}
@Override
public void writeTag(int fieldNumber, int wireType) throws IOException {
writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
}
@Override
public void writeInt32(int fieldNumber, int value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
writeInt32NoTag(value);
}
@Override
public void writeUInt32(int fieldNumber, int value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
writeUInt32NoTag(value);
}
@Override
public void writeFixed32(int fieldNumber, int value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
writeFixed32NoTag(value);
}
@Override
public void writeUInt64(int fieldNumber, long value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
writeUInt64NoTag(value);
}
@Override
public void writeFixed64(int fieldNumber, long value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
writeFixed64NoTag(value);
}
@Override
public void writeBool(int fieldNumber, boolean value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
write((byte) (value ? 1 : 0));
}
@Override
public void writeString(int fieldNumber, String value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeStringNoTag(value);
}
@Override
public void writeBytes(int fieldNumber, ByteString value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeBytesNoTag(value);
}
@Override
public void writeByteArray(int fieldNumber, byte[] value) throws IOException {
writeByteArray(fieldNumber, value, 0, value.length);
}
@Override
public void writeByteArray(int fieldNumber, byte[] value, int offset, int length)
throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeByteArrayNoTag(value, offset, length);
}
@Override
public void writeByteBuffer(int fieldNumber, ByteBuffer value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeUInt32NoTag(value.capacity());
writeRawBytes(value);
}
@Override
public void writeMessage(int fieldNumber, MessageLite value) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeMessageNoTag(value);
}
@Override
public void writeMessageSetExtension(int fieldNumber, MessageLite value) throws IOException {
writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
}
@Override
public void writeRawMessageSetExtension(int fieldNumber, ByteString value) throws IOException {
writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
}
@Override
public void writeMessageNoTag(MessageLite value) throws IOException {
writeUInt32NoTag(value.getSerializedSize());
value.writeTo(this);
}
@Override
public void write(byte value) throws IOException {
if (position >= limit) {
throw new OutOfSpaceException(
String.format("Pos: %d, limit: %d, len: %d", position, limit, 1));
}
UnsafeUtil.putByte(position++, value);
}
@Override
public void writeBytesNoTag(ByteString value) throws IOException {
writeUInt32NoTag(value.size());
value.writeTo(this);
}
@Override
public void writeByteArrayNoTag(byte[] value, int offset, int length) throws IOException {
writeUInt32NoTag(length);
write(value, offset, length);
}
@Override
public void writeRawBytes(ByteBuffer value) throws IOException {
if (value.hasArray()) {
write(value.array(), value.arrayOffset(), value.capacity());
} else {
ByteBuffer duplicated = value.duplicate();
duplicated.clear();
write(duplicated);
}
}
@Override
public void writeInt32NoTag(int value) throws IOException {
if (value >= 0) {
writeUInt32NoTag(value);
} else {
// Must sign-extend.
writeUInt64NoTag(value);
}
}
@Override
public void writeUInt32NoTag(int value) throws IOException {
if (position <= oneVarintLimit) {
// Optimization to avoid bounds checks on each iteration.
while (true) {
if ((value & ~0x7F) == 0) {
UnsafeUtil.putByte(position++, (byte) value);
return;
} else {
UnsafeUtil.putByte(position++, (byte) ((value & 0x7F) | 0x80));
value >>>= 7;
}
}
} else {
while (position < limit) {
if ((value & ~0x7F) == 0) {
UnsafeUtil.putByte(position++, (byte) value);
return;
} else {
UnsafeUtil.putByte(position++, (byte) ((value & 0x7F) | 0x80));
value >>>= 7;
}
}
throw new OutOfSpaceException(
String.format("Pos: %d, limit: %d, len: %d", position, limit, 1));
}
}
@Override
public void writeFixed32NoTag(int value) throws IOException {
buffer.putInt(bufferPos(position), value);
position += FIXED_32_SIZE;
}
@Override
public void writeUInt64NoTag(long value) throws IOException {
if (position <= oneVarintLimit) {
// Optimization to avoid bounds checks on each iteration.
while (true) {
if ((value & ~0x7FL) == 0) {
UnsafeUtil.putByte(position++, (byte) value);
return;
} else {
UnsafeUtil.putByte(position++, (byte) (((int) value & 0x7F) | 0x80));
value >>>= 7;
}
}
} else {
while (position < limit) {
if ((value & ~0x7FL) == 0) {
UnsafeUtil.putByte(position++, (byte) value);
return;
} else {
UnsafeUtil.putByte(position++, (byte) (((int) value & 0x7F) | 0x80));
value >>>= 7;
}
}
throw new OutOfSpaceException(
String.format("Pos: %d, limit: %d, len: %d", position, limit, 1));
}
}
@Override
public void writeFixed64NoTag(long value) throws IOException {
buffer.putLong(bufferPos(position), value);
position += FIXED_64_SIZE;
}
@Override
public void write(byte[] value, int offset, int length) throws IOException {
if (value == null
|| offset < 0
|| length < 0
|| (value.length - length) < offset
|| (limit - length) < position) {
if (value == null) {
throw new NullPointerException("value");
}
throw new OutOfSpaceException(
String.format("Pos: %d, limit: %d, len: %d", position, limit, length));
}
UnsafeUtil.copyMemory(
value, UnsafeUtil.getArrayBaseOffset() + offset, null, position, length);
position += length;
}
@Override
public void writeLazy(byte[] value, int offset, int length) throws IOException {
write(value, offset, length);
}
@Override
public void write(ByteBuffer value) throws IOException {
try {
int length = value.remaining();
repositionBuffer(position);
buffer.put(value);
position += length;
} catch (BufferOverflowException e) {
throw new OutOfSpaceException(e);
}
}
@Override
public void writeLazy(ByteBuffer value) throws IOException {
write(value);
}
@Override
public void writeStringNoTag(String value) throws IOException {
long prevPos = position;
try {
// UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
// and at most 3 times of it. We take advantage of this in both branches below.
int maxEncodedSize = value.length() * Utf8.MAX_BYTES_PER_CHAR;
int maxLengthVarIntSize = computeUInt32SizeNoTag(maxEncodedSize);
int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
if (minLengthVarIntSize == maxLengthVarIntSize) {
// Save the current position and increment past the length field. We'll come back
// and write the length field after the encoding is complete.
int stringStart = bufferPos(position) + minLengthVarIntSize;
buffer.position(stringStart);
// Encode the string.
Utf8.encodeUtf8(value, buffer);
// Write the length and advance the position.
int length = buffer.position() - stringStart;
writeUInt32NoTag(length);
position += length;
} else {
// Calculate and write the encoded length.
int length = Utf8.encodedLength(value);
writeUInt32NoTag(length);
// Write the string and advance the position.
repositionBuffer(position);
Utf8.encodeUtf8(value, buffer);
position += length;
}
} catch (UnpairedSurrogateException e) {
// Roll back the change and convert to an IOException.
position = prevPos;
repositionBuffer(position);
// TODO(nathanmittler): We should throw an IOException here instead.
inefficientWriteStringNoTag(value, e);
} catch (IllegalArgumentException e) {
// Thrown by buffer.position() if out of range.
throw new OutOfSpaceException(e);
} catch (IndexOutOfBoundsException e) {
throw new OutOfSpaceException(e);
}
}
@Override
public void flush() {
// Update the position of the original buffer.
originalBuffer.position(bufferPos(position));
}
@Override
public int spaceLeft() {
return (int) (limit - position);
}
@Override
public int getTotalBytesWritten() {
return (int) (position - initialPosition);
}
private void repositionBuffer(long pos) {
buffer.position(bufferPos(pos));
}
private int bufferPos(long pos) {
return (int) (pos - address);
}
}
/**
* Abstract base class for buffered encoders.
*/

@ -1212,33 +1212,20 @@ public final class Descriptors {
private final Object defaultDefault;
}
// TODO(xiaofeng): Implement it consistently across different languages. See b/24751348.
private static String fieldNameToLowerCamelCase(String name) {
// This method should match exactly with the ToJsonName() function in C++
// descriptor.cc.
private static String fieldNameToJsonName(String name) {
StringBuilder result = new StringBuilder(name.length());
boolean isNextUpperCase = false;
for (int i = 0; i < name.length(); i++) {
Character ch = name.charAt(i);
if (Character.isLowerCase(ch)) {
if (isNextUpperCase) {
result.append(Character.toUpperCase(ch));
} else {
result.append(ch);
}
isNextUpperCase = false;
} else if (Character.isUpperCase(ch)) {
if (i == 0) {
// Force first letter to lower-case.
result.append(Character.toLowerCase(ch));
} else {
// Capital letters after the first are left as-is.
result.append(ch);
}
isNextUpperCase = false;
} else if (Character.isDigit(ch)) {
result.append(ch);
if (ch == '_') {
isNextUpperCase = true;
} else if (isNextUpperCase) {
result.append(Character.toUpperCase(ch));
isNextUpperCase = false;
} else {
isNextUpperCase = true;
result.append(ch);
}
}
return result.toString();
@ -1257,7 +1244,7 @@ public final class Descriptors {
if (proto.hasJsonName()) {
jsonName = proto.getJsonName();
} else {
jsonName = fieldNameToLowerCamelCase(proto.getName());
jsonName = fieldNameToJsonName(proto.getName());
}
if (proto.hasType()) {

@ -45,6 +45,7 @@ import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@ -1609,24 +1610,6 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
FieldDescriptor getDescriptor();
}
private abstract static class CachedDescriptorRetriever
implements ExtensionDescriptorRetriever {
private volatile FieldDescriptor descriptor;
protected abstract FieldDescriptor loadDescriptor();
@Override
public FieldDescriptor getDescriptor() {
if (descriptor == null) {
synchronized (this) {
if (descriptor == null) {
descriptor = loadDescriptor();
}
}
}
return descriptor;
}
}
// =================================================================
/** Calls Class.getMethod and throws a RuntimeException if it fails. */
@ -2223,6 +2206,20 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
field.getNumber());
}
private Message coerceType(Message value) {
if (value == null) {
return null;
}
if (mapEntryMessageDefaultInstance.getClass().isInstance(value)) {
return value;
}
// The value is not the exact right message type. However, if it
// is an alternative implementation of the same type -- e.g. a
// DynamicMessage -- we should accept it. In this case we can make
// a copy of the message.
return mapEntryMessageDefaultInstance.toBuilder().mergeFrom(value).build();
}
@Override
public Object get(GeneratedMessageV3 message) {
List result = new ArrayList();
@ -2278,15 +2275,15 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
public Object getRepeatedRaw(Builder builder, int index) {
return getRepeated(builder, index);
}
@Override
public void setRepeated(Builder builder, int index, Object value) {
getMutableMapField(builder).getMutableList().set(index, (Message) value);
getMutableMapField(builder).getMutableList().set(index, coerceType((Message) value));
}
@Override
public void addRepeated(Builder builder, Object value) {
getMutableMapField(builder).getMutableList().add((Message) value);
getMutableMapField(builder).getMutableList().add(coerceType((Message) value));
}
@Override
@ -2713,4 +2710,131 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
output.writeBytesNoTag((ByteString) value);
}
}
protected static <V> void serializeIntegerMapTo(
CodedOutputStream out,
MapField<Integer, V> field,
MapEntry<Integer, V> defaultEntry,
int fieldNumber) throws IOException {
Map<Integer, V> m = field.getMap();
if (!out.isSerializationDeterministic()) {
serializeMapTo(out, m, defaultEntry, fieldNumber);
return;
}
// Sorting the unboxed keys and then look up the values during serialziation is 2x faster
// than sorting map entries with a custom comparator directly.
int[] keys = new int[m.size()];
int index = 0;
for (int k : m.keySet()) {
keys[index++] = k;
}
Arrays.sort(keys);
for (int key : keys) {
out.writeMessage(fieldNumber,
defaultEntry.newBuilderForType()
.setKey(key)
.setValue(m.get(key))
.build());
}
}
protected static <V> void serializeLongMapTo(
CodedOutputStream out,
MapField<Long, V> field,
MapEntry<Long, V> defaultEntry,
int fieldNumber)
throws IOException {
Map<Long, V> m = field.getMap();
if (!out.isSerializationDeterministic()) {
serializeMapTo(out, m, defaultEntry, fieldNumber);
return;
}
long[] keys = new long[m.size()];
int index = 0;
for (long k : m.keySet()) {
keys[index++] = k;
}
Arrays.sort(keys);
for (long key : keys) {
out.writeMessage(fieldNumber,
defaultEntry.newBuilderForType()
.setKey(key)
.setValue(m.get(key))
.build());
}
}
protected static <V> void serializeStringMapTo(
CodedOutputStream out,
MapField<String, V> field,
MapEntry<String, V> defaultEntry,
int fieldNumber)
throws IOException {
Map<String, V> m = field.getMap();
if (!out.isSerializationDeterministic()) {
serializeMapTo(out, m, defaultEntry, fieldNumber);
return;
}
// Sorting the String keys and then look up the values during serialziation is 25% faster than
// sorting map entries with a custom comparator directly.
String[] keys = new String[m.size()];
keys = m.keySet().toArray(keys);
Arrays.sort(keys);
for (String key : keys) {
out.writeMessage(fieldNumber,
defaultEntry.newBuilderForType()
.setKey(key)
.setValue(m.get(key))
.build());
}
}
protected static <V> void serializeBooleanMapTo(
CodedOutputStream out,
MapField<Boolean, V> field,
MapEntry<Boolean, V> defaultEntry,
int fieldNumber)
throws IOException {
Map<Boolean, V> m = field.getMap();
if (!out.isSerializationDeterministic()) {
serializeMapTo(out, m, defaultEntry, fieldNumber);
return;
}
maybeSerializeBooleanEntryTo(out, m, defaultEntry, fieldNumber, false);
maybeSerializeBooleanEntryTo(out, m, defaultEntry, fieldNumber, true);
}
private static <V> void maybeSerializeBooleanEntryTo(
CodedOutputStream out,
Map<Boolean, V> m,
MapEntry<Boolean, V> defaultEntry,
int fieldNumber,
boolean key)
throws IOException {
if (m.containsKey(key)) {
out.writeMessage(fieldNumber,
defaultEntry.newBuilderForType()
.setKey(key)
.setValue(m.get(key))
.build());
}
}
/** Serialize the map using the iteration order. */
private static <K, V> void serializeMapTo(
CodedOutputStream out,
Map<K, V> m,
MapEntry<K, V> defaultEntry,
int fieldNumber)
throws IOException {
for (Map.Entry<K, V> entry : m.entrySet()) {
out.writeMessage(fieldNumber,
defaultEntry.newBuilderForType()
.setKey(entry.getKey())
.setValue(entry.getValue())
.build());
}
}
}

@ -59,6 +59,16 @@ public final class Internal {
static final Charset UTF_8 = Charset.forName("UTF-8");
static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
/**
* Throws an appropriate {@link NullPointerException} if the given objects is {@code null}.
*/
static <T> T checkNotNull(T obj, String message) {
if (obj == null) {
throw new NullPointerException(message);
}
return obj;
}
/**
* Helper called by generated code to construct default values for string
* fields.

@ -107,11 +107,23 @@ public class InvalidProtocolBufferException extends IOException {
"Protocol message end-group tag did not match expected tag.");
}
static InvalidProtocolBufferException invalidWireType() {
return new InvalidProtocolBufferException(
static InvalidWireTypeException invalidWireType() {
return new InvalidWireTypeException(
"Protocol message tag had invalid wire type.");
}
/**
* Exception indicating that and unexpected wire type was encountered for a field.
*/
@ExperimentalApi
public static class InvalidWireTypeException extends InvalidProtocolBufferException {
private static final long serialVersionUID = 3283890091615336259L;
public InvalidWireTypeException(String description) {
super(description);
}
}
static InvalidProtocolBufferException recursionLimitExceeded() {
return new InvalidProtocolBufferException(
"Protocol message had too many levels of nesting. May be malicious. " +

@ -334,6 +334,15 @@ public final class MapEntry<K, V> extends AbstractMessage {
} else {
if (field.getType() == FieldDescriptor.Type.ENUM) {
value = ((EnumValueDescriptor) value).getNumber();
} else if (field.getType() == FieldDescriptor.Type.MESSAGE) {
if (value != null && !metadata.defaultValue.getClass().isInstance(value)) {
// The value is not the exact right message type. However, if it
// is an alternative implementation of the same type -- e.g. a
// DynamicMessage -- we should accept it. In this case we can make
// a copy of the message.
value =
((Message) metadata.defaultValue).toBuilder().mergeFrom((Message) value).build();
}
}
setValue((V) value);
}

@ -30,6 +30,8 @@
package com.google.protobuf;
import static com.google.protobuf.Internal.checkNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidObjectException;
@ -49,10 +51,9 @@ final class NioByteString extends ByteString.LeafByteString {
private final ByteBuffer buffer;
NioByteString(ByteBuffer buffer) {
if (buffer == null) {
throw new NullPointerException("buffer");
}
checkNotNull(buffer, "buffer");
// Use native byte order for fast fixed32/64 operations.
this.buffer = buffer.slice().order(ByteOrder.nativeOrder());
}
@ -266,7 +267,7 @@ final class NioByteString extends ByteString.LeafByteString {
@Override
public CodedInputStream newCodedInput() {
return CodedInputStream.newInstance(buffer);
return CodedInputStream.newInstance(buffer, true);
}
/**

@ -406,6 +406,7 @@ final class RopeByteString extends ByteString {
right.writeTo(output);
}
@Override
protected String toStringInternal(Charset charset) {
return new String(toByteArray(), charset);

@ -1576,14 +1576,22 @@ public final class TextFormat {
// Support specifying repeated field values as a comma-separated list.
// Ex."foo: [1, 2, 3]"
if (field.isRepeated() && tokenizer.tryConsume("[")) {
while (true) {
consumeFieldValue(tokenizer, extensionRegistry, target, field, extension,
parseTreeBuilder, unknownFields);
if (tokenizer.tryConsume("]")) {
// End of list.
break;
if (!tokenizer.tryConsume("]")) { // Allow "foo: []" to be treated as empty.
while (true) {
consumeFieldValue(
tokenizer,
extensionRegistry,
target,
field,
extension,
parseTreeBuilder,
unknownFields);
if (tokenizer.tryConsume("]")) {
// End of list.
break;
}
tokenizer.consume(",");
}
tokenizer.consume(",");
}
} else {
consumeFieldValue(tokenizer, extensionRegistry, target, field,

@ -45,7 +45,8 @@ import java.util.Map.Entry;
*
* <p>The locations of primary fields values are retrieved by {@code getLocation} or
* {@code getLocations}. The locations of sub message values are within nested
* {@code TextFormatParseInfoTree}s and are retrieve by {@code getNestedTree} or {@code getNestedTrees}.
* {@code TextFormatParseInfoTree}s and are retrieve by {@code getNestedTree} or
* {@code getNestedTrees}.
*
* <p>The {@code TextFormatParseInfoTree} is created by a Builder.
*/

@ -64,6 +64,29 @@ import java.nio.ByteBuffer;
public final class UnsafeByteOperations {
private UnsafeByteOperations() {}
/**
* An unsafe operation that returns a {@link ByteString} that is backed by the provided buffer.
*
* @param buffer the buffer to be wrapped
* @return a {@link ByteString} backed by the provided buffer
*/
public static ByteString unsafeWrap(byte[] buffer) {
return ByteString.wrap(buffer);
}
/**
* An unsafe operation that returns a {@link ByteString} that is backed by a subregion of the
* provided buffer.
*
* @param buffer the buffer to be wrapped
* @param offset the offset of the wrapped region
* @param length the number of bytes of the wrapped region
* @return a {@link ByteString} backed by the provided buffer
*/
public static ByteString unsafeWrap(byte[] buffer, int offset, int length) {
return ByteString.wrap(buffer, offset, length);
}
/**
* An unsafe operation that returns a {@link ByteString} that is backed by the provided buffer.
*
@ -71,12 +94,7 @@ public final class UnsafeByteOperations {
* @return a {@link ByteString} backed by the provided buffer
*/
public static ByteString unsafeWrap(ByteBuffer buffer) {
if (buffer.hasArray()) {
final int offset = buffer.arrayOffset();
return ByteString.wrap(buffer.array(), offset + buffer.position(), buffer.remaining());
} else {
return new NioByteString(buffer);
}
return ByteString.wrap(buffer);
}
/**
@ -98,4 +116,5 @@ public final class UnsafeByteOperations {
public static void unsafeWriteTo(ByteString bytes, ByteOutput output) throws IOException {
bytes.writeTo(output);
}
}

@ -30,17 +30,14 @@
package com.google.protobuf;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import sun.misc.Unsafe;
/**
* Utility class for working with unsafe operations.
*/
/** Utility class for working with unsafe operations. */
// TODO(nathanmittler): Add support for Android Memory/MemoryBlock
final class UnsafeUtil {
private static final sun.misc.Unsafe UNSAFE = getUnsafe();
@ -50,8 +47,7 @@ final class UnsafeUtil {
private static final long ARRAY_BASE_OFFSET = byteArrayBaseOffset();
private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(field(Buffer.class, "address"));
private UnsafeUtil() {
}
private UnsafeUtil() {}
static boolean hasUnsafeArrayOperations() {
return HAS_UNSAFE_ARRAY_OPERATIONS;
@ -61,27 +57,83 @@ final class UnsafeUtil {
return HAS_UNSAFE_BYTEBUFFER_OPERATIONS;
}
static Object allocateInstance(Class<?> clazz) {
try {
return UNSAFE.allocateInstance(clazz);
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
}
static long objectFieldOffset(Field field) {
return UNSAFE.objectFieldOffset(field);
}
static long getArrayBaseOffset() {
return ARRAY_BASE_OFFSET;
}
static byte getByte(byte[] target, long offset) {
static byte getByte(Object target, long offset) {
return UNSAFE.getByte(target, offset);
}
static void putByte(byte[] target, long offset, byte value) {
static void putByte(Object target, long offset, byte value) {
UNSAFE.putByte(target, offset, value);
}
static void copyMemory(
byte[] src, long srcOffset, byte[] target, long targetOffset, long length) {
UNSAFE.copyMemory(src, srcOffset, target, targetOffset, length);
static int getInt(Object target, long offset) {
return UNSAFE.getInt(target, offset);
}
static long getLong(byte[] target, long offset) {
static void putInt(Object target, long offset, int value) {
UNSAFE.putInt(target, offset, value);
}
static long getLong(Object target, long offset) {
return UNSAFE.getLong(target, offset);
}
static void putLong(Object target, long offset, long value) {
UNSAFE.putLong(target, offset, value);
}
static boolean getBoolean(Object target, long offset) {
return UNSAFE.getBoolean(target, offset);
}
static void putBoolean(Object target, long offset, boolean value) {
UNSAFE.putBoolean(target, offset, value);
}
static float getFloat(Object target, long offset) {
return UNSAFE.getFloat(target, offset);
}
static void putFloat(Object target, long offset, float value) {
UNSAFE.putFloat(target, offset, value);
}
static double getDouble(Object target, long offset) {
return UNSAFE.getDouble(target, offset);
}
static void putDouble(Object target, long offset, double value) {
UNSAFE.putDouble(target, offset, value);
}
static Object getObject(Object target, long offset) {
return UNSAFE.getObject(target, offset);
}
static void putObject(Object target, long offset, Object value) {
UNSAFE.putObject(target, offset, value);
}
static void copyMemory(
Object src, long srcOffset, Object target, long targetOffset, long length) {
UNSAFE.copyMemory(src, srcOffset, target, targetOffset, length);
}
static byte getByte(long address) {
return UNSAFE.getByte(address);
}
@ -90,14 +142,30 @@ final class UnsafeUtil {
UNSAFE.putByte(address, value);
}
static int getInt(long address) {
return UNSAFE.getInt(address);
}
static void putInt(long address, int value) {
UNSAFE.putInt(address, value);
}
static long getLong(long address) {
return UNSAFE.getLong(address);
}
static void putLong(long address, long value) {
UNSAFE.putLong(address, value);
}
static void copyMemory(long srcAddress, long targetAddress, long length) {
UNSAFE.copyMemory(srcAddress, targetAddress, length);
}
static void setMemory(long address, long numBytes, byte value) {
UNSAFE.setMemory(address, numBytes, value);
}
/**
* Gets the offset of the {@code address} field of the given direct {@link ByteBuffer}.
*/
@ -136,18 +204,29 @@ final class UnsafeUtil {
return unsafe;
}
/**
* Indicates whether or not unsafe array operations are supported on this platform.
*/
/** Indicates whether or not unsafe array operations are supported on this platform. */
private static boolean supportsUnsafeArrayOperations() {
boolean supported = false;
if (UNSAFE != null) {
try {
Class<?> clazz = UNSAFE.getClass();
clazz.getMethod("objectFieldOffset", Field.class);
clazz.getMethod("allocateInstance", Class.class);
clazz.getMethod("arrayBaseOffset", Class.class);
clazz.getMethod("getByte", Object.class, long.class);
clazz.getMethod("putByte", Object.class, long.class, byte.class);
clazz.getMethod("getBoolean", Object.class, long.class);
clazz.getMethod("putBoolean", Object.class, long.class, boolean.class);
clazz.getMethod("getInt", Object.class, long.class);
clazz.getMethod("putInt", Object.class, long.class, int.class);
clazz.getMethod("getLong", Object.class, long.class);
clazz.getMethod("putLong", Object.class, long.class, long.class);
clazz.getMethod("getFloat", Object.class, long.class);
clazz.getMethod("putFloat", Object.class, long.class, float.class);
clazz.getMethod("getDouble", Object.class, long.class);
clazz.getMethod("putDouble", Object.class, long.class, double.class);
clazz.getMethod("getObject", Object.class, long.class);
clazz.getMethod("putObject", Object.class, long.class, Object.class);
clazz.getMethod(
"copyMemory", Object.class, long.class, Object.class, long.class, long.class);
supported = true;
@ -163,11 +242,17 @@ final class UnsafeUtil {
if (UNSAFE != null) {
try {
Class<?> clazz = UNSAFE.getClass();
// Methods for getting direct buffer address.
clazz.getMethod("objectFieldOffset", Field.class);
clazz.getMethod("getByte", long.class);
clazz.getMethod("getLong", Object.class, long.class);
clazz.getMethod("getByte", long.class);
clazz.getMethod("putByte", long.class, byte.class);
clazz.getMethod("getInt", long.class);
clazz.getMethod("putInt", long.class, int.class);
clazz.getMethod("getLong", long.class);
clazz.getMethod("putLong", long.class, long.class);
clazz.getMethod("setMemory", long.class, long.class, byte.class);
clazz.getMethod("copyMemory", long.class, long.class, long.class);
supported = true;
} catch (Throwable e) {

@ -47,6 +47,10 @@ public final class WireFormat {
// Do not allow instantiation.
private WireFormat() {}
static final int FIXED_32_SIZE = 4;
static final int FIXED_64_SIZE = 8;
static final int MAX_VARINT_SIZE = 10;
public static final int WIRETYPE_VARINT = 0;
public static final int WIRETYPE_FIXED64 = 1;
public static final int WIRETYPE_LENGTH_DELIMITED = 2;

@ -40,9 +40,8 @@ import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestRequiredForeign;
import protobuf_unittest.UnittestProto.TestUnpackedTypes;
import junit.framework.TestCase;
import java.util.Map;
import junit.framework.TestCase;
/**
* Unit test for {@link AbstractMessage}.
@ -492,7 +491,6 @@ public class AbstractMessageTest extends TestCase {
checkEqualsIsConsistent(eUnknownFields, eUnknownFields2);
}
/**
* Asserts that the given proto has symmetric equals and hashCode methods.
*/

@ -32,11 +32,10 @@ package com.google.protobuf;
import static java.util.Arrays.asList;
import junit.framework.TestCase;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import junit.framework.TestCase;
/**
* Tests for {@link BooleanArrayList}.

@ -30,13 +30,12 @@
package com.google.protobuf;
import junit.framework.TestCase;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Random;
import junit.framework.TestCase;
/**
* Tests for {@link ByteBufferWriter}.

@ -31,9 +31,6 @@
package com.google.protobuf;
import com.google.protobuf.ByteString.Output;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -48,6 +45,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Random;
import junit.framework.TestCase;
/**
* Test methods with implementations in {@link ByteString}, plus do some top-level "integration"

@ -35,15 +35,13 @@ import protobuf_unittest.UnittestProto.SparseEnumMessage;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestSparseEnum;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
/**
* Unit test for {@link CodedOutputStream}.
@ -151,16 +149,21 @@ public class CodedOutputStreamTest extends TestCase {
private final int initialPosition;
private final CodedOutputStream stream;
private final ByteBuffer buffer;
private final boolean unsafe;
NioDirectCoder(int size) {
this(size, 0);
NioDirectCoder(int size, boolean unsafe) {
this(size, 0, unsafe);
}
NioDirectCoder(int size, int initialPosition) {
NioDirectCoder(int size, int initialPosition, boolean unsafe) {
this.unsafe = unsafe;
this.initialPosition = initialPosition;
buffer = ByteBuffer.allocateDirect(size);
buffer.position(initialPosition);
stream = CodedOutputStream.newInstance(buffer);
stream =
unsafe
? CodedOutputStream.newUnsafeInstance(buffer)
: CodedOutputStream.newSafeInstance(buffer);
}
@Override
@ -181,7 +184,7 @@ public class CodedOutputStreamTest extends TestCase {
@Override
public OutputType getOutputType() {
return OutputType.NIO_DIRECT;
return unsafe ? OutputType.NIO_DIRECT_SAFE : OutputType.NIO_DIRECT_UNSAFE;
}
}
@ -198,10 +201,16 @@ public class CodedOutputStreamTest extends TestCase {
return new NioHeapCoder(size);
}
},
NIO_DIRECT() {
NIO_DIRECT_SAFE() {
@Override
Coder newCoder(int size) {
return new NioDirectCoder(size);
return new NioDirectCoder(size, false);
}
},
NIO_DIRECT_UNSAFE() {
@Override
Coder newCoder(int size) {
return new NioDirectCoder(size, true);
}
},
STREAM() {
@ -389,6 +398,7 @@ public class CodedOutputStreamTest extends TestCase {
!= CodedOutputStream.computeUInt32SizeNoTag(string.length() * Utf8.MAX_BYTES_PER_CHAR));
coder.stream().writeStringNoTag(string);
coder.stream().flush();
int stringSize = CodedOutputStream.computeStringSizeNoTag(string);
// Verify that the total bytes written is correct
@ -478,11 +488,12 @@ public class CodedOutputStreamTest extends TestCase {
public void testWriteByteArrayWithOffsets() throws Exception {
byte[] fullArray = bytes(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88);
byte[] destination = new byte[4];
CodedOutputStream codedStream = CodedOutputStream.newInstance(destination);
codedStream.writeByteArrayNoTag(fullArray, 2, 2);
assertEqualBytes(OutputType.ARRAY, bytes(0x02, 0x33, 0x44, 0x00), destination);
assertEquals(3, codedStream.getTotalBytesWritten());
for (OutputType type : new OutputType[] {OutputType.ARRAY}) {
Coder coder = type.newCoder(4);
coder.stream().writeByteArrayNoTag(fullArray, 2, 2);
assertEqualBytes(type, bytes(0x02, 0x33, 0x44), coder.toByteArray());
assertEquals(3, coder.stream().getTotalBytesWritten());
}
}
public void testSerializeUtf8_MultipleSmallWrites() throws Exception {
@ -561,7 +572,12 @@ public class CodedOutputStreamTest extends TestCase {
// Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
// An array of size 1 will cause a failure when trying to write the varint.
for (OutputType outputType :
new OutputType[] {OutputType.ARRAY, OutputType.NIO_HEAP, OutputType.NIO_DIRECT}) {
new OutputType[] {
OutputType.ARRAY,
OutputType.NIO_HEAP,
OutputType.NIO_DIRECT_SAFE,
OutputType.NIO_DIRECT_UNSAFE
}) {
for (int i = 0; i < 11; i++) {
Coder coder = outputType.newCoder(i);
try {
@ -599,10 +615,13 @@ public class CodedOutputStreamTest extends TestCase {
public void testNioEncodersWithInitialOffsets() throws Exception {
String value = "abc";
for (Coder coder : new Coder[] {new NioHeapCoder(10, 2), new NioDirectCoder(10, 2)}) {
for (Coder coder :
new Coder[] {
new NioHeapCoder(10, 2), new NioDirectCoder(10, 2, false), new NioDirectCoder(10, 2, true)
}) {
coder.stream().writeStringNoTag(value);
coder.stream().flush();
assertEqualBytes(coder.getOutputType(), new byte[]{3, 'a', 'b', 'c'}, coder.toByteArray());
assertEqualBytes(coder.getOutputType(), new byte[] {3, 'a', 'b', 'c'}, coder.toByteArray());
}
}

@ -31,11 +31,9 @@
package com.google.protobuf;
import protobuf_unittest.UnittestProto.TestDeprecatedFields;
import junit.framework.TestCase;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import junit.framework.TestCase;
/**
* Test field deprecation

@ -55,15 +55,15 @@ import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
import protobuf_unittest.UnittestProto.TestJsonName;
import protobuf_unittest.UnittestProto.TestMultipleExtensionRanges;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestReservedFields;
import protobuf_unittest.UnittestProto.TestService;
import junit.framework.TestCase;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import junit.framework.TestCase;
/**
* Unit test for {@link Descriptors}.
@ -805,4 +805,15 @@ public class DescriptorsTest extends TestCase {
Descriptors.FileDescriptor.buildFrom(
fileDescriptorProto, new FileDescriptor[0]);
}
public void testFieldJsonName() throws Exception {
Descriptor d = TestJsonName.getDescriptor();
assertEquals(6, d.getFields().size());
assertEquals("fieldName1", d.getFields().get(0).getJsonName());
assertEquals("fieldName2", d.getFields().get(1).getJsonName());
assertEquals("FieldName3", d.getFields().get(2).getJsonName());
assertEquals("FieldName4", d.getFields().get(3).getJsonName());
assertEquals("FIELDNAME5", d.getFields().get(4).getJsonName());
assertEquals("@type", d.getFields().get(5).getJsonName());
}
}

@ -32,11 +32,10 @@ package com.google.protobuf;
import static java.util.Arrays.asList;
import junit.framework.TestCase;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import junit.framework.TestCase;
/**
* Tests for {@link DoubleArrayList}.

@ -37,10 +37,8 @@ import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestEmptyMessage;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import junit.framework.TestCase;
import java.util.Arrays;
import junit.framework.TestCase;
/**
* Unit test for {@link DynamicMessage}. See also {@link MessageTest}, which

@ -32,26 +32,24 @@ package com.google.protobuf;
import protobuf_unittest.NonNestedExtension;
import protobuf_unittest.NonNestedExtensionLite;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Tests for {@link ExtensionRegistryFactory} and the {@link ExtensionRegistry} instances it
* creates.
*
*
* <p>This test simulates the runtime behaviour of the ExtensionRegistryFactory by delegating test
* definitions to two inner classes {@link InnerTest} and {@link InnerLiteTest}, the latter of
* which is executed using a custom ClassLoader, simulating the ProtoLite environment.
*
*
* <p>The test mechanism employed here is based on the pattern in
* {@code com.google.common.util.concurrent.AbstractFutureFallbackAtomicHelperTest}
*/
@ -68,6 +66,7 @@ public class ExtensionRegistryFactoryTest extends TestCase {
void testEmpty();
void testIsFullRegistry();
void testAdd();
void testAdd_immutable();
}
/**
@ -125,6 +124,29 @@ public class ExtensionRegistryFactoryTest extends TestCase {
assertNotNull("Extension is registered in masqueraded full registry",
fullRegistry2.findImmutableExtensionByName("protobuf_unittest.nonNestedExtension"));
}
@Override
public void testAdd_immutable() {
ExtensionRegistryLite registry1 = ExtensionRegistryLite.newInstance().getUnmodifiable();
try {
NonNestedExtensionLite.registerAllExtensions(registry1);
fail();
} catch (UnsupportedOperationException expected) {}
try {
registry1.add(NonNestedExtensionLite.nonNestedExtensionLite);
fail();
} catch (UnsupportedOperationException expected) {}
ExtensionRegistryLite registry2 = ExtensionRegistryLite.newInstance().getUnmodifiable();
try {
NonNestedExtension.registerAllExtensions((ExtensionRegistry) registry2);
fail();
} catch (IllegalArgumentException expected) {}
try {
registry2.add(NonNestedExtension.nonNestedExtension);
fail();
} catch (IllegalArgumentException expected) {}
}
}
/**
@ -162,12 +184,21 @@ public class ExtensionRegistryFactoryTest extends TestCase {
NonNestedExtensionLite.MessageLiteToBeExtended.getDefaultInstance(), 1);
assertNotNull("Extension is registered in Lite registry", extension);
}
@Override
public void testAdd_immutable() {
ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance().getUnmodifiable();
try {
NonNestedExtensionLite.registerAllExtensions(registry);
fail();
} catch (UnsupportedOperationException expected) {}
}
}
/**
* Defines a suite of tests which the JUnit3 runner retrieves by reflection.
*/
public static Test suite() {
public static Test suite() {
TestSuite suite = new TestSuite();
for (Method method : RegistryTests.class.getMethods()) {
suite.addTest(TestSuite.createTest(ExtensionRegistryFactoryTest.class, method.getName()));

@ -32,11 +32,10 @@ package com.google.protobuf;
import static java.util.Arrays.asList;
import junit.framework.TestCase;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import junit.framework.TestCase;
/**
* Tests for {@link FloatArrayList}.

@ -65,9 +65,6 @@ import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
import protobuf_unittest.UnittestProto.TestOneof2;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestUnpackedTypes;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
@ -76,6 +73,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
/**
* Unit test for generated messages and generated code. See also

@ -32,11 +32,10 @@ package com.google.protobuf;
import static java.util.Arrays.asList;
import junit.framework.TestCase;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import junit.framework.TestCase;
/**
* Tests for {@link IntArrayList}.

@ -35,10 +35,8 @@ import static protobuf_unittest.UnittestProto.optionalInt64Extension;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import junit.framework.TestCase;
import java.io.IOException;
import junit.framework.TestCase;
/**
* Unit test for {@link LazyFieldLite}.

@ -32,10 +32,8 @@ package com.google.protobuf;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import junit.framework.TestCase;
import java.io.IOException;
import junit.framework.TestCase;
/**
* Unit test for {@link LazyField}.

@ -34,10 +34,8 @@ import protobuf_unittest.LazyFieldsLite.LazyExtension;
import protobuf_unittest.LazyFieldsLite.LazyInnerMessageLite;
import protobuf_unittest.LazyFieldsLite.LazyMessageLite;
import protobuf_unittest.LazyFieldsLite.LazyNestedInnerMessageLite;
import junit.framework.TestCase;
import java.util.ArrayList;
import junit.framework.TestCase;
/**
* Unit test for messages with lazy fields.

@ -32,13 +32,12 @@ package com.google.protobuf;
import static java.util.Arrays.asList;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
/**
* Tests for {@link LazyStringArrayList}.

@ -32,10 +32,8 @@ package com.google.protobuf;
import protobuf_unittest.UnittestProto;
import junit.framework.TestCase;
import java.io.IOException;
import junit.framework.TestCase;
/**
* Tests to make sure the lazy conversion of UTF8-encoded byte arrays to

@ -35,7 +35,6 @@ import static java.util.Collections.singletonList;
import com.google.protobuf.UnittestImportLite.ImportEnumLite;
import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
import com.google.protobuf.UnittestLite;
import com.google.protobuf.UnittestLite.ForeignEnumLite;
import com.google.protobuf.UnittestLite.ForeignMessageLite;
import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
@ -52,15 +51,8 @@ import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* Test lite runtime.
*
@ -139,7 +131,6 @@ public class LiteTest extends TestCase {
UnittestLite.optionalNestedMessageExtensionLite).getBb());
}
public void testClone() {
TestAllTypesLite.Builder expected = TestAllTypesLite.newBuilder()
.setOptionalInt32(123);

@ -30,8 +30,6 @@
package com.google.protobuf;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
@ -45,6 +43,7 @@ import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import junit.framework.TestCase;
/**
* Test {@code LiteralByteString} by setting up a reference string in {@link #setUp()}.

@ -32,11 +32,10 @@ package com.google.protobuf;
import static java.util.Arrays.asList;
import junit.framework.TestCase;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import junit.framework.TestCase;
/**
* Tests for {@link LongArrayList}.

@ -35,15 +35,13 @@ import map_lite_test.MapForProto2TestProto.TestMap;
import map_lite_test.MapForProto2TestProto.TestMap.MessageValue;
import map_lite_test.MapForProto2TestProto.TestMapOrBuilder;
import map_lite_test.MapForProto2TestProto.TestUnknownEnumValue;
import junit.framework.TestCase;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
/**
* Unit tests for map fields.

@ -32,14 +32,14 @@ package com.google.protobuf;
import com.google.protobuf.Descriptors.FieldDescriptor;
import map_test.MapForProto2TestProto.BizarroTestMap;
import map_test.MapForProto2TestProto.ReservedAsMapField;
import map_test.MapForProto2TestProto.ReservedAsMapFieldWithEnumValue;
import map_test.MapForProto2TestProto.TestMap;
import map_test.MapForProto2TestProto.TestMap.MessageValue;
import map_test.MapForProto2TestProto.TestMap.MessageWithRequiredFields;
import map_test.MapForProto2TestProto.TestMapOrBuilder;
import map_test.MapForProto2TestProto.TestRecursiveMap;
import map_test.MapForProto2TestProto.TestUnknownEnumValue;
import junit.framework.TestCase;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@ -47,6 +47,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
/**
* Unit tests for map fields in proto2 protos.
@ -1143,6 +1144,11 @@ public class MapForProto2Test extends TestCase {
assertEquals(2, mapEntry.getAllFields().size());
}
public void testReservedWordsFieldNames() {
ReservedAsMapField.newBuilder().build();
ReservedAsMapFieldWithEnumValue.newBuilder().build();
}
private static <K, V> Map<K, V> newMap(K key1, V value1) {
Map<K, V> map = new HashMap<K, V>();
map.put(key1, value1);

@ -36,12 +36,12 @@ import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import map_test.MapTestProto.BizarroTestMap;
import map_test.MapTestProto.ReservedAsMapField;
import map_test.MapTestProto.ReservedAsMapFieldWithEnumValue;
import map_test.MapTestProto.TestMap;
import map_test.MapTestProto.TestMap.MessageValue;
import map_test.MapTestProto.TestMapOrBuilder;
import map_test.MapTestProto.TestOnChangeEventPropagation;
import junit.framework.TestCase;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@ -49,6 +49,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
/**
* Unit tests for map fields.
@ -1307,6 +1308,171 @@ public class MapTest extends TestCase {
}
}
public void testReservedWordsFieldNames() {
ReservedAsMapField.newBuilder().build();
ReservedAsMapFieldWithEnumValue.newBuilder().build();
}
public void testDeterministicSerialziation() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
// int32->int32
builder.putInt32ToInt32Field(5, 1);
builder.putInt32ToInt32Field(1, 1);
builder.putInt32ToInt32Field(4, 1);
builder.putInt32ToInt32Field(-2, 1);
builder.putInt32ToInt32Field(0, 1);
// uint32->int32
builder.putUint32ToInt32Field(5, 1);
builder.putUint32ToInt32Field(1, 1);
builder.putUint32ToInt32Field(4, 1);
builder.putUint32ToInt32Field(-2, 1);
builder.putUint32ToInt32Field(0, 1);
// int64->int32
builder.putInt64ToInt32Field(5L, 1);
builder.putInt64ToInt32Field(1L, 1);
builder.putInt64ToInt32Field(4L, 1);
builder.putInt64ToInt32Field(-2L, 1);
builder.putInt64ToInt32Field(0L, 1);
// string->int32
builder.putStringToInt32Field("baz", 1);
builder.putStringToInt32Field("foo", 1);
builder.putStringToInt32Field("bar", 1);
builder.putStringToInt32Field("", 1);
builder.putStringToInt32Field("hello", 1);
builder.putStringToInt32Field("world", 1);
TestMap message = builder.build();
byte[] serialized = new byte[message.getSerializedSize()];
CodedOutputStream output = CodedOutputStream.newInstance(serialized);
output.useDeterministicSerialization();
message.writeTo(output);
output.flush();
CodedInputStream input = CodedInputStream.newInstance(serialized);
List<Integer> int32Keys = new ArrayList<Integer>();
List<Integer> uint32Keys = new ArrayList<Integer>();
List<Long> int64Keys = new ArrayList<Long>();
List<String> stringKeys = new ArrayList<String>();
int tag;
while (true) {
tag = input.readTag();
if (tag == 0) {
break;
}
int length = input.readRawVarint32();
int oldLimit = input.pushLimit(length);
switch (WireFormat.getTagFieldNumber(tag)) {
case TestMap.STRING_TO_INT32_FIELD_FIELD_NUMBER:
stringKeys.add(readMapStringKey(input));
break;
case TestMap.INT32_TO_INT32_FIELD_FIELD_NUMBER:
int32Keys.add(readMapIntegerKey(input));
break;
case TestMap.UINT32_TO_INT32_FIELD_FIELD_NUMBER:
uint32Keys.add(readMapIntegerKey(input));
break;
case TestMap.INT64_TO_INT32_FIELD_FIELD_NUMBER:
int64Keys.add(readMapLongKey(input));
break;
default:
fail("Unexpected fields.");
}
input.popLimit(oldLimit);
}
assertEquals(
Arrays.asList(-2, 0, 1, 4, 5),
int32Keys);
assertEquals(
Arrays.asList(-2, 0, 1, 4, 5),
uint32Keys);
assertEquals(
Arrays.asList(-2L, 0L, 1L, 4L, 5L),
int64Keys);
assertEquals(
Arrays.asList("", "bar", "baz", "foo", "hello", "world"),
stringKeys);
}
public void testInitFromPartialDynamicMessage() {
FieldDescriptor fieldDescriptor =
TestMap.getDescriptor().findFieldByNumber(TestMap.INT32_TO_MESSAGE_FIELD_FIELD_NUMBER);
Descriptor mapEntryType = fieldDescriptor.getMessageType();
FieldDescriptor keyField = mapEntryType.findFieldByNumber(1);
FieldDescriptor valueField = mapEntryType.findFieldByNumber(2);
DynamicMessage dynamicMessage =
DynamicMessage.newBuilder(TestMap.getDescriptor())
.addRepeatedField(
fieldDescriptor,
DynamicMessage.newBuilder(mapEntryType)
.setField(keyField, 10)
.setField(valueField, TestMap.MessageValue.newBuilder().setValue(10).build())
.build())
.build();
TestMap message = TestMap.newBuilder().mergeFrom(dynamicMessage).build();
assertEquals(
TestMap.MessageValue.newBuilder().setValue(10).build(),
message.getInt32ToMessageFieldMap().get(10));
}
public void testInitFromFullyDynamicMessage() {
FieldDescriptor fieldDescriptor =
TestMap.getDescriptor().findFieldByNumber(TestMap.INT32_TO_MESSAGE_FIELD_FIELD_NUMBER);
Descriptor mapEntryType = fieldDescriptor.getMessageType();
FieldDescriptor keyField = mapEntryType.findFieldByNumber(1);
FieldDescriptor valueField = mapEntryType.findFieldByNumber(2);
DynamicMessage dynamicMessage =
DynamicMessage.newBuilder(TestMap.getDescriptor())
.addRepeatedField(
fieldDescriptor,
DynamicMessage.newBuilder(mapEntryType)
.setField(keyField, 10)
.setField(
valueField,
DynamicMessage.newBuilder(TestMap.MessageValue.getDescriptor())
.setField(
TestMap.MessageValue.getDescriptor().findFieldByName("value"), 10)
.build())
.build())
.build();
TestMap message = TestMap.newBuilder().mergeFrom(dynamicMessage).build();
assertEquals(
TestMap.MessageValue.newBuilder().setValue(10).build(),
message.getInt32ToMessageFieldMap().get(10));
}
private int readMapIntegerKey(CodedInputStream input) throws IOException {
int tag = input.readTag();
assertEquals(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT), tag);
int ret = input.readInt32();
// skip the value field.
input.skipField(input.readTag());
assertTrue(input.isAtEnd());
return ret;
}
private long readMapLongKey(CodedInputStream input) throws IOException {
int tag = input.readTag();
assertEquals(WireFormat.makeTag(1, WireFormat.WIRETYPE_VARINT), tag);
long ret = input.readInt64();
// skip the value field.
input.skipField(input.readTag());
assertTrue(input.isAtEnd());
return ret;
}
private String readMapStringKey(CodedInputStream input) throws IOException {
int tag = input.readTag();
assertEquals(WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED), tag);
String ret = input.readString();
// skip the value field.
input.skipField(input.readTag());
assertTrue(input.isAtEnd());
return ret;
}
private static <K, V> Map<K, V> newMap(K key1, V value1) {
Map<K, V> map = new HashMap<K, V>();
map.put(key1, value1);

@ -35,10 +35,8 @@ import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestRequiredForeign;
import junit.framework.TestCase;
import java.util.List;
import junit.framework.TestCase;
/**
* Misc. unit tests for message operations that apply to both generated

@ -32,11 +32,9 @@ package com.google.protobuf;
import protobuf_unittest.Vehicle;
import protobuf_unittest.Wheel;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
/**
* Test cases that exercise end-to-end use cases involving

@ -32,8 +32,6 @@ package com.google.protobuf;
import static com.google.protobuf.Internal.UTF_8;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
@ -48,6 +46,7 @@ import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import junit.framework.TestCase;
/**
* Tests for {@link NioByteString}.

@ -36,16 +36,14 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.google.protobuf.DescriptorProtos.DescriptorProto;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Tests the exceptions thrown when parsing from a stream. The methods on the {@link Parser}

@ -42,13 +42,11 @@ import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestEmptyMessage;
import protobuf_unittest.UnittestProto.TestParsingMerge;
import protobuf_unittest.UnittestProto.TestRequired;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import junit.framework.TestCase;
/**
* Unit test for {@link Parser}.

@ -32,12 +32,11 @@ package com.google.protobuf;
import static java.util.Arrays.asList;
import junit.framework.TestCase;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
/**
* Tests for {@link ProtobufArrayList}.

@ -32,11 +32,9 @@ package com.google.protobuf;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
import junit.framework.TestCase;
import java.util.Collections;
import java.util.List;
import junit.framework.TestCase;
/**
* Tests for {@link RepeatedFieldBuilderV3}. This tests basic functionality.

@ -42,15 +42,13 @@ import protobuf_unittest.UnittestProto.FooResponse;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestService;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
import org.easymock.classextension.EasyMock;
import org.easymock.IArgumentMatcher;
import org.easymock.classextension.IMocksControl;
import java.util.HashSet;
import java.util.Set;
/**
* Tests services and stubs.
*
@ -271,6 +269,8 @@ public class ServiceTest extends TestCase {
file.getServices().get(0).getMethods().get(0).getName());
}
// =================================================================
/**

@ -30,8 +30,6 @@
package com.google.protobuf;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -40,6 +38,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import junit.framework.TestCase;
/**
* @author darick@google.com Darick Tong

@ -232,12 +232,10 @@ import protobuf_unittest.UnittestProto.TestOneof2;
import protobuf_unittest.UnittestProto.TestPackedExtensions;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestUnpackedTypes;
import junit.framework.Assert;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import junit.framework.Assert;
/**
* Contains methods for setting all fields of {@code TestAllTypes} to
@ -259,6 +257,13 @@ public final class TestUtil {
return ByteString.copyFrom(str.getBytes(Internal.UTF_8));
}
/**
* Dirties the message by resetting the momoized serialized size.
*/
public static void resetMemoizedSize(AbstractMessage message) {
message.memoizedSize = -1;
}
/**
* Get a {@code TestAllTypes} with all fields set as they would be by
* {@link #setAllFields(TestAllTypes.Builder)}.

@ -42,11 +42,9 @@ import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
import protobuf_unittest.UnittestProto.TestEmptyMessage;
import protobuf_unittest.UnittestProto.TestOneof2;
import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet;
import junit.framework.TestCase;
import java.io.StringReader;
import java.util.List;
import junit.framework.TestCase;
/**
* Test case for {@link TextFormat}.
@ -992,10 +990,35 @@ public class TextFormatTest extends TestCase {
assertParseSuccessWithOverwriteForbidden("repeated_nested_message [{ bb: 1 }, { bb: 2 }]\n");
}
public void testParseShortRepeatedFormOfEmptyRepeatedFields() throws Exception {
assertParseSuccessWithOverwriteForbidden("repeated_foreign_enum: []");
assertParseSuccessWithOverwriteForbidden("repeated_int32: []\n");
assertParseSuccessWithOverwriteForbidden("RepeatedGroup []\n");
assertParseSuccessWithOverwriteForbidden("repeated_nested_message []\n");
}
public void testParseShortRepeatedFormWithTrailingComma() throws Exception {
assertParseErrorWithOverwriteForbidden(
"1:38: Expected identifier. Found \']\'",
"repeated_foreign_enum: [FOREIGN_FOO, ]\n");
assertParseErrorWithOverwriteForbidden(
"1:22: Couldn't parse integer: For input string: \"]\"",
"repeated_int32: [ 1, ]\n");
assertParseErrorWithOverwriteForbidden(
"1:25: Expected \"{\".",
"RepeatedGroup [{ a: 1 },]\n");
assertParseErrorWithOverwriteForbidden(
"1:37: Expected \"{\".",
"repeated_nested_message [{ bb: 1 }, ]\n");
}
public void testParseShortRepeatedFormOfNonRepeatedFields() throws Exception {
assertParseErrorWithOverwriteForbidden(
"1:17: Couldn't parse integer: For input string: \"[\"",
"optional_int32: [1]\n");
assertParseErrorWithOverwriteForbidden(
"1:17: Couldn't parse integer: For input string: \"[\"",
"optional_int32: []\n");
}
// =======================================================================

@ -35,11 +35,9 @@ import com.google.protobuf.UnittestLite.TestAllTypesLite;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
import junit.framework.TestCase;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import junit.framework.TestCase;
/**
* Tests for {@link UnknownFieldSetLite}.

@ -38,11 +38,9 @@ import protobuf_unittest.UnittestProto.TestEmptyMessage;
import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions;
import protobuf_unittest.UnittestProto.TestPackedExtensions;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import junit.framework.TestCase;
import java.util.Arrays;
import java.util.Map;
import junit.framework.TestCase;
/**
* Tests related to unknown field handling.

@ -30,11 +30,10 @@
package com.google.protobuf;
import junit.framework.TestCase;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import junit.framework.TestCase;
/**
* Tests for {@link UnmodifiableLazyStringList}.

@ -44,12 +44,10 @@ import protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible;
import protobuf_unittest.UnittestProto.TestPackedExtensions;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.List;
import junit.framework.TestCase;
/**
* Tests related to parsing and serialization.

@ -36,7 +36,6 @@ import "google/protobuf/unittest.proto";
option java_package = "com.google.protobuf";
option java_outer_classname = "FieldPresenceTestProto";
option java_generate_equals_and_hash = true;
message TestAllTypes {
enum NestedEnum {

@ -32,7 +32,6 @@ syntax = "proto2";
option java_outer_classname = "MapForProto2TestProto";
option java_generate_equals_and_hash = true;
message TestMap {
message MessageValue {
@ -81,6 +80,42 @@ message BizarroTestMap {
map<string, bytes> int32_to_message_field = 5; // different key and value types
map<string, bytes> string_to_int32_field = 6; // same key type, different value
}
// Used to test that java reserved words can be used as protobuf field names
// Not all reserved words are tested (to avoid bloat) but instead an arbitrary
// subset of them chosen to cover various keyword categories like
// type, modifier, declaration, etc.
message ReservedAsMapField {
map<string, uint32> if = 1;
map<string, uint32> const = 2;
map<string, uint32> private = 3;
map<string, uint32> class = 4;
map<string, uint32> int = 5;
map<string, uint32> void = 6;
map<string, uint32> string = 7; // These are also proto keywords
map<string, uint32> package = 8;
map<string, uint32> enum = 9; // Most recent Java reserved word
map<string, uint32> null = 10;
// null is not a 'reserved word' per se but as a literal needs similar care
}
message ReservedAsMapFieldWithEnumValue {
enum SampleEnum {
A = 0;
B = 1;
}
map<string, SampleEnum> if = 1;
map<string, SampleEnum> const = 2;
map<string, SampleEnum> private = 3;
map<string, SampleEnum> class = 4;
map<string, SampleEnum> int = 5;
map<string, SampleEnum> void = 6;
map<string, SampleEnum> string = 7; // These are also proto keywords
map<string, SampleEnum> package = 8;
map<string, SampleEnum> enum = 9; // Most recent Java reserved word
map<string, SampleEnum> null = 10;
// null is not a 'reserved word' per se but as a literal needs similar care
}
package map_for_proto2_lite_test;
option java_package = "map_lite_test";
option optimize_for = LITE_RUNTIME;

@ -34,7 +34,6 @@ package map_for_proto2_test;
option java_package = "map_test";
option java_outer_classname = "MapForProto2TestProto";
option java_generate_equals_and_hash = true;
message TestMap {
message MessageValue {
@ -83,3 +82,39 @@ message BizarroTestMap {
map<string, bytes> int32_to_message_field = 5; // different key and value types
map<string, bytes> string_to_int32_field = 6; // same key type, different value
}
// Used to test that java reserved words can be used as protobuf field names
// Not all reserved words are tested (to avoid bloat) but instead an arbitrary
// subset of them chosen to cover various keyword categories like
// type, modifier, declaration, etc.
message ReservedAsMapField {
map<string, uint32> if = 1;
map<string, uint32> const = 2;
map<string, uint32> private = 3;
map<string, uint32> class = 4;
map<string, uint32> int = 5;
map<string, uint32> void = 6;
map<string, uint32> string = 7; // These are also proto keywords
map<string, uint32> package = 8;
map<string, uint32> enum = 9; // Most recent Java reserved word
map<string, uint32> null = 10;
// null is not a 'reserved word' per se but as a literal needs similar care
}
message ReservedAsMapFieldWithEnumValue {
enum SampleEnum {
A = 0;
B = 1;
}
map<string, SampleEnum> if = 1;
map<string, SampleEnum> const = 2;
map<string, SampleEnum> private = 3;
map<string, SampleEnum> class = 4;
map<string, SampleEnum> int = 5;
map<string, SampleEnum> void = 6;
map<string, SampleEnum> string = 7; // These are also proto keywords
map<string, SampleEnum> package = 8;
map<string, SampleEnum> enum = 9; // Most recent Java reserved word
map<string, SampleEnum> null = 10;
// null is not a 'reserved word' per se but as a literal needs similar care
}

@ -34,7 +34,6 @@ package map_test;
option java_package = "map_test";
option java_outer_classname = "MapTestProto";
option java_generate_equals_and_hash = true;
message TestMap {
message MessageValue {
@ -53,6 +52,8 @@ message TestMap {
map<int32, EnumValue> int32_to_enum_field = 4;
map<int32, MessageValue> int32_to_message_field = 5;
map<string, int32> string_to_int32_field = 6;
map<uint32, int32> uint32_to_int32_field = 7;
map<int64, int32> int64_to_int32_field = 8;
}
// Used to test that a nested builder containing map fields will properly
@ -71,3 +72,39 @@ message BizarroTestMap {
map<string, bytes> int32_to_message_field = 5; // different key and value types
map<string, bytes> string_to_int32_field = 6; // same key type, different value
}
// Used to test that java reserved words can be used as protobuf field names
// Not all reserved words are tested (to avoid bloat) but instead an arbitrary
// subset of them chosen to cover various keyword categories like
// type, modifier, declaration, etc.
message ReservedAsMapField {
map<string, uint32> if = 1;
map<string, uint32> const = 2;
map<string, uint32> private = 3;
map<string, uint32> class = 4;
map<string, uint32> int = 5;
map<string, uint32> void = 6;
map<string, uint32> string = 7; // These are also proto keywords
map<string, uint32> package = 8;
map<string, uint32> enum = 9; // Most recent Java reserved word
map<string, uint32> null = 10;
// null is not a 'reserved word' per se but as a literal needs similar care
}
message ReservedAsMapFieldWithEnumValue {
enum SampleEnum {
A = 0;
B = 1;
}
map<string, SampleEnum> if = 1;
map<string, SampleEnum> const = 2;
map<string, SampleEnum> private = 3;
map<string, SampleEnum> class = 4;
map<string, SampleEnum> int = 5;
map<string, SampleEnum> void = 6;
map<string, SampleEnum> string = 7; // These are also proto keywords
map<string, SampleEnum> package = 8;
map<string, SampleEnum> enum = 9; // Most recent Java reserved word
map<string, SampleEnum> null = 10;
// null is not a 'reserved word' per se but as a literal needs similar care
}

@ -43,7 +43,6 @@ package io_protocol_tests;
option java_package = "com.google.protobuf";
option java_outer_classname = "TestBadIdentifiersProto";
option java_generate_equals_and_hash = true;
message TestMessage {
optional string cached_size = 1;

@ -11,7 +11,7 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.0.2</version>
<version>3.1.0</version>
<packaging>pom</packaging>
<name>Protocol Buffers [Parent]</name>

@ -6,7 +6,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.0.2</version>
<version>3.1.0</version>
</parent>
<artifactId>protobuf-java-util</artifactId>

@ -30,50 +30,86 @@
package com.google.protobuf.util;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.math.IntMath.checkedAdd;
import static com.google.common.math.IntMath.checkedSubtract;
import static com.google.common.math.LongMath.checkedAdd;
import static com.google.common.math.LongMath.checkedMultiply;
import static com.google.common.math.LongMath.checkedSubtract;
import static com.google.protobuf.util.Timestamps.MICROS_PER_SECOND;
import static com.google.protobuf.util.Timestamps.MILLIS_PER_SECOND;
import static com.google.protobuf.util.Timestamps.NANOS_PER_MICROSECOND;
import static com.google.protobuf.util.Timestamps.NANOS_PER_MILLISECOND;
import static com.google.protobuf.util.Timestamps.NANOS_PER_SECOND;
import com.google.common.collect.ComparisonChain;
import com.google.protobuf.Duration;
import java.text.ParseException;
import java.util.Comparator;
/**
* Utilities to help create/manipulate {@code protobuf/duration.proto}.
* Utilities to help create/manipulate {@code protobuf/duration.proto}. All operations throw an
* {@link IllegalArgumentException} if the input(s) are not {@linkplain #isValid(Duration) valid}.
*/
public final class Durations {
static final long DURATION_SECONDS_MIN = -315576000000L;
static final long DURATION_SECONDS_MAX = 315576000000L;
// TODO(kak): Do we want to expose Duration constants for MAX/MIN?
/** A constant holding the minimum valid {@link Duration}, approximately {@code -10,000} years. */
public static final Duration MIN_VALUE =
Duration.newBuilder().setSeconds(DURATION_SECONDS_MIN).setNanos(-999999999).build();
/** A constant holding the maximum valid {@link Duration}, approximately {@code +10,000} years. */
public static final Duration MAX_VALUE =
Duration.newBuilder().setSeconds(DURATION_SECONDS_MAX).setNanos(999999999).build();
private Durations() {}
private static final Comparator<Duration> COMPARATOR =
new Comparator<Duration>() {
@Override
public int compare(Duration d1, Duration d2) {
checkValid(d1);
checkValid(d2);
return ComparisonChain.start()
.compare(d1.getSeconds(), d2.getSeconds())
.compare(d1.getNanos(), d2.getNanos())
.result();
}
};
/**
* Returns a {@link Comparator} for {@link Duration}s which sorts in increasing chronological
* order. Nulls and invalid {@link Duration}s are not allowed (see {@link #isValid}).
*/
public static Comparator<Duration> comparator() {
return COMPARATOR;
}
/**
* Returns true if the given {@link Duration} is valid. The {@code seconds} value must be in the
* range [-315,576,000,000, +315,576,000,000]. The {@code nanos} value must be in the range
* [-999,999,999, +999,999,999].
*
* <p>Note: Durations less than one second are represented with a 0 {@code seconds} field and a
* positive or negative {@code nanos} field. For durations of one second or more, a non-zero value
* for the {@code nanos} field must be of the same sign as the {@code seconds} field.
* <p><b>Note:</b> Durations less than one second are represented with a 0 {@code seconds} field
* and a positive or negative {@code nanos} field. For durations of one second or more, a non-zero
* value for the {@code nanos} field must be of the same sign as the {@code seconds} field.
*/
public static boolean isValid(Duration duration) {
return isValid(duration.getSeconds(), duration.getNanos());
}
/**
* Returns true if the given number of seconds and nanos is a valid {@link Duration}. The
* {@code seconds} value must be in the range [-315,576,000,000, +315,576,000,000]. The
* {@code nanos} value must be in the range [-999,999,999, +999,999,999].
* Returns true if the given number of seconds and nanos is a valid {@link Duration}. The {@code
* seconds} value must be in the range [-315,576,000,000, +315,576,000,000]. The {@code nanos}
* value must be in the range [-999,999,999, +999,999,999].
*
* <p>Note: Durations less than one second are represented with a 0 {@code seconds} field and a
* positive or negative {@code nanos} field. For durations of one second or more, a non-zero value
* for the {@code nanos} field must be of the same sign as the {@code seconds} field.
* <p><b>Note:</b> Durations less than one second are represented with a 0 {@code seconds} field
* and a positive or negative {@code nanos} field. For durations of one second or more, a non-zero
* value for the {@code nanos} field must be of the same sign as the {@code seconds} field.
*/
public static boolean isValid(long seconds, long nanos) {
public static boolean isValid(long seconds, int nanos) {
if (seconds < DURATION_SECONDS_MIN || seconds > DURATION_SECONDS_MAX) {
return false;
}
@ -88,35 +124,35 @@ public final class Durations {
return true;
}
/**
* Throws an {@link IllegalArgumentException} if the given seconds/nanos are not
* a valid {@link Duration}.
*/
private static void checkValid(long seconds, int nanos) {
if (!isValid(seconds, nanos)) {
throw new IllegalArgumentException(String.format(
"Duration is not valid. See proto definition for valid values. "
+ "Seconds (%s) must be in range [-315,576,000,000, +315,576,000,000]."
+ "Nanos (%s) must be in range [-999,999,999, +999,999,999]. "
+ "Nanos must have the same sign as seconds", seconds, nanos));
}
/** Throws an {@link IllegalArgumentException} if the given {@link Duration} is not valid. */
public static Duration checkValid(Duration duration) {
long seconds = duration.getSeconds();
int nanos = duration.getNanos();
checkArgument(
isValid(seconds, nanos),
"Duration is not valid. See proto definition for valid values. "
+ "Seconds (%s) must be in range [-315,576,000,000, +315,576,000,000]. "
+ "Nanos (%s) must be in range [-999,999,999, +999,999,999]. "
+ "Nanos must have the same sign as seconds",
seconds,
nanos);
return duration;
}
/**
* Convert Duration to string format. The string format will contains 3, 6,
* or 9 fractional digits depending on the precision required to represent
* the exact Duration value. For example: "1s", "1.010s", "1.000000100s",
* "-3.100s" The range that can be represented by Duration is from
* Convert Duration to string format. The string format will contains 3, 6, or 9 fractional digits
* depending on the precision required to represent the exact Duration value. For example: "1s",
* "1.010s", "1.000000100s", "-3.100s" The range that can be represented by Duration is from
* -315,576,000,000 to +315,576,000,000 inclusive (in seconds).
*
* @return The string representation of the given duration.
* @throws IllegalArgumentException if the given duration is not in the valid
* range.
* @throws IllegalArgumentException if the given duration is not in the valid range.
*/
public static String toString(Duration duration) {
checkValid(duration);
long seconds = duration.getSeconds();
int nanos = duration.getNanos();
checkValid(seconds, nanos);
StringBuilder result = new StringBuilder();
if (seconds < 0 || nanos < 0) {
@ -172,9 +208,20 @@ public final class Durations {
}
}
/** Create a Duration from the number of seconds. */
public static Duration fromSeconds(long seconds) {
return normalizedDuration(seconds, 0);
}
/**
* Create a Duration from the number of milliseconds.
* Convert a Duration to the number of seconds. The result will be rounded towards 0 to the
* nearest second. E.g., if the duration represents -1 nanosecond, it will be rounded to 0.
*/
public static long toSeconds(Duration duration) {
return checkValid(duration).getSeconds();
}
/** Create a Duration from the number of milliseconds. */
public static Duration fromMillis(long milliseconds) {
return normalizedDuration(
milliseconds / MILLIS_PER_SECOND,
@ -182,17 +229,17 @@ public final class Durations {
}
/**
* Convert a Duration to the number of milliseconds.The result will be
* rounded towards 0 to the nearest millisecond. E.g., if the duration
* represents -1 nanosecond, it will be rounded to 0.
* Convert a Duration to the number of milliseconds. The result will be rounded towards 0 to the
* nearest millisecond. E.g., if the duration represents -1 nanosecond, it will be rounded to 0.
*/
public static long toMillis(Duration duration) {
return duration.getSeconds() * MILLIS_PER_SECOND + duration.getNanos() / NANOS_PER_MILLISECOND;
checkValid(duration);
return checkedAdd(
checkedMultiply(duration.getSeconds(), MILLIS_PER_SECOND),
duration.getNanos() / NANOS_PER_MILLISECOND);
}
/**
* Create a Duration from the number of microseconds.
*/
/** Create a Duration from the number of microseconds. */
public static Duration fromMicros(long microseconds) {
return normalizedDuration(
microseconds / MICROS_PER_SECOND,
@ -200,57 +247,60 @@ public final class Durations {
}
/**
* Convert a Duration to the number of microseconds.The result will be
* rounded towards 0 to the nearest microseconds. E.g., if the duration
* represents -1 nanosecond, it will be rounded to 0.
* Convert a Duration to the number of microseconds. The result will be rounded towards 0 to the
* nearest microseconds. E.g., if the duration represents -1 nanosecond, it will be rounded to 0.
*/
public static long toMicros(Duration duration) {
return duration.getSeconds() * MICROS_PER_SECOND + duration.getNanos() / NANOS_PER_MICROSECOND;
checkValid(duration);
return checkedAdd(
checkedMultiply(duration.getSeconds(), MICROS_PER_SECOND),
duration.getNanos() / NANOS_PER_MICROSECOND);
}
/**
* Create a Duration from the number of nanoseconds.
*/
/** Create a Duration from the number of nanoseconds. */
public static Duration fromNanos(long nanoseconds) {
return normalizedDuration(
nanoseconds / NANOS_PER_SECOND, (int) (nanoseconds % NANOS_PER_SECOND));
}
/**
* Convert a Duration to the number of nanoseconds.
*/
/** Convert a Duration to the number of nanoseconds. */
public static long toNanos(Duration duration) {
return duration.getSeconds() * NANOS_PER_SECOND + duration.getNanos();
checkValid(duration);
return checkedAdd(
checkedMultiply(duration.getSeconds(), NANOS_PER_SECOND), duration.getNanos());
}
/**
* Add two durations.
*/
/** Add two durations. */
public static Duration add(Duration d1, Duration d2) {
return normalizedDuration(d1.getSeconds() + d2.getSeconds(), d1.getNanos() + d2.getNanos());
checkValid(d1);
checkValid(d2);
return normalizedDuration(
checkedAdd(d1.getSeconds(), d2.getSeconds()), checkedAdd(d1.getNanos(), d2.getNanos()));
}
/**
* Subtract a duration from another.
*/
/** Subtract a duration from another. */
public static Duration subtract(Duration d1, Duration d2) {
return normalizedDuration(d1.getSeconds() - d2.getSeconds(), d1.getNanos() - d2.getNanos());
checkValid(d1);
checkValid(d2);
return normalizedDuration(
checkedSubtract(d1.getSeconds(), d2.getSeconds()),
checkedSubtract(d1.getNanos(), d2.getNanos()));
}
static Duration normalizedDuration(long seconds, int nanos) {
if (nanos <= -NANOS_PER_SECOND || nanos >= NANOS_PER_SECOND) {
seconds += nanos / NANOS_PER_SECOND;
seconds = checkedAdd(seconds, nanos / NANOS_PER_SECOND);
nanos %= NANOS_PER_SECOND;
}
if (seconds > 0 && nanos < 0) {
nanos += NANOS_PER_SECOND;
seconds -= 1;
nanos += NANOS_PER_SECOND; // no overflow since nanos is negative (and we're adding)
seconds--; // no overflow since seconds is positive (and we're decrementing)
}
if (seconds < 0 && nanos > 0) {
nanos -= NANOS_PER_SECOND;
seconds += 1;
nanos -= NANOS_PER_SECOND; // no overflow since nanos is positive (and we're subtracting)
seconds++; // no overflow since seconds is negative (and we're incrementing)
}
checkValid(seconds, nanos);
return Duration.newBuilder().setSeconds(seconds).setNanos(nanos).build();
Duration duration = Duration.newBuilder().setSeconds(seconds).setNanos(nanos).build();
return checkValid(duration);
}
}

@ -640,6 +640,10 @@ public class JsonFormat {
/** Prints google.protobuf.Any */
private void printAny(MessageOrBuilder message) throws IOException {
if (Any.getDefaultInstance().equals(message)) {
generator.print("{}");
return;
}
Descriptor descriptor = message.getDescriptorForType();
FieldDescriptor typeUrlField = descriptor.findFieldByName("type_url");
FieldDescriptor valueField = descriptor.findFieldByName("value");
@ -1235,6 +1239,9 @@ public class JsonFormat {
throw new InvalidProtocolBufferException("Expect message object but got: " + json);
}
JsonObject object = (JsonObject) json;
if (object.entrySet().isEmpty()) {
return; // builder never modified, so it will end up building the default instance of Any
}
JsonElement typeUrlElement = object.get("@type");
if (typeUrlElement == null) {
throw new InvalidProtocolBufferException("Missing type url when parsing: " + json);
@ -1327,6 +1334,9 @@ public class JsonFormat {
Message.Builder listBuilder = builder.newBuilderForField(field);
merge(json, listBuilder);
builder.setField(field, listBuilder.build());
} else if (json instanceof JsonNull) {
builder.setField(
type.findFieldByName("null_value"), NullValue.NULL_VALUE.getValueDescriptor());
} else {
throw new IllegalStateException("Unexpected json data: " + json);
}
@ -1620,11 +1630,6 @@ public class JsonFormat {
}
private ByteString parseBytes(JsonElement json) throws InvalidProtocolBufferException {
String encoded = json.getAsString();
if (encoded.length() % 4 != 0) {
throw new InvalidProtocolBufferException(
"Bytes field is not encoded in standard BASE64 with paddings: " + encoded);
}
return ByteString.copyFrom(BaseEncoding.base64().decode(json.getAsString()));
}

@ -30,19 +30,29 @@
package com.google.protobuf.util;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.math.IntMath.checkedAdd;
import static com.google.common.math.IntMath.checkedSubtract;
import static com.google.common.math.LongMath.checkedAdd;
import static com.google.common.math.LongMath.checkedMultiply;
import static com.google.common.math.LongMath.checkedSubtract;
import com.google.common.collect.ComparisonChain;
import com.google.protobuf.Duration;
import com.google.protobuf.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
/**
* Utilities to help create/manipulate {@code protobuf/timestamp.proto}.
* Utilities to help create/manipulate {@code protobuf/timestamp.proto}. All operations throw an
* {@link IllegalArgumentException} if the input(s) are not {@linkplain #isValid(Timestamp) valid}.
*/
public final class Timestamps {
// Timestamp for "0001-01-01T00:00:00Z"
static final long TIMESTAMP_SECONDS_MIN = -62135596800L;
@ -55,10 +65,19 @@ public final class Timestamps {
static final long MILLIS_PER_SECOND = 1000;
static final long MICROS_PER_SECOND = 1000000;
// TODO(kak): Do we want to expose Timestamp constants for MAX/MIN?
/** A constant holding the minimum valid {@link Timestamp}, {@code 0001-01-01T00:00:00Z}. */
public static final Timestamp MIN_VALUE =
Timestamp.newBuilder().setSeconds(TIMESTAMP_SECONDS_MIN).setNanos(0).build();
/**
* A constant holding the maximum valid {@link Timestamp}, {@code 9999-12-31T23:59:59.999999999Z}.
*/
public static final Timestamp MAX_VALUE =
Timestamp.newBuilder().setSeconds(TIMESTAMP_SECONDS_MAX).setNanos(999999999).build();
private static final ThreadLocal<SimpleDateFormat> timestampFormat =
new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return createTimestampFormat();
}
@ -76,28 +95,50 @@ public final class Timestamps {
private Timestamps() {}
private static final Comparator<Timestamp> COMPARATOR =
new Comparator<Timestamp>() {
@Override
public int compare(Timestamp t1, Timestamp t2) {
checkValid(t1);
checkValid(t2);
return ComparisonChain.start()
.compare(t1.getSeconds(), t2.getSeconds())
.compare(t1.getNanos(), t2.getNanos())
.result();
}
};
/**
* Returns a {@link Comparator} for {@link Timestamp}s which sorts in increasing chronological
* order. Nulls and invalid {@link Timestamp}s are not allowed (see {@link #isValid}).
*/
public static Comparator<Timestamp> comparator() {
return COMPARATOR;
}
/**
* Returns true if the given {@link Timestamp} is valid. The {@code seconds} value must be in the
* range [-62,135,596,800, +253,402,300,799] (i.e., between 0001-01-01T00:00:00Z and
* 9999-12-31T23:59:59Z). The {@code nanos} value must be in the range [0, +999,999,999].
*
* <p>Note: Negative second values with fractions must still have non-negative nanos value that
* counts forward in time.
* <p><b>Note:</b> Negative second values with fractional seconds must still have non-negative
* nanos values that count forward in time.
*/
public static boolean isValid(Timestamp timestamp) {
return isValid(timestamp.getSeconds(), timestamp.getNanos());
}
/**
* Returns true if the given number of seconds and nanos is a valid {@link Timestamp}. The
* {@code seconds} value must be in the range [-62,135,596,800, +253,402,300,799] (i.e., between
* Returns true if the given number of seconds and nanos is a valid {@link Timestamp}. The {@code
* seconds} value must be in the range [-62,135,596,800, +253,402,300,799] (i.e., between
* 0001-01-01T00:00:00Z and 9999-12-31T23:59:59Z). The {@code nanos} value must be in the range
* [0, +999,999,999].
*
* <p>Note: Negative second values with fractions must still have non-negative nanos value that
* counts forward in time.
* <p><b>Note:</b> Negative second values with fractional seconds must still have non-negative
* nanos values that count forward in time.
*/
public static boolean isValid(long seconds, long nanos) {
public static boolean isValid(long seconds, int nanos) {
if (seconds < TIMESTAMP_SECONDS_MIN || seconds > TIMESTAMP_SECONDS_MAX) {
return false;
}
@ -107,37 +148,37 @@ public final class Timestamps {
return true;
}
/**
* Throws an {@link IllegalArgumentException} if the given seconds/nanos are not
* a valid {@link Timestamp}.
*/
private static void checkValid(long seconds, int nanos) {
if (!isValid(seconds, nanos)) {
throw new IllegalArgumentException(String.format(
"Timestamp is not valid. See proto definition for valid values. "
+ "Seconds (%s) must be in range [-62,135,596,800, +253,402,300,799]."
+ "Nanos (%s) must be in range [0, +999,999,999].",
seconds, nanos));
}
/** Throws an {@link IllegalArgumentException} if the given {@link Timestamp} is not valid. */
public static Timestamp checkValid(Timestamp timestamp) {
long seconds = timestamp.getSeconds();
int nanos = timestamp.getNanos();
checkArgument(
isValid(seconds, nanos),
"Timestamp is not valid. See proto definition for valid values. "
+ "Seconds (%s) must be in range [-62,135,596,800, +253,402,300,799]. "
+ "Nanos (%s) must be in range [0, +999,999,999].",
seconds,
nanos);
return timestamp;
}
/**
* Convert Timestamp to RFC 3339 date string format. The output will always
* be Z-normalized and uses 3, 6 or 9 fractional digits as required to
* represent the exact value. Note that Timestamp can only represent time
* from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. See
* Convert Timestamp to RFC 3339 date string format. The output will always be Z-normalized and
* uses 3, 6 or 9 fractional digits as required to represent the exact value. Note that Timestamp
* can only represent time from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. See
* https://www.ietf.org/rfc/rfc3339.txt
*
* <p>Example of generated format: "1972-01-01T10:00:20.021Z"
*
* @return The string representation of the given timestamp.
* @throws IllegalArgumentException if the given timestamp is not in the
* valid range.
* @throws IllegalArgumentException if the given timestamp is not in the valid range.
*/
public static String toString(Timestamp timestamp) {
checkValid(timestamp);
long seconds = timestamp.getSeconds();
int nanos = timestamp.getNanos();
checkValid(seconds, nanos);
StringBuilder result = new StringBuilder();
// Format the seconds part.
Date date = new Date(seconds * MILLIS_PER_SECOND);
@ -152,10 +193,9 @@ public final class Timestamps {
}
/**
* Parse from RFC 3339 date string to Timestamp. This method accepts all
* outputs of {@link #toString(Timestamp)} and it also accepts any fractional
* digits (or none) and any offset as long as they fit into nano-seconds
* precision.
* Parse from RFC 3339 date string to Timestamp. This method accepts all outputs of {@link
* #toString(Timestamp)} and it also accepts any fractional digits (or none) and any offset as
* long as they fit into nano-seconds precision.
*
* <p>Example of accepted format: "1972-01-01T10:00:20.021-05:00"
*
@ -210,13 +250,26 @@ public final class Timestamps {
try {
return normalizedTimestamp(seconds, nanos);
} catch (IllegalArgumentException e) {
throw new ParseException("Failed to parse timestmap: timestamp is out of range.", 0);
throw new ParseException("Failed to parse timestamp: timestamp is out of range.", 0);
}
}
/** Create a Timestamp from the number of seconds elapsed from the epoch. */
public static Timestamp fromSeconds(long seconds) {
return normalizedTimestamp(seconds, 0);
}
/**
* Create a Timestamp from the number of milliseconds elapsed from the epoch.
* Convert a Timestamp to the number of seconds elapsed from the epoch.
*
* <p>The result will be rounded down to the nearest second. E.g., if the timestamp represents
* "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 second.
*/
public static long toSeconds(Timestamp timestamp) {
return checkValid(timestamp).getSeconds();
}
/** Create a Timestamp from the number of milliseconds elapsed from the epoch. */
public static Timestamp fromMillis(long milliseconds) {
return normalizedTimestamp(
milliseconds / MILLIS_PER_SECOND,
@ -226,18 +279,17 @@ public final class Timestamps {
/**
* Convert a Timestamp to the number of milliseconds elapsed from the epoch.
*
* <p>The result will be rounded down to the nearest millisecond. E.g., if the
* timestamp represents "1969-12-31T23:59:59.999999999Z", it will be rounded
* to -1 millisecond.
* <p>The result will be rounded down to the nearest millisecond. E.g., if the timestamp
* represents "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 millisecond.
*/
public static long toMillis(Timestamp timestamp) {
return timestamp.getSeconds() * MILLIS_PER_SECOND
+ timestamp.getNanos() / NANOS_PER_MILLISECOND;
checkValid(timestamp);
return checkedAdd(
checkedMultiply(timestamp.getSeconds(), MILLIS_PER_SECOND),
timestamp.getNanos() / NANOS_PER_MILLISECOND);
}
/**
* Create a Timestamp from the number of microseconds elapsed from the epoch.
*/
/** Create a Timestamp from the number of microseconds elapsed from the epoch. */
public static Timestamp fromMicros(long microseconds) {
return normalizedTimestamp(
microseconds / MICROS_PER_SECOND,
@ -247,65 +299,67 @@ public final class Timestamps {
/**
* Convert a Timestamp to the number of microseconds elapsed from the epoch.
*
* <p>The result will be rounded down to the nearest microsecond. E.g., if the
* timestamp represents "1969-12-31T23:59:59.999999999Z", it will be rounded
* to -1 millisecond.
* <p>The result will be rounded down to the nearest microsecond. E.g., if the timestamp
* represents "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 millisecond.
*/
public static long toMicros(Timestamp timestamp) {
return timestamp.getSeconds() * MICROS_PER_SECOND
+ timestamp.getNanos() / NANOS_PER_MICROSECOND;
checkValid(timestamp);
return checkedAdd(
checkedMultiply(timestamp.getSeconds(), MICROS_PER_SECOND),
timestamp.getNanos() / NANOS_PER_MICROSECOND);
}
/**
* Create a Timestamp from the number of nanoseconds elapsed from the epoch.
*/
/** Create a Timestamp from the number of nanoseconds elapsed from the epoch. */
public static Timestamp fromNanos(long nanoseconds) {
return normalizedTimestamp(
nanoseconds / NANOS_PER_SECOND, (int) (nanoseconds % NANOS_PER_SECOND));
}
/**
* Convert a Timestamp to the number of nanoseconds elapsed from the epoch.
*/
/** Convert a Timestamp to the number of nanoseconds elapsed from the epoch. */
public static long toNanos(Timestamp timestamp) {
return timestamp.getSeconds() * NANOS_PER_SECOND + timestamp.getNanos();
checkValid(timestamp);
return checkedAdd(
checkedMultiply(timestamp.getSeconds(), NANOS_PER_SECOND), timestamp.getNanos());
}
/**
* Calculate the difference between two timestamps.
*/
/** Calculate the difference between two timestamps. */
public static Duration between(Timestamp from, Timestamp to) {
checkValid(from);
checkValid(to);
return Durations.normalizedDuration(
to.getSeconds() - from.getSeconds(), to.getNanos() - from.getNanos());
checkedSubtract(to.getSeconds(), from.getSeconds()),
checkedSubtract(to.getNanos(), from.getNanos()));
}
/**
* Add a duration to a timestamp.
*/
/** Add a duration to a timestamp. */
public static Timestamp add(Timestamp start, Duration length) {
checkValid(start);
Durations.checkValid(length);
return normalizedTimestamp(
start.getSeconds() + length.getSeconds(), start.getNanos() + length.getNanos());
checkedAdd(start.getSeconds(), length.getSeconds()),
checkedAdd(start.getNanos(), length.getNanos()));
}
/**
* Subtract a duration from a timestamp.
*/
/** Subtract a duration from a timestamp. */
public static Timestamp subtract(Timestamp start, Duration length) {
checkValid(start);
Durations.checkValid(length);
return normalizedTimestamp(
start.getSeconds() - length.getSeconds(), start.getNanos() - length.getNanos());
checkedSubtract(start.getSeconds(), length.getSeconds()),
checkedSubtract(start.getNanos(), length.getNanos()));
}
private static Timestamp normalizedTimestamp(long seconds, int nanos) {
static Timestamp normalizedTimestamp(long seconds, int nanos) {
if (nanos <= -NANOS_PER_SECOND || nanos >= NANOS_PER_SECOND) {
seconds += nanos / NANOS_PER_SECOND;
seconds = checkedAdd(seconds, nanos / NANOS_PER_SECOND);
nanos %= NANOS_PER_SECOND;
}
if (nanos < 0) {
nanos += NANOS_PER_SECOND;
seconds -= 1;
nanos += NANOS_PER_SECOND; // no overflow since nanos is negative (and we're adding)
seconds = checkedSubtract(seconds, 1);
}
checkValid(seconds, nanos);
return Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build();
Timestamp timestamp = Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build();
return checkValid(timestamp);
}
private static long parseTimezoneOffset(String value) throws ParseException {
@ -324,7 +378,7 @@ public final class Timestamps {
result = result * 10;
if (i < value.length()) {
if (value.charAt(i) < '0' || value.charAt(i) > '9') {
throw new ParseException("Invalid nanosecnds.", 0);
throw new ParseException("Invalid nanoseconds.", 0);
}
result += value.charAt(i) - '0';
}
@ -332,11 +386,8 @@ public final class Timestamps {
return result;
}
/**
* Format the nano part of a timestamp or a duration.
*/
/** Format the nano part of a timestamp or a duration. */
static String formatNanos(int nanos) {
assert nanos >= 1 && nanos <= 999999999;
// Determine whether to use 3, 6, or 9 digits for the nano part.
if (nanos % NANOS_PER_MILLISECOND == 0) {
return String.format("%1$03d", nanos / NANOS_PER_MILLISECOND);

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

Loading…
Cancel
Save