Merge branch 'master' into kotlinProtos
This commit is contained in:
commit
87faccd18e
4
.github/mergeable.yml
vendored
4
.github/mergeable.yml
vendored
@ -11,8 +11,8 @@ mergeable:
|
||||
regex: 'release notes: yes'
|
||||
message: 'Please include release notes: yes'
|
||||
- must_include:
|
||||
regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel|cmake|protoc)'
|
||||
message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cmake, cleanup, conformance tests, integration, protoc.'
|
||||
regex: '^(autotools|bazel|c#|c\+\+|cleanup|cmake|conformance tests|integration|go|java|javascript|objective-c|php|protoc|python|ruby)'
|
||||
message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: autotools, bazel, cmake, cleanup, conformance tests, integration, protoc.'
|
||||
- must_include:
|
||||
regex: 'release notes: no'
|
||||
message: 'Please include release notes: no'
|
||||
|
44
BUILD
44
BUILD
@ -14,38 +14,6 @@ exports_files(["LICENSE"])
|
||||
# build configuration
|
||||
################################################################################
|
||||
|
||||
# TODO(yannic): Remove in 3.14.0.
|
||||
string_flag(
|
||||
name = "incompatible_use_com_google_googletest",
|
||||
build_setting_default = "true",
|
||||
values = ["true", "false"]
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "use_com_google_googletest",
|
||||
flag_values = {
|
||||
"//:incompatible_use_com_google_googletest": "true"
|
||||
},
|
||||
)
|
||||
|
||||
GTEST = select({
|
||||
"//:use_com_google_googletest": [
|
||||
"@com_google_googletest//:gtest",
|
||||
],
|
||||
"//conditions:default": [
|
||||
"//external:gtest",
|
||||
],
|
||||
})
|
||||
|
||||
GTEST_MAIN = select({
|
||||
"//:use_com_google_googletest": [
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
"//conditions:default": [
|
||||
"//external:gtest_main",
|
||||
],
|
||||
})
|
||||
|
||||
################################################################################
|
||||
# ZLIB configuration
|
||||
################################################################################
|
||||
@ -571,6 +539,7 @@ COMMON_TEST_SRCS = [
|
||||
|
||||
cc_binary(
|
||||
name = "test_plugin",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
# AUTOGEN(test_plugin_srcs)
|
||||
"src/google/protobuf/compiler/mock_code_generator.cc",
|
||||
@ -580,7 +549,8 @@ cc_binary(
|
||||
deps = [
|
||||
":protobuf",
|
||||
":protoc_lib",
|
||||
] + GTEST,
|
||||
"@com_google_googletest//:gtest",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
@ -592,7 +562,9 @@ cc_test(
|
||||
],
|
||||
deps = [
|
||||
":protobuf_lite",
|
||||
] + GTEST_MAIN,
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
@ -695,7 +667,9 @@ cc_test(
|
||||
":cc_test_protos",
|
||||
":protobuf",
|
||||
":protoc_lib",
|
||||
] + PROTOBUF_DEPS + GTEST_MAIN,
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
] + PROTOBUF_DEPS,
|
||||
)
|
||||
|
||||
################################################################################
|
||||
|
150
CHANGES.txt
150
CHANGES.txt
@ -1,5 +1,93 @@
|
||||
Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
C++
|
||||
* Allow MessageDifferencer::TreatAsSet() (and friends) to override previous
|
||||
calls instead of crashing.
|
||||
* Reduce the size of generated proto headers for protos with `string` or
|
||||
`bytes` fields.
|
||||
* Move arena() operation on uncommon path to out-of-line routine
|
||||
* For iterator-pair function parameter types, take both iterators by value.
|
||||
* Code-space savings and perhaps some modest performance improvements in
|
||||
RepeatedPtrField.
|
||||
* Eliminate nullptr check from every tag parse.
|
||||
* Remove unused _$name$_cached_byte_size_ fields.
|
||||
* Serialize extension ranges together when not broken by a proto field in the
|
||||
middle.
|
||||
* Do out-of-line allocation and deallocation of string object in ArenaString.
|
||||
* Streamline ParseContext::ParseMessage<T> to avoid code bloat and improve
|
||||
performance.
|
||||
* New member functions RepeatedField::Assign, RepeatedPtrField::{Add, Assign}.
|
||||
* Fix undefined behavior warning due to innocuous uninitialization of value
|
||||
on an error path.
|
||||
* Avoid expensive inlined code space for encoding message length for messages
|
||||
>= 128 bytes and instead do a procedure call to a shared out-of-line routine.
|
||||
|
||||
Java:
|
||||
* Exceptions thrown while reading from an InputStream in parseFrom are now
|
||||
included as causes.
|
||||
* Support potentially more efficient proto parsing from RopeByteStrings.
|
||||
* Clarify runtime of ByteString.Output.toStringBuffer().
|
||||
|
||||
Python
|
||||
* Fixed a bug in text format where a trailing colon was printed for repeated field.
|
||||
* When TextFormat encounters a duplicate message map key, replace the current
|
||||
one instead of merging.
|
||||
|
||||
JavaScript
|
||||
* Make Any.pack() chainable.
|
||||
|
||||
2021-03-10 version 3.15.6 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
Ruby
|
||||
* Fixed bug in string comparison logic (#8386)
|
||||
|
||||
2021-03-04 version 3.15.5 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
Ruby
|
||||
* Fixed quadratic memory use in array append (#8379)
|
||||
|
||||
PHP
|
||||
* Fixed quadratic memory use in array append (#8379)
|
||||
|
||||
C++
|
||||
* Do not disable RTTI by default in the CMake build (#8377)
|
||||
|
||||
2021-03-02 version 3.15.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
Ruby
|
||||
* Fixed SEGV when users pass nil messages (#8363)
|
||||
* Fixed quadratic memory usage when appending to arrays (#8364)
|
||||
|
||||
C++
|
||||
* Create a CMake option to control whether or not RTTI is enabled (#8361)
|
||||
|
||||
PHP
|
||||
* read_property() handler is not supposed to return NULL (#8362)
|
||||
|
||||
2021-02-25 version 3.15.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
Ruby
|
||||
* Ruby <2.7 now uses WeakMap too, which prevents memory leaks. (#8341)
|
||||
|
||||
2021-02-23 version 3.15.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
Ruby
|
||||
* Fix for FieldDescriptor.get(msg) (#8330)
|
||||
|
||||
C++
|
||||
* Fix PROTOBUF_CONSTINIT macro redefinition (#8323)
|
||||
|
||||
2021-02-05 version 3.15.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
Ruby
|
||||
* Bugfix for Message.[] for repeated or map fields (#8313)
|
||||
|
||||
2021-02-05 version 3.15.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
Protocol Compiler
|
||||
* Optional fields for proto3 are enabled by default, and no longer require
|
||||
the --experimental_allow_proto3_optional flag.
|
||||
|
||||
C++
|
||||
* MessageDifferencer: fixed bug when using custom ignore with multiple
|
||||
unknown fields
|
||||
@ -23,11 +111,56 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
output (does not affect comparison logic) and stop printing 'value' in the
|
||||
path. The modified print functionality is in the
|
||||
MessageDifferencer::StreamReporter.
|
||||
* Fixes https://github.com/protocolbuffers/protobuf/issues/8129
|
||||
* Fixed https://github.com/protocolbuffers/protobuf/issues/8129
|
||||
* Ensure that null char symbol, package and file names do not result in a
|
||||
crash.
|
||||
* Constant initialize the global message instances
|
||||
* Pretty print 'max' instead of numeric values in reserved ranges.
|
||||
* Removed remaining instances of std::is_pod, which is deprecated in C++20.
|
||||
* Changes to reduce code size for unknown field handling by making uncommon
|
||||
cases out of line.
|
||||
* Fix std::is_pod deprecated in C++20 (#7180)
|
||||
* Fix some -Wunused-parameter warnings (#8053)
|
||||
* Fix detecting file as directory on zOS issue #8051 (#8052)
|
||||
* Don't include sys/param.h for _BYTE_ORDER (#8106)
|
||||
* remove CMAKE_THREAD_LIBS_INIT from pkgconfig CFLAGS (#8154)
|
||||
* Fix TextFormatMapTest.DynamicMessage issue#5136 (#8159)
|
||||
* Fix for compiler warning issue#8145 (#8160)
|
||||
* fix: support deprecated enums for GCC < 6 (#8164)
|
||||
* Fix some warning when compiling with Visual Studio 2019 on x64 target (#8125)
|
||||
|
||||
Python
|
||||
* Provided an override for the reverse() method that will reverse the internal
|
||||
collection directly instead of using the other methods of the BaseContainer.
|
||||
* MessageFactory.CreateProtoype can be overridden to customize class creation.
|
||||
* Fix PyUnknownFields memory leak (#7928)
|
||||
* Add macOS big sur compatibility (#8126)
|
||||
|
||||
JavaScript
|
||||
* Generate `getDescriptor` methods with `*` as their `this` type.
|
||||
* Enforce `let/const` for generated messages.
|
||||
* js/binary/utils.js: Fix jspb.utils.joinUnsignedDecimalString to work with negative bitsLow and low but non-zero bitsHigh parameter. (#8170)
|
||||
|
||||
PHP
|
||||
* Added support for PHP 8. (#8105)
|
||||
* unregister INI entries and fix invalid read on shutdown (#8042)
|
||||
* Fix PhpDoc comments for message accessors to include "|null". (#8136)
|
||||
* fix: convert native PHP floats to single precision (#8187)
|
||||
* Fixed PHP to support field numbers >=2**28. (#8235)
|
||||
* feat: add support for deprecated fields to PHP compiler (#8223)
|
||||
* Protect against stack overflow if the user derives from Message. (#8248)
|
||||
* Fixed clone for Message, RepeatedField, and MapField. (#8245)
|
||||
* Updated upb to allow nonzero offset minutes in JSON timestamps. (#8258)
|
||||
|
||||
Ruby
|
||||
* Added support for Ruby 3. (#8184)
|
||||
* Rewrote the data storage layer to be based on upb_msg objects from the
|
||||
upb library. This should lead to much better parsing performance,
|
||||
particularly for large messages. (#8184).
|
||||
* Fill out JRuby support (#7923)
|
||||
* [Ruby] Fix: (SIGSEGV) gRPC-Ruby issue on Windows. memory alloc infinite
|
||||
recursion/run out of memory (#8195)
|
||||
* Fix jruby support to handle messages nested more than 1 level deep (#8194)
|
||||
|
||||
Java
|
||||
* Avoid possible UnsupportedOperationException when using CodedInputSteam
|
||||
@ -40,15 +173,14 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
* Now Proto3 Oneof fields have "has" methods for checking their presence in
|
||||
Java.
|
||||
* Annotates Java proto generated *_FIELD_NUMBER constants.
|
||||
* Add -assumevalues to remove JvmMemoryAccessor on Android.
|
||||
|
||||
Python
|
||||
* Provided an override for the reverse() method that will reverse the internal
|
||||
collection directly instead of using the other methods of the BaseContainer.
|
||||
* MessageFactory.CreateProtoype can be overridden to customize class creation.
|
||||
|
||||
Javascript
|
||||
* Generate `getDescriptor` methods with `*` as their `this` type.
|
||||
* Enforce `let/const` for generated messages.
|
||||
C#
|
||||
* Fix parsing negative Int32Value that crosses segment boundary (#8035)
|
||||
* Change ByteString to use memory and support unsafe create without copy (#7645)
|
||||
* Optimize MapField serialization by removing MessageAdapter (#8143)
|
||||
* Allow FileDescriptors to be parsed with extension registries (#8220)
|
||||
* Optimize writing small strings (#8149)
|
||||
|
||||
2020-11-11 version 3.14.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
|
@ -544,7 +544,6 @@ java_EXTRA_DIST=
|
||||
java/core/src/test/proto/com/google/protobuf/test_check_utf8.proto \
|
||||
java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto \
|
||||
java/core/src/test/proto/com/google/protobuf/test_custom_options.proto \
|
||||
java/core/src/test/proto/com/google/protobuf/test_extra_interfaces.proto \
|
||||
java/core/src/test/proto/com/google/protobuf/wrappers_test.proto \
|
||||
java/lite.md \
|
||||
java/lite/BUILD \
|
||||
@ -1412,10 +1411,6 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
|
||||
examples/pubspec.yaml \
|
||||
protobuf.bzl \
|
||||
protobuf_deps.bzl \
|
||||
python/release/wheel/build_wheel_manylinux.sh \
|
||||
python/release/wheel/Dockerfile \
|
||||
python/release/wheel/protobuf_optimized_pip.sh \
|
||||
python/release/wheel/README.md \
|
||||
third_party/six.BUILD \
|
||||
third_party/zlib.BUILD \
|
||||
third_party/wyhash/LICENSE \
|
||||
|
@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'Protobuf-C++'
|
||||
s.version = '3.14.0'
|
||||
s.version = '3.15.6'
|
||||
s.summary = 'Protocol Buffers v3 runtime library for C++.'
|
||||
s.homepage = 'https://github.com/google/protobuf'
|
||||
s.license = '3-Clause BSD License'
|
||||
|
@ -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.14.0'
|
||||
s.version = '3.15.6'
|
||||
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
|
||||
s.homepage = 'https://github.com/protocolbuffers/protobuf'
|
||||
s.license = '3-Clause BSD License'
|
||||
|
21
WORKSPACE
21
WORKSPACE
@ -17,6 +17,15 @@ http_archive(
|
||||
],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "com_github_google_benchmark",
|
||||
sha256 = "2a778d821997df7d8646c9c59b8edb9a573a6e04c534c01892a40aa524a7b68c",
|
||||
strip_prefix = "benchmark-bf585a2789e30585b4e3ce6baf11ef2750b54677",
|
||||
urls = [
|
||||
"https://github.com/google/benchmark/archive/bf585a2789e30585b4e3ce6baf11ef2750b54677.zip",
|
||||
],
|
||||
)
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
load("//:protobuf_deps.bzl", "protobuf_deps")
|
||||
|
||||
@ -29,18 +38,6 @@ bind(
|
||||
actual = "//util/python:python_headers",
|
||||
)
|
||||
|
||||
# TODO(yannic): Remove in 3.14.0.
|
||||
bind(
|
||||
name = "gtest",
|
||||
actual = "@com_google_googletest//:gtest",
|
||||
)
|
||||
|
||||
# TODO(yannic): Remove in 3.14.0.
|
||||
bind(
|
||||
name = "gtest_main",
|
||||
actual = "@com_google_googletest//:gtest_main",
|
||||
)
|
||||
|
||||
jvm_maven_import_external(
|
||||
name = "guava_maven",
|
||||
artifact = "com.google.guava:guava:18.0",
|
||||
|
65
benchmarks/BUILD
Normal file
65
benchmarks/BUILD
Normal file
@ -0,0 +1,65 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
|
||||
load("@rules_java//java:defs.bzl", "java_proto_library")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
|
||||
proto_library(
|
||||
name = "benchmarks_proto",
|
||||
srcs = [
|
||||
"benchmarks.proto",
|
||||
],
|
||||
strip_import_prefix = "/benchmarks",
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "benchmarks_cc_proto",
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"benchmarks_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "benchmarks_java_proto",
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"benchmarks_proto",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "google_size_proto",
|
||||
srcs = [
|
||||
"google_size.proto",
|
||||
],
|
||||
strip_import_prefix = "/benchmarks",
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "google_size_cc_proto",
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"google_size_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "google_size_java_proto",
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"google_size_proto",
|
||||
],
|
||||
)
|
15
benchmarks/cpp/BUILD
Normal file
15
benchmarks/cpp/BUILD
Normal file
@ -0,0 +1,15 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary")
|
||||
|
||||
cc_binary(
|
||||
name = "cpp",
|
||||
srcs = [
|
||||
"cpp_benchmark.cc",
|
||||
],
|
||||
tags = ["benchmark"],
|
||||
deps = [
|
||||
"//:protobuf",
|
||||
"//benchmarks:benchmarks_cc_proto",
|
||||
"//benchmarks/datasets:cc_protos",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
59
benchmarks/datasets/BUILD
Normal file
59
benchmarks/datasets/BUILD
Normal file
@ -0,0 +1,59 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("@rules_java//java:defs.bzl", "java_library")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
|
||||
filegroup(
|
||||
name = "datasets",
|
||||
srcs = [
|
||||
"//benchmarks/datasets/google_message1/proto2:datasets",
|
||||
"//benchmarks/datasets/google_message1/proto3:datasets",
|
||||
"//benchmarks/datasets/google_message2:datasets",
|
||||
"//benchmarks/datasets/google_message3:datasets",
|
||||
"//benchmarks/datasets/google_message4:datasets",
|
||||
],
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "protos",
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//benchmarks/datasets/google_message1/proto2:benchmark_message1_proto2_proto",
|
||||
"//benchmarks/datasets/google_message1/proto3:benchmark_message1_proto3_proto",
|
||||
"//benchmarks/datasets/google_message2:benchmark_message2_proto",
|
||||
"//benchmarks/datasets/google_message3:benchmark_message3_proto",
|
||||
"//benchmarks/datasets/google_message4:benchmark_message4_proto",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "cc_protos",
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//benchmarks/datasets/google_message1/proto2:benchmark_message1_proto2_cc_proto",
|
||||
"//benchmarks/datasets/google_message1/proto3:benchmark_message1_proto3_cc_proto",
|
||||
"//benchmarks/datasets/google_message2:benchmark_message2_cc_proto",
|
||||
"//benchmarks/datasets/google_message3:benchmark_message3_cc_proto",
|
||||
"//benchmarks/datasets/google_message4:benchmark_message4_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_library(
|
||||
name = "java_protos",
|
||||
visibility = [
|
||||
"//benchmarks:__subpackages__",
|
||||
],
|
||||
exports = [
|
||||
"//benchmarks/datasets/google_message1/proto2:benchmark_message1_proto2_java_proto",
|
||||
"//benchmarks/datasets/google_message1/proto3:benchmark_message1_proto3_java_proto",
|
||||
"//benchmarks/datasets/google_message2:benchmark_message2_java_proto",
|
||||
"//benchmarks/datasets/google_message3:benchmark_message3_java_proto",
|
||||
"//benchmarks/datasets/google_message4:benchmark_message4_java_proto",
|
||||
],
|
||||
)
|
44
benchmarks/datasets/google_message1/proto2/BUILD
Normal file
44
benchmarks/datasets/google_message1/proto2/BUILD
Normal file
@ -0,0 +1,44 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
|
||||
load("@rules_java//java:defs.bzl", "java_proto_library")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
|
||||
filegroup(
|
||||
name = "datasets",
|
||||
srcs = [
|
||||
"dataset.google_message1_proto2.pb",
|
||||
],
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "benchmark_message1_proto2_proto",
|
||||
srcs = [
|
||||
"benchmark_message1_proto2.proto",
|
||||
],
|
||||
strip_import_prefix = "/benchmarks",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "benchmark_message1_proto2_cc_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message1_proto2_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "benchmark_message1_proto2_java_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message1_proto2_proto",
|
||||
],
|
||||
)
|
44
benchmarks/datasets/google_message1/proto3/BUILD
Normal file
44
benchmarks/datasets/google_message1/proto3/BUILD
Normal file
@ -0,0 +1,44 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
|
||||
load("@rules_java//java:defs.bzl", "java_proto_library")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
|
||||
filegroup(
|
||||
name = "datasets",
|
||||
srcs = [
|
||||
"dataset.google_message1_proto3.pb",
|
||||
],
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "benchmark_message1_proto3_proto",
|
||||
srcs = [
|
||||
"benchmark_message1_proto3.proto",
|
||||
],
|
||||
strip_import_prefix = "/benchmarks",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "benchmark_message1_proto3_cc_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message1_proto3_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "benchmark_message1_proto3_java_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message1_proto3_proto",
|
||||
],
|
||||
)
|
44
benchmarks/datasets/google_message2/BUILD
Normal file
44
benchmarks/datasets/google_message2/BUILD
Normal file
@ -0,0 +1,44 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
|
||||
load("@rules_java//java:defs.bzl", "java_proto_library")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
|
||||
filegroup(
|
||||
name = "datasets",
|
||||
srcs = [
|
||||
"dataset.google_message2.pb",
|
||||
],
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "benchmark_message2_proto",
|
||||
srcs = [
|
||||
"benchmark_message2.proto",
|
||||
],
|
||||
strip_import_prefix = "/benchmarks",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "benchmark_message2_cc_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message2_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "benchmark_message2_java_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message2_proto",
|
||||
],
|
||||
)
|
50
benchmarks/datasets/google_message3/BUILD
Normal file
50
benchmarks/datasets/google_message3/BUILD
Normal file
@ -0,0 +1,50 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
|
||||
load("@rules_java//java:defs.bzl", "java_proto_library")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
|
||||
filegroup(
|
||||
name = "datasets",
|
||||
srcs = [],
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "benchmark_message3_proto",
|
||||
srcs = [
|
||||
"benchmark_message3.proto",
|
||||
"benchmark_message3_1.proto",
|
||||
"benchmark_message3_2.proto",
|
||||
"benchmark_message3_3.proto",
|
||||
"benchmark_message3_4.proto",
|
||||
"benchmark_message3_5.proto",
|
||||
"benchmark_message3_6.proto",
|
||||
"benchmark_message3_7.proto",
|
||||
"benchmark_message3_8.proto",
|
||||
],
|
||||
strip_import_prefix = "/benchmarks",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "benchmark_message3_cc_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message3_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "benchmark_message3_java_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message3_proto",
|
||||
],
|
||||
)
|
45
benchmarks/datasets/google_message4/BUILD
Normal file
45
benchmarks/datasets/google_message4/BUILD
Normal file
@ -0,0 +1,45 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
|
||||
load("@rules_java//java:defs.bzl", "java_proto_library")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
|
||||
filegroup(
|
||||
name = "datasets",
|
||||
srcs = [],
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "benchmark_message4_proto",
|
||||
srcs = [
|
||||
"benchmark_message4.proto",
|
||||
"benchmark_message4_1.proto",
|
||||
"benchmark_message4_2.proto",
|
||||
"benchmark_message4_3.proto",
|
||||
],
|
||||
strip_import_prefix = "/benchmarks",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "benchmark_message4_cc_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message4_proto",
|
||||
],
|
||||
)
|
||||
|
||||
java_proto_library(
|
||||
name = "benchmark_message4_java_proto",
|
||||
visibility = [
|
||||
"//benchmarks/datasets:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"benchmark_message4_proto",
|
||||
],
|
||||
)
|
@ -45,6 +45,7 @@ option(protobuf_BUILD_CONFORMANCE "Build conformance tests" OFF)
|
||||
option(protobuf_BUILD_EXAMPLES "Build examples" OFF)
|
||||
option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" ON)
|
||||
option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF)
|
||||
option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries" OFF)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON)
|
||||
else (BUILD_SHARED_LIBS)
|
||||
@ -117,6 +118,10 @@ endif()
|
||||
|
||||
add_definitions(-DGOOGLE_PROTOBUF_CMAKE_BUILD)
|
||||
|
||||
if (protobuf_DISABLE_RTTI)
|
||||
add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI=1)
|
||||
endif()
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
add_definitions(-DHAVE_PTHREAD)
|
||||
|
@ -30,7 +30,9 @@ endforeach()
|
||||
|
||||
if (protobuf_BUILD_PROTOC_BINARIES)
|
||||
install(TARGETS protoc EXPORT protobuf-targets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
COMPONENT protoc)
|
||||
if (UNIX AND NOT APPLE)
|
||||
set_property(TARGET protoc
|
||||
PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
|
||||
|
@ -15,7 +15,7 @@ function(protobuf_generate)
|
||||
if(COMMAND target_sources)
|
||||
list(APPEND _singleargs TARGET)
|
||||
endif()
|
||||
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS)
|
||||
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS)
|
||||
|
||||
cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}")
|
||||
|
||||
@ -130,9 +130,9 @@ function(protobuf_generate)
|
||||
add_custom_command(
|
||||
OUTPUT ${_generated_srcs}
|
||||
COMMAND protobuf::protoc
|
||||
ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file}
|
||||
ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file}
|
||||
DEPENDS ${_abs_file} protobuf::protoc
|
||||
COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}"
|
||||
COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}. Custom options: ${protobuf_generate_PROTOC_OPTIONS}"
|
||||
VERBATIM )
|
||||
endforeach()
|
||||
|
||||
|
15
configure.ac
15
configure.ac
@ -17,7 +17,7 @@ AC_PREREQ(2.59)
|
||||
# In the SVN trunk, the version should always be the next anticipated release
|
||||
# version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed
|
||||
# the size of one file name in the dist tarfile over the 99-char limit.)
|
||||
AC_INIT([Protocol Buffers],[3.14.0],[protobuf@googlegroups.com],[protobuf])
|
||||
AC_INIT([Protocol Buffers],[3.15.6],[protobuf@googlegroups.com],[protobuf])
|
||||
|
||||
AM_MAINTAINER_MODE([enable])
|
||||
|
||||
@ -223,6 +223,19 @@ case "$target_os" in
|
||||
esac
|
||||
AM_CONDITIONAL([OBJC_CONFORMANCE_TEST], [test $OBJC_CONFORMANCE_TEST = 1])
|
||||
|
||||
AC_MSG_CHECKING(whether -llog is needed)
|
||||
ANDROID_TEST=no
|
||||
case "$target_os" in
|
||||
*android*)
|
||||
ANDROID_TEST=yes
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT($ANDROID_TEST)
|
||||
if test "x$ANDROID_TEST" = xyes; then
|
||||
LIBLOG_LIBS="-llog"
|
||||
fi
|
||||
AC_SUBST([LIBLOG_LIBS])
|
||||
|
||||
# HACK: Make gmock's configure script pick up our copy of CFLAGS and CXXFLAGS,
|
||||
# since the flags added by ACX_CHECK_SUNCC must be used when compiling gmock
|
||||
# too.
|
||||
|
@ -300,7 +300,7 @@ const FieldDescriptor* GetFieldForOneofType(FieldDescriptor::Type type,
|
||||
}
|
||||
|
||||
string UpperCase(string str) {
|
||||
for (int i = 0; i < str.size(); i++) {
|
||||
for (size_t i = 0; i < str.size(); i++) {
|
||||
str[i] = toupper(str[i]);
|
||||
}
|
||||
return str;
|
||||
|
@ -55,6 +55,7 @@ using google::protobuf::util::JsonToBinaryString;
|
||||
using google::protobuf::util::NewTypeResolverForDescriptorPool;
|
||||
using google::protobuf::util::TypeResolver;
|
||||
using protobuf_test_messages::proto3::TestAllTypesProto3;
|
||||
using protobuf_test_messages::proto2::TestAllTypesProto2;
|
||||
using std::string;
|
||||
|
||||
static const char kTypeUrlPrefix[] = "type.googleapis.com";
|
||||
@ -102,6 +103,8 @@ void CheckedWrite(int fd, const void *buf, size_t len) {
|
||||
|
||||
void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
|
||||
Message *test_message;
|
||||
google::protobuf::LinkMessageReflection<TestAllTypesProto2>();
|
||||
google::protobuf::LinkMessageReflection<TestAllTypesProto3>();
|
||||
const Descriptor *descriptor = DescriptorPool::generated_pool()->FindMessageTypeByName(
|
||||
request.message_type());
|
||||
if (!descriptor) {
|
||||
@ -131,7 +134,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
|
||||
&proto_binary, options);
|
||||
if (!status.ok()) {
|
||||
response->set_parse_error(string("Parse error: ") +
|
||||
std::string(status.error_message()));
|
||||
std::string(status.message()));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -186,7 +189,7 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
|
||||
if (!status.ok()) {
|
||||
response->set_serialize_error(
|
||||
string("Failed to serialize JSON output: ") +
|
||||
std::string(status.error_message()));
|
||||
std::string(status.message()));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -297,7 +297,7 @@ void ForkPipeRunner::SpawnTestProgram() {
|
||||
|
||||
std::vector<const char *> argv;
|
||||
argv.push_back(executable.get());
|
||||
for (int i = 0; i < executable_args_.size(); ++i) {
|
||||
for (size_t i = 0; i < executable_args_.size(); ++i) {
|
||||
argv.push_back(executable_args_[i].c_str());
|
||||
}
|
||||
argv.push_back(nullptr);
|
||||
@ -307,7 +307,7 @@ void ForkPipeRunner::SpawnTestProgram() {
|
||||
}
|
||||
|
||||
void ForkPipeRunner::CheckedWrite(int fd, const void *buf, size_t len) {
|
||||
if (write(fd, buf, len) != len) {
|
||||
if (static_cast<size_t>(write(fd, buf, len)) != len) {
|
||||
GOOGLE_LOG(FATAL) << current_test_name_
|
||||
<< ": error writing to test program: " << strerror(errno);
|
||||
}
|
||||
|
@ -451,6 +451,27 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() {
|
||||
}
|
||||
)",
|
||||
prototype);
|
||||
|
||||
prototype.Clear();
|
||||
ConformanceRequestSetting setting_map(
|
||||
REQUIRED, conformance::TEXT_FORMAT, conformance::PROTOBUF,
|
||||
conformance::TEXT_FORMAT_TEST, prototype, "DuplicateMapKey", R"(
|
||||
map_string_nested_message {
|
||||
key: "duplicate"
|
||||
value: { a: 123 }
|
||||
}
|
||||
map_string_nested_message {
|
||||
key: "duplicate"
|
||||
value: { corecursive: {} }
|
||||
}
|
||||
)");
|
||||
// The last-specified value will be retained in a parsed map
|
||||
RunValidInputTest(setting_map, R"(
|
||||
map_string_nested_message {
|
||||
key: "duplicate"
|
||||
value: { corecursive: {} }
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
} // namespace protobuf
|
||||
|
@ -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.14.0</version>
|
||||
<version>3.15.6</version>
|
||||
<authors>Google Inc.</authors>
|
||||
<owners>protobuf-packages</owners>
|
||||
<licenseUrl>https://github.com/protocolbuffers/protobuf/blob/master/LICENSE</licenseUrl>
|
||||
|
@ -17,4 +17,4 @@ Invoke-WebRequest -Uri $InstallScriptUrl -OutFile $InstallScriptPath
|
||||
# The SDK versions to install should be kept in sync with versions
|
||||
# installed by kokoro/linux/dockerfile/test/csharp/Dockerfile
|
||||
&$InstallScriptPath -Version 2.1.802
|
||||
&$InstallScriptPath -Version 3.1.301
|
||||
&$InstallScriptPath -Version 5.0.102
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<IsPackable>False</IsPackable>
|
||||
|
@ -25,49 +25,54 @@ namespace ProtobufUnittest {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"Ci5nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX29wdGlvbmFsLnBy",
|
||||
"b3RvEhFwcm90b2J1Zl91bml0dGVzdCKxCgoSVGVzdFByb3RvM09wdGlvbmFs",
|
||||
"EhsKDm9wdGlvbmFsX2ludDMyGAEgASgFSACIAQESGwoOb3B0aW9uYWxfaW50",
|
||||
"NjQYAiABKANIAYgBARIcCg9vcHRpb25hbF91aW50MzIYAyABKA1IAogBARIc",
|
||||
"Cg9vcHRpb25hbF91aW50NjQYBCABKARIA4gBARIcCg9vcHRpb25hbF9zaW50",
|
||||
"MzIYBSABKBFIBIgBARIcCg9vcHRpb25hbF9zaW50NjQYBiABKBJIBYgBARId",
|
||||
"ChBvcHRpb25hbF9maXhlZDMyGAcgASgHSAaIAQESHQoQb3B0aW9uYWxfZml4",
|
||||
"ZWQ2NBgIIAEoBkgHiAEBEh4KEW9wdGlvbmFsX3NmaXhlZDMyGAkgASgPSAiI",
|
||||
"AQESHgoRb3B0aW9uYWxfc2ZpeGVkNjQYCiABKBBICYgBARIbCg5vcHRpb25h",
|
||||
"bF9mbG9hdBgLIAEoAkgKiAEBEhwKD29wdGlvbmFsX2RvdWJsZRgMIAEoAUgL",
|
||||
"iAEBEhoKDW9wdGlvbmFsX2Jvb2wYDSABKAhIDIgBARIcCg9vcHRpb25hbF9z",
|
||||
"dHJpbmcYDiABKAlIDYgBARIbCg5vcHRpb25hbF9ieXRlcxgPIAEoDEgOiAEB",
|
||||
"Eh4KDW9wdGlvbmFsX2NvcmQYECABKAlCAggBSA+IAQESWQoXb3B0aW9uYWxf",
|
||||
"bmVzdGVkX21lc3NhZ2UYEiABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0",
|
||||
"UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUgQiAEBElkKE2xhenlfbmVz",
|
||||
"dGVkX21lc3NhZ2UYEyABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJv",
|
||||
"dG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUICKAFIEYgBARJTChRvcHRpb25h",
|
||||
"bF9uZXN0ZWRfZW51bRgVIAEoDjIwLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQ",
|
||||
"cm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtSBKIAQESFgoOc2luZ3VsYXJfaW50",
|
||||
"MzIYFiABKAUSFgoOc2luZ3VsYXJfaW50NjQYFyABKAMaJwoNTmVzdGVkTWVz",
|
||||
"c2FnZRIPCgJiYhgBIAEoBUgAiAEBQgUKA19iYiJKCgpOZXN0ZWRFbnVtEg8K",
|
||||
"C1VOU1BFQ0lGSUVEEAASBwoDRk9PEAESBwoDQkFSEAISBwoDQkFaEAMSEAoD",
|
||||
"TkVHEP///////////wFCEQoPX29wdGlvbmFsX2ludDMyQhEKD19vcHRpb25h",
|
||||
"bF9pbnQ2NEISChBfb3B0aW9uYWxfdWludDMyQhIKEF9vcHRpb25hbF91aW50",
|
||||
"NjRCEgoQX29wdGlvbmFsX3NpbnQzMkISChBfb3B0aW9uYWxfc2ludDY0QhMK",
|
||||
"EV9vcHRpb25hbF9maXhlZDMyQhMKEV9vcHRpb25hbF9maXhlZDY0QhQKEl9v",
|
||||
"cHRpb25hbF9zZml4ZWQzMkIUChJfb3B0aW9uYWxfc2ZpeGVkNjRCEQoPX29w",
|
||||
"dGlvbmFsX2Zsb2F0QhIKEF9vcHRpb25hbF9kb3VibGVCEAoOX29wdGlvbmFs",
|
||||
"X2Jvb2xCEgoQX29wdGlvbmFsX3N0cmluZ0IRCg9fb3B0aW9uYWxfYnl0ZXNC",
|
||||
"EAoOX29wdGlvbmFsX2NvcmRCGgoYX29wdGlvbmFsX25lc3RlZF9tZXNzYWdl",
|
||||
"QhYKFF9sYXp5X25lc3RlZF9tZXNzYWdlQhcKFV9vcHRpb25hbF9uZXN0ZWRf",
|
||||
"ZW51bSKJAgoZVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZRJSCg5uZXN0ZWRf",
|
||||
"bWVzc2FnZRgBIAEoCzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNP",
|
||||
"cHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZRJgChdvcHRpb25hbF9uZXN0",
|
||||
"ZWRfbWVzc2FnZRgCIAEoCzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90",
|
||||
"bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZUgAiAEBGhoKDU5lc3Rl",
|
||||
"ZE1lc3NhZ2USCQoBcxgBIAEoCUIaChhfb3B0aW9uYWxfbmVzdGVkX21lc3Nh",
|
||||
"Z2VCJQohY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvUAFiBnBy",
|
||||
"b3RvMw=="));
|
||||
"b3RvEhFwcm90b2J1Zl91bml0dGVzdBogZ29vZ2xlL3Byb3RvYnVmL2Rlc2Ny",
|
||||
"aXB0b3IucHJvdG8isQoKElRlc3RQcm90bzNPcHRpb25hbBIbCg5vcHRpb25h",
|
||||
"bF9pbnQzMhgBIAEoBUgAiAEBEhsKDm9wdGlvbmFsX2ludDY0GAIgASgDSAGI",
|
||||
"AQESHAoPb3B0aW9uYWxfdWludDMyGAMgASgNSAKIAQESHAoPb3B0aW9uYWxf",
|
||||
"dWludDY0GAQgASgESAOIAQESHAoPb3B0aW9uYWxfc2ludDMyGAUgASgRSASI",
|
||||
"AQESHAoPb3B0aW9uYWxfc2ludDY0GAYgASgSSAWIAQESHQoQb3B0aW9uYWxf",
|
||||
"Zml4ZWQzMhgHIAEoB0gGiAEBEh0KEG9wdGlvbmFsX2ZpeGVkNjQYCCABKAZI",
|
||||
"B4gBARIeChFvcHRpb25hbF9zZml4ZWQzMhgJIAEoD0gIiAEBEh4KEW9wdGlv",
|
||||
"bmFsX3NmaXhlZDY0GAogASgQSAmIAQESGwoOb3B0aW9uYWxfZmxvYXQYCyAB",
|
||||
"KAJICogBARIcCg9vcHRpb25hbF9kb3VibGUYDCABKAFIC4gBARIaCg1vcHRp",
|
||||
"b25hbF9ib29sGA0gASgISAyIAQESHAoPb3B0aW9uYWxfc3RyaW5nGA4gASgJ",
|
||||
"SA2IAQESGwoOb3B0aW9uYWxfYnl0ZXMYDyABKAxIDogBARIeCg1vcHRpb25h",
|
||||
"bF9jb3JkGBAgASgJQgIIAUgPiAEBElkKF29wdGlvbmFsX25lc3RlZF9tZXNz",
|
||||
"YWdlGBIgASgLMjMucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlv",
|
||||
"bmFsLk5lc3RlZE1lc3NhZ2VIEIgBARJZChNsYXp5X25lc3RlZF9tZXNzYWdl",
|
||||
"GBMgASgLMjMucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFs",
|
||||
"Lk5lc3RlZE1lc3NhZ2VCAigBSBGIAQESUwoUb3B0aW9uYWxfbmVzdGVkX2Vu",
|
||||
"dW0YFSABKA4yMC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9u",
|
||||
"YWwuTmVzdGVkRW51bUgSiAEBEhYKDnNpbmd1bGFyX2ludDMyGBYgASgFEhYK",
|
||||
"DnNpbmd1bGFyX2ludDY0GBcgASgDGicKDU5lc3RlZE1lc3NhZ2USDwoCYmIY",
|
||||
"ASABKAVIAIgBAUIFCgNfYmIiSgoKTmVzdGVkRW51bRIPCgtVTlNQRUNJRklF",
|
||||
"RBAAEgcKA0ZPTxABEgcKA0JBUhACEgcKA0JBWhADEhAKA05FRxD/////////",
|
||||
"//8BQhEKD19vcHRpb25hbF9pbnQzMkIRCg9fb3B0aW9uYWxfaW50NjRCEgoQ",
|
||||
"X29wdGlvbmFsX3VpbnQzMkISChBfb3B0aW9uYWxfdWludDY0QhIKEF9vcHRp",
|
||||
"b25hbF9zaW50MzJCEgoQX29wdGlvbmFsX3NpbnQ2NEITChFfb3B0aW9uYWxf",
|
||||
"Zml4ZWQzMkITChFfb3B0aW9uYWxfZml4ZWQ2NEIUChJfb3B0aW9uYWxfc2Zp",
|
||||
"eGVkMzJCFAoSX29wdGlvbmFsX3NmaXhlZDY0QhEKD19vcHRpb25hbF9mbG9h",
|
||||
"dEISChBfb3B0aW9uYWxfZG91YmxlQhAKDl9vcHRpb25hbF9ib29sQhIKEF9v",
|
||||
"cHRpb25hbF9zdHJpbmdCEQoPX29wdGlvbmFsX2J5dGVzQhAKDl9vcHRpb25h",
|
||||
"bF9jb3JkQhoKGF9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZUIWChRfbGF6eV9u",
|
||||
"ZXN0ZWRfbWVzc2FnZUIXChVfb3B0aW9uYWxfbmVzdGVkX2VudW0iiQIKGVRl",
|
||||
"c3RQcm90bzNPcHRpb25hbE1lc3NhZ2USUgoObmVzdGVkX21lc3NhZ2UYASAB",
|
||||
"KAsyOi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNz",
|
||||
"YWdlLk5lc3RlZE1lc3NhZ2USYAoXb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UY",
|
||||
"AiABKAsyOi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxN",
|
||||
"ZXNzYWdlLk5lc3RlZE1lc3NhZ2VIAIgBARoaCg1OZXN0ZWRNZXNzYWdlEgkK",
|
||||
"AXMYASABKAlCGgoYX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlIqkBChhQcm90",
|
||||
"bzNPcHRpb25hbEV4dGVuc2lvbnMyPAoPZXh0X25vX29wdGlvbmFsEh8uZ29v",
|
||||
"Z2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIjN2akBIAEoBTJBChFleHRf",
|
||||
"d2l0aF9vcHRpb25hbBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9u",
|
||||
"cxiJzdmpASABKAWIAQE6DMDozM0KCMjozM0KEEIlCiFjb20uZ29vZ2xlLnBy",
|
||||
"b3RvYnVmLnRlc3RpbmcucHJvdG9QAWIGcHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor, },
|
||||
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional), global::ProtobufUnittest.TestProto3Optional.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum", "SingularInt32", "SingularInt64" }, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum" }, new[]{ typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage), global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage.Parser, new[]{ "Bb" }, new[]{ "Bb" }, null, null, null)}),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Parser, new[]{ "NestedMessage", "OptionalNestedMessage" }, new[]{ "OptionalNestedMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage.Parser, new[]{ "S" }, null, null, null, null)})
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Parser, new[]{ "NestedMessage", "OptionalNestedMessage" }, new[]{ "OptionalNestedMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage.Parser, new[]{ "S" }, null, null, null, null)}),
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.Proto3OptionalExtensions), global::ProtobufUnittest.Proto3OptionalExtensions.Parser, null, null, null, new pb::Extension[] { global::ProtobufUnittest.Proto3OptionalExtensions.Extensions.ExtNoOptional, global::ProtobufUnittest.Proto3OptionalExtensions.Extensions.ExtWithOptional }, null)
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
@ -1789,6 +1794,153 @@ namespace ProtobufUnittest {
|
||||
|
||||
}
|
||||
|
||||
public sealed partial class Proto3OptionalExtensions : pb::IMessage<Proto3OptionalExtensions>
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
, pb::IBufferMessage
|
||||
#endif
|
||||
{
|
||||
private static readonly pb::MessageParser<Proto3OptionalExtensions> _parser = new pb::MessageParser<Proto3OptionalExtensions>(() => new Proto3OptionalExtensions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<Proto3OptionalExtensions> Parser { get { return _parser; } }
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::ProtobufUnittest.UnittestProto3OptionalReflection.Descriptor.MessageTypes[2]; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public Proto3OptionalExtensions() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public Proto3OptionalExtensions(Proto3OptionalExtensions other) : this() {
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public Proto3OptionalExtensions Clone() {
|
||||
return new Proto3OptionalExtensions(this);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as Proto3OptionalExtensions);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public bool Equals(Proto3OptionalExtensions other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
output.WriteRawMessage(this);
|
||||
#else
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(ref output);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void MergeFrom(Proto3OptionalExtensions other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void MergeFrom(pb::CodedInputStream input) {
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
input.ReadRawMessage(this);
|
||||
#else
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
switch(tag) {
|
||||
default:
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
switch(tag) {
|
||||
default:
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#region Extensions
|
||||
/// <summary>Container for extensions for other messages declared in the Proto3OptionalExtensions message type.</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static partial class Extensions {
|
||||
public static readonly pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, int> ExtNoOptional =
|
||||
new pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, int>(355886728, pb::FieldCodec.ForInt32(2847093824, 0));
|
||||
public static readonly pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, int> ExtWithOptional =
|
||||
new pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, int>(355886729, pb::FieldCodec.ForInt32(2847093832, 0));
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace Google.Protobuf.Buffers
|
||||
/// ArrayBufferWriter is originally from corefx, and has been contributed to Protobuf
|
||||
/// https://github.com/dotnet/runtime/blob/071da4c41aa808c949a773b92dca6f88de9d11f3/src/libraries/Common/src/System/Buffers/ArrayBufferWriter.cs
|
||||
/// </summary>
|
||||
internal sealed class ArrayBufferWriter<T> : IBufferWriter<T>
|
||||
internal sealed class TestArrayBufferWriter<T> : IBufferWriter<T>
|
||||
{
|
||||
private T[] _buffer;
|
||||
private int _index;
|
||||
@ -50,10 +50,10 @@ namespace Google.Protobuf.Buffers
|
||||
private const int DefaultInitialBufferSize = 256;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of an <see cref="ArrayBufferWriter{T}"/>, in which data can be written to,
|
||||
/// Creates an instance of an <see cref="TestArrayBufferWriter{T}"/>, in which data can be written to,
|
||||
/// with the default initial capacity.
|
||||
/// </summary>
|
||||
public ArrayBufferWriter()
|
||||
public TestArrayBufferWriter()
|
||||
{
|
||||
_buffer = new T[0];
|
||||
_index = 0;
|
||||
@ -66,14 +66,14 @@ namespace Google.Protobuf.Buffers
|
||||
public int? MaxGrowBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of an <see cref="ArrayBufferWriter{T}"/>, in which data can be written to,
|
||||
/// Creates an instance of an <see cref="TestArrayBufferWriter{T}"/>, in which data can be written to,
|
||||
/// with an initial capacity specified.
|
||||
/// </summary>
|
||||
/// <param name="initialCapacity">The minimum capacity with which to initialize the underlying buffer.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown when <paramref name="initialCapacity"/> is not positive (i.e. less than or equal to 0).
|
||||
/// </exception>
|
||||
public ArrayBufferWriter(int initialCapacity)
|
||||
public TestArrayBufferWriter(int initialCapacity)
|
||||
{
|
||||
if (initialCapacity <= 0)
|
||||
throw new ArgumentException(nameof(initialCapacity));
|
||||
@ -111,7 +111,7 @@ namespace Google.Protobuf.Buffers
|
||||
/// Clears the data written to the underlying buffer.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You must clear the <see cref="ArrayBufferWriter{T}"/> before trying to re-use it.
|
||||
/// You must clear the <see cref="TestArrayBufferWriter{T}"/> before trying to re-use it.
|
||||
/// </remarks>
|
||||
public void Clear()
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ using System.IO;
|
||||
using Google.Protobuf.TestProtos;
|
||||
using Google.Protobuf.Buffers;
|
||||
using NUnit.Framework;
|
||||
using System.Text;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@ -57,7 +58,7 @@ namespace Google.Protobuf
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
// IBufferWriter
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteUInt32((uint) value);
|
||||
ctx.Flush();
|
||||
@ -76,7 +77,7 @@ namespace Google.Protobuf
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
// IBufferWriter
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteUInt64(value);
|
||||
ctx.Flush();
|
||||
@ -99,7 +100,7 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = bufferSize;
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteUInt32((uint) value);
|
||||
@ -114,7 +115,7 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = bufferSize;
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteUInt64(value);
|
||||
@ -173,7 +174,7 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteFixed32(value);
|
||||
ctx.Flush();
|
||||
@ -189,7 +190,7 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = bufferSize;
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteFixed32(value);
|
||||
@ -211,7 +212,7 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteFixed64(value);
|
||||
ctx.Flush();
|
||||
@ -227,7 +228,7 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(data, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = blockSize;
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteFixed64(value);
|
||||
@ -269,7 +270,7 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
Assert.AreEqual(rawBytes, rawOutput.ToArray());
|
||||
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
bufferWriter.MaxGrowBy = blockSize;
|
||||
message.WriteTo(bufferWriter);
|
||||
Assert.AreEqual(rawBytes, bufferWriter.WrittenSpan.ToArray());
|
||||
@ -291,7 +292,7 @@ namespace Google.Protobuf
|
||||
output.Flush();
|
||||
byte[] expectedBytes2 = expectedOutput.ToArray();
|
||||
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
WriteContext.Initialize(bufferWriter, out WriteContext ctx);
|
||||
ctx.WriteMessage(message);
|
||||
ctx.Flush();
|
||||
@ -516,5 +517,67 @@ namespace Google.Protobuf
|
||||
var stream = new CodedOutputStream(new byte[10]);
|
||||
stream.Dispose();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteString_AsciiSmall_MaxUtf8SizeExceedsBuffer()
|
||||
{
|
||||
var buffer = new byte[5];
|
||||
var output = new CodedOutputStream(buffer);
|
||||
output.WriteString("ABC");
|
||||
|
||||
output.Flush();
|
||||
|
||||
// Verify written content
|
||||
var input = new CodedInputStream(buffer);
|
||||
Assert.AreEqual("ABC", input.ReadString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteStringsOfDifferentSizes_Ascii()
|
||||
{
|
||||
for (int i = 1; i <= 1024; i++)
|
||||
{
|
||||
var buffer = new byte[4096];
|
||||
var output = new CodedOutputStream(buffer);
|
||||
var sb = new StringBuilder();
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
sb.Append((j % 10).ToString()); // incrementing numbers, repeating
|
||||
}
|
||||
var s = sb.ToString();
|
||||
output.WriteString(s);
|
||||
|
||||
output.Flush();
|
||||
|
||||
// Verify written content
|
||||
var input = new CodedInputStream(buffer);
|
||||
Assert.AreEqual(s, input.ReadString());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteStringsOfDifferentSizes_Unicode()
|
||||
{
|
||||
for (int i = 1; i <= 1024; i++)
|
||||
{
|
||||
var buffer = new byte[4096];
|
||||
var output = new CodedOutputStream(buffer);
|
||||
var sb = new StringBuilder();
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
char c = (char)((j % 10) + 10112);
|
||||
sb.Append(c.ToString()); // incrementing unicode numbers, repeating
|
||||
}
|
||||
var s = sb.ToString();
|
||||
output.WriteString(s);
|
||||
|
||||
output.Flush();
|
||||
|
||||
// Verify written content
|
||||
var input = new CodedInputStream(buffer);
|
||||
|
||||
Assert.AreEqual(s, input.ReadString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -611,6 +611,32 @@ namespace Google.Protobuf.Collections
|
||||
Assert.IsTrue(input.IsAtEnd);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddEntriesFrom_CodedInputStream_MissingKey()
|
||||
{
|
||||
// map will have string key and string value
|
||||
var keyTag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
|
||||
var valueTag = WireFormat.MakeTag(2, WireFormat.WireType.LengthDelimited);
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
var output = new CodedOutputStream(memoryStream);
|
||||
output.WriteLength(11); // total of valueTag + value
|
||||
output.WriteTag(valueTag);
|
||||
output.WriteString("the_value");
|
||||
output.Flush();
|
||||
|
||||
Console.WriteLine(BitConverter.ToString(memoryStream.ToArray()));
|
||||
|
||||
var field = new MapField<string, string>();
|
||||
var mapCodec = new MapField<string, string>.Codec(FieldCodec.ForString(keyTag, ""), FieldCodec.ForString(valueTag, ""), 10);
|
||||
var input = new CodedInputStream(memoryStream.ToArray());
|
||||
|
||||
field.AddEntriesFrom(input, mapCodec);
|
||||
CollectionAssert.AreEquivalent(new[] { "" }, field.Keys);
|
||||
CollectionAssert.AreEquivalent(new[] { "the_value" }, field.Values);
|
||||
Assert.IsTrue(input.IsAtEnd);
|
||||
}
|
||||
|
||||
#if !NET35
|
||||
[Test]
|
||||
public void IDictionaryKeys_Equals_IReadOnlyDictionaryKeys()
|
||||
|
@ -116,7 +116,22 @@ namespace Google.Protobuf
|
||||
var other = message.Clone();
|
||||
|
||||
Assert.AreEqual(message, other);
|
||||
Assert.AreEqual(message.CalculateSize(), message.CalculateSize());
|
||||
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDefaultValueRoundTrip()
|
||||
{
|
||||
var message = new TestAllExtensions();
|
||||
message.SetExtension(OptionalBoolExtension, false);
|
||||
Assert.IsFalse(message.GetExtension(OptionalBoolExtension));
|
||||
Assert.IsTrue(message.HasExtension(OptionalBoolExtension));
|
||||
|
||||
var bytes = message.ToByteArray();
|
||||
var registry = new ExtensionRegistry { OptionalBoolExtension };
|
||||
var parsed = TestAllExtensions.Parser.WithExtensionRegistry(registry).ParseFrom(bytes);
|
||||
Assert.IsFalse(parsed.GetExtension(OptionalBoolExtension));
|
||||
Assert.IsTrue(parsed.HasExtension(OptionalBoolExtension));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net451;netcoreapp2.1</TargetFrameworks>
|
||||
<TargetFrameworks>net451;netcoreapp2.1;net50</TargetFrameworks>
|
||||
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<IsPackable>False</IsPackable>
|
||||
|
@ -551,9 +551,13 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
[Test]
|
||||
// Skip these test cases in .NET 5 because floating point parsing supports bigger values.
|
||||
// These big values won't throw an error in the test.
|
||||
#if !NET5_0
|
||||
[TestCase("1.7977e308")]
|
||||
[TestCase("-1.7977e308")]
|
||||
[TestCase("1e309")]
|
||||
#endif
|
||||
[TestCase("1,0")]
|
||||
[TestCase("1.0.0")]
|
||||
[TestCase("+1")]
|
||||
|
@ -199,8 +199,12 @@ namespace Google.Protobuf
|
||||
[TestCase("1e-")]
|
||||
[TestCase("--")]
|
||||
[TestCase("--1")]
|
||||
// Skip these test cases in .NET 5 because floating point parsing supports bigger values.
|
||||
// These big values won't throw an error in the test.
|
||||
#if !NET5_0
|
||||
[TestCase("-1.7977e308")]
|
||||
[TestCase("1.7977e308")]
|
||||
#endif
|
||||
public void InvalidNumberValue(string json)
|
||||
{
|
||||
AssertThrowsAfter(json);
|
||||
|
@ -141,7 +141,7 @@ namespace Google.Protobuf
|
||||
};
|
||||
var exception = Assert.Throws<InvalidProtocolBufferException>(() =>
|
||||
{
|
||||
WriteContext.Initialize(new ArrayBufferWriter<byte>(), out WriteContext writeCtx);
|
||||
WriteContext.Initialize(new TestArrayBufferWriter<byte>(), out WriteContext writeCtx);
|
||||
((IBufferMessage)message).InternalWriteTo(ref writeCtx);
|
||||
});
|
||||
Assert.AreEqual($"Message {typeof(LegacyGeneratedCodeMessageA).Name} doesn't provide the generated method that enables WriteContext-based serialization. You might need to regenerate the generated protobuf code.", exception.Message);
|
||||
|
@ -83,7 +83,7 @@ namespace Google.Protobuf
|
||||
var bytes = message.ToByteArray();
|
||||
|
||||
// also serialize using IBufferWriter and check it leads to the same data
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
message.WriteTo(bufferWriter);
|
||||
Assert.AreEqual(bytes, bufferWriter.WrittenSpan.ToArray(), "Both serialization approaches need to result in the same data.");
|
||||
|
||||
@ -112,7 +112,7 @@ namespace Google.Protobuf
|
||||
Assert.AreEqual(message.CalculateSize(), bytes.Length);
|
||||
|
||||
// serialize using IBufferWriter and check it leads to the same output
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
var bufferWriter = new TestArrayBufferWriter<byte>();
|
||||
message.WriteTo(bufferWriter);
|
||||
Assert.AreEqual(bytes, bufferWriter.WrittenSpan.ToArray());
|
||||
|
||||
@ -124,7 +124,7 @@ namespace Google.Protobuf
|
||||
// test for different IBufferWriter.GetSpan() segment sizes
|
||||
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
|
||||
{
|
||||
var segmentedBufferWriter = new ArrayBufferWriter<byte>();
|
||||
var segmentedBufferWriter = new TestArrayBufferWriter<byte>();
|
||||
segmentedBufferWriter.MaxGrowBy = blockSize;
|
||||
message.WriteTo(segmentedBufferWriter);
|
||||
Assert.AreEqual(bytes, segmentedBufferWriter.WrittenSpan.ToArray());
|
||||
|
@ -35,7 +35,9 @@ using NUnit.Framework;
|
||||
using ProtobufUnittest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnitTest.Issues.TestProtos;
|
||||
|
||||
namespace Google.Protobuf.Reflection
|
||||
{
|
||||
@ -70,6 +72,24 @@ namespace Google.Protobuf.Reflection
|
||||
TestFileDescriptor(converted[2], converted[1], converted[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FileDescriptor_BuildFromByteStrings_WithExtensionRegistry()
|
||||
{
|
||||
var extension = UnittestCustomOptionsProto3Extensions.MessageOpt1;
|
||||
|
||||
var byteStrings = new[]
|
||||
{
|
||||
DescriptorReflection.Descriptor.Proto.ToByteString(),
|
||||
UnittestCustomOptionsProto3Reflection.Descriptor.Proto.ToByteString()
|
||||
};
|
||||
var registry = new ExtensionRegistry { extension };
|
||||
|
||||
var descriptor = FileDescriptor.BuildFromByteStrings(byteStrings, registry).Last();
|
||||
var message = descriptor.MessageTypes.Single(t => t.Name == nameof(TestMessageWithCustomOptions));
|
||||
var extensionValue = message.GetOptions().GetExtension(extension);
|
||||
Assert.AreEqual(-56, extensionValue);
|
||||
}
|
||||
|
||||
private void TestFileDescriptor(FileDescriptor file, FileDescriptor importedFile, FileDescriptor importedPublicFile)
|
||||
{
|
||||
Assert.AreEqual("unittest_proto3.proto", file.Name);
|
||||
|
Binary file not shown.
@ -448,12 +448,10 @@ namespace Google.Protobuf.Collections
|
||||
[SecuritySafeCritical]
|
||||
public void AddEntriesFrom(ref ParseContext ctx, Codec codec)
|
||||
{
|
||||
var adapter = new Codec.MessageAdapter(codec);
|
||||
do
|
||||
{
|
||||
adapter.Reset();
|
||||
ctx.ReadMessage(adapter);
|
||||
this[adapter.Key] = adapter.Value;
|
||||
KeyValuePair<TKey, TValue> entry = ParsingPrimitivesMessages.ReadMapEntry(ref ctx, codec);
|
||||
this[entry.Key] = entry.Value;
|
||||
} while (ParsingPrimitives.MaybeConsumeTag(ref ctx.buffer, ref ctx.state, codec.MapTag));
|
||||
}
|
||||
|
||||
@ -485,13 +483,13 @@ namespace Google.Protobuf.Collections
|
||||
[SecuritySafeCritical]
|
||||
public void WriteTo(ref WriteContext ctx, Codec codec)
|
||||
{
|
||||
var message = new Codec.MessageAdapter(codec);
|
||||
foreach (var entry in list)
|
||||
{
|
||||
message.Key = entry.Key;
|
||||
message.Value = entry.Value;
|
||||
ctx.WriteTag(codec.MapTag);
|
||||
ctx.WriteMessage(message);
|
||||
|
||||
WritingPrimitives.WriteLength(ref ctx.buffer, ref ctx.state, CalculateEntrySize(codec, entry));
|
||||
codec.KeyCodec.WriteTagAndValue(ref ctx, entry.Key);
|
||||
codec.ValueCodec.WriteTagAndValue(ref ctx, entry.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -506,18 +504,22 @@ namespace Google.Protobuf.Collections
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
var message = new Codec.MessageAdapter(codec);
|
||||
int size = 0;
|
||||
foreach (var entry in list)
|
||||
{
|
||||
message.Key = entry.Key;
|
||||
message.Value = entry.Value;
|
||||
int entrySize = CalculateEntrySize(codec, entry);
|
||||
|
||||
size += CodedOutputStream.ComputeRawVarint32Size(codec.MapTag);
|
||||
size += CodedOutputStream.ComputeMessageSize(message);
|
||||
size += CodedOutputStream.ComputeLengthSize(entrySize) + entrySize;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
private static int CalculateEntrySize(Codec codec, KeyValuePair<TKey, TValue> entry)
|
||||
{
|
||||
return codec.KeyCodec.CalculateSizeWithTag(entry.Key) + codec.ValueCodec.CalculateSizeWithTag(entry.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string representation of this repeated field, in the same
|
||||
/// way as it would be represented by the default JSON formatter.
|
||||
@ -655,100 +657,19 @@ namespace Google.Protobuf.Collections
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tag used in the enclosing message to indicate map entries.
|
||||
/// The key codec.
|
||||
/// </summary>
|
||||
internal uint MapTag { get { return mapTag; } }
|
||||
internal FieldCodec<TKey> KeyCodec => keyCodec;
|
||||
|
||||
/// <summary>
|
||||
/// A mutable message class, used for parsing and serializing. This
|
||||
/// delegates the work to a codec, but implements the <see cref="IMessage"/> interface
|
||||
/// for interop with <see cref="CodedInputStream"/> and <see cref="CodedOutputStream"/>.
|
||||
/// This is nested inside Codec as it's tightly coupled to the associated codec,
|
||||
/// and it's simpler if it has direct access to all its fields.
|
||||
/// The value codec.
|
||||
/// </summary>
|
||||
internal class MessageAdapter : IMessage, IBufferMessage
|
||||
{
|
||||
private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 };
|
||||
internal FieldCodec<TValue> ValueCodec => valueCodec;
|
||||
|
||||
private readonly Codec codec;
|
||||
internal TKey Key { get; set; }
|
||||
internal TValue Value { get; set; }
|
||||
|
||||
internal MessageAdapter(Codec codec)
|
||||
{
|
||||
this.codec = codec;
|
||||
}
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
Key = codec.keyCodec.DefaultValue;
|
||||
Value = codec.valueCodec.DefaultValue;
|
||||
}
|
||||
|
||||
public void MergeFrom(CodedInputStream input)
|
||||
{
|
||||
// Message adapter is an internal class and we know that all the parsing will happen via InternalMergeFrom.
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
public void InternalMergeFrom(ref ParseContext ctx)
|
||||
{
|
||||
uint tag;
|
||||
while ((tag = ctx.ReadTag()) != 0)
|
||||
{
|
||||
if (tag == codec.keyCodec.Tag)
|
||||
{
|
||||
Key = codec.keyCodec.Read(ref ctx);
|
||||
}
|
||||
else if (tag == codec.valueCodec.Tag)
|
||||
{
|
||||
Value = codec.valueCodec.Read(ref ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParsingPrimitivesMessages.SkipLastField(ref ctx.buffer, ref ctx.state);
|
||||
}
|
||||
}
|
||||
|
||||
// Corner case: a map entry with a key but no value, where the value type is a message.
|
||||
// Read it as if we'd seen input with no data (i.e. create a "default" message).
|
||||
if (Value == null)
|
||||
{
|
||||
if (ctx.state.CodedInputStream != null)
|
||||
{
|
||||
// the decoded message might not support parsing from ParseContext, so
|
||||
// we need to allow fallback to the legacy MergeFrom(CodedInputStream) parsing.
|
||||
Value = codec.valueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData));
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseContext.Initialize(new ReadOnlySequence<byte>(ZeroLengthMessageStreamData), out ParseContext zeroLengthCtx);
|
||||
Value = codec.valueCodec.Read(ref zeroLengthCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteTo(CodedOutputStream output)
|
||||
{
|
||||
// Message adapter is an internal class and we know that all the writing will happen via InternalWriteTo.
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
public void InternalWriteTo(ref WriteContext ctx)
|
||||
{
|
||||
codec.keyCodec.WriteTagAndValue(ref ctx, Key);
|
||||
codec.valueCodec.WriteTagAndValue(ref ctx, Value);
|
||||
}
|
||||
|
||||
public int CalculateSize()
|
||||
{
|
||||
return codec.keyCodec.CalculateSizeWithTag(Key) + codec.valueCodec.CalculateSizeWithTag(Value);
|
||||
}
|
||||
|
||||
MessageDescriptor IMessage.Descriptor { get { return null; } }
|
||||
}
|
||||
/// <summary>
|
||||
/// The tag used in the enclosing message to indicate map entries.
|
||||
/// </summary>
|
||||
internal uint MapTag => mapTag;
|
||||
}
|
||||
|
||||
private class MapView<T> : ICollection<T>, ICollection
|
||||
|
@ -59,7 +59,7 @@ namespace Google.Protobuf
|
||||
|
||||
public int CalculateSize()
|
||||
{
|
||||
return codec.CalculateSizeWithTag(field);
|
||||
return codec.CalculateUnconditionalSizeWithTag(field);
|
||||
}
|
||||
|
||||
public IExtensionValue Clone()
|
||||
|
@ -876,6 +876,12 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public int CalculateSizeWithTag(T value) => IsDefault(value) ? 0 : ValueSizeCalculator(value) + tagSize;
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the size required to write the given value, with a tag, even
|
||||
/// if the value is the default.
|
||||
/// </summary>
|
||||
internal int CalculateUnconditionalSizeWithTag(T value) => ValueSizeCalculator(value) + tagSize;
|
||||
|
||||
private bool IsDefault(T value) => EqualityComparer.Equals(value, DefaultValue);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>C# runtime library for Protocol Buffers - Google's data interchange format.</Description>
|
||||
<Copyright>Copyright 2015, Google Inc.</Copyright>
|
||||
<AssemblyTitle>Google Protocol Buffers</AssemblyTitle>
|
||||
<VersionPrefix>3.14.0</VersionPrefix>
|
||||
<VersionPrefix>3.15.6</VersionPrefix>
|
||||
<!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence -->
|
||||
<LangVersion>7.2</LangVersion>
|
||||
<Authors>Google Inc.</Authors>
|
||||
<TargetFrameworks>netstandard1.1;netstandard2.0;net45</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard1.1;netstandard2.0;net45;net50</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
@ -27,15 +27,23 @@
|
||||
<DefineConstants>$(DefineConstants);GOOGLE_PROTOBUF_SUPPORT_FAST_STRING</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'net50' ">
|
||||
<DefineConstants>$(DefineConstants);GOOGLE_PROTOBUF_SUPPORT_FAST_STRING;GOOGLE_PROTOBUF_SIMD</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Memory" Version="4.5.3"/>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" Version="1.0.0"/>
|
||||
<!-- Needed for the net45 build to work on Unix. See https://github.com/dotnet/designs/pull/33 -->
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Needed for netcoreapp2.1 to work correctly. .NET is not able to load the assembly without this -->
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' OR '$(TargetFramework)' == 'netstandard1.1' ">
|
||||
<PackageReference Include="System.Memory" Version="4.5.3"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="System.Memory" Version="4.5.3"/>
|
||||
<!-- Needed for netcoreapp2.1 to work correctly. .NET is not able to load the assembly without this -->
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -32,9 +32,11 @@
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security;
|
||||
using Google.Protobuf.Collections;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@ -44,6 +46,8 @@ namespace Google.Protobuf
|
||||
[SecuritySafeCritical]
|
||||
internal static class ParsingPrimitivesMessages
|
||||
{
|
||||
private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 };
|
||||
|
||||
public static void SkipLastField(ref ReadOnlySpan<byte> buffer, ref ParserInternalState state)
|
||||
{
|
||||
if (state.lastTag == 0)
|
||||
@ -134,6 +138,65 @@ namespace Google.Protobuf
|
||||
SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit);
|
||||
}
|
||||
|
||||
public static KeyValuePair<TKey, TValue> ReadMapEntry<TKey, TValue>(ref ParseContext ctx, MapField<TKey, TValue>.Codec codec)
|
||||
{
|
||||
int length = ParsingPrimitives.ParseLength(ref ctx.buffer, ref ctx.state);
|
||||
if (ctx.state.recursionDepth >= ctx.state.recursionLimit)
|
||||
{
|
||||
throw InvalidProtocolBufferException.RecursionLimitExceeded();
|
||||
}
|
||||
int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, length);
|
||||
++ctx.state.recursionDepth;
|
||||
|
||||
TKey key = codec.KeyCodec.DefaultValue;
|
||||
TValue value = codec.ValueCodec.DefaultValue;
|
||||
|
||||
uint tag;
|
||||
while ((tag = ctx.ReadTag()) != 0)
|
||||
{
|
||||
if (tag == codec.KeyCodec.Tag)
|
||||
{
|
||||
key = codec.KeyCodec.Read(ref ctx);
|
||||
}
|
||||
else if (tag == codec.ValueCodec.Tag)
|
||||
{
|
||||
value = codec.ValueCodec.Read(ref ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
SkipLastField(ref ctx.buffer, ref ctx.state);
|
||||
}
|
||||
}
|
||||
|
||||
// Corner case: a map entry with a key but no value, where the value type is a message.
|
||||
// Read it as if we'd seen input with no data (i.e. create a "default" message).
|
||||
if (value == null)
|
||||
{
|
||||
if (ctx.state.CodedInputStream != null)
|
||||
{
|
||||
// the decoded message might not support parsing from ParseContext, so
|
||||
// we need to allow fallback to the legacy MergeFrom(CodedInputStream) parsing.
|
||||
value = codec.ValueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData));
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseContext.Initialize(new ReadOnlySequence<byte>(ZeroLengthMessageStreamData), out ParseContext zeroLengthCtx);
|
||||
value = codec.ValueCodec.Read(ref zeroLengthCtx);
|
||||
}
|
||||
}
|
||||
|
||||
CheckReadEndOfStreamTag(ref ctx.state);
|
||||
// Check that we've read exactly as much data as expected.
|
||||
if (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state))
|
||||
{
|
||||
throw InvalidProtocolBufferException.TruncatedMessage();
|
||||
}
|
||||
--ctx.state.recursionDepth;
|
||||
SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit);
|
||||
|
||||
return new KeyValuePair<TKey, TValue>(key, value);
|
||||
}
|
||||
|
||||
public static void ReadGroup(ref ParseContext ctx, IMessage message)
|
||||
{
|
||||
if (ctx.state.recursionDepth >= ctx.state.recursionLimit)
|
||||
|
@ -107,57 +107,58 @@ namespace Google.Protobuf.Reflection {
|
||||
"eV9wYWNrYWdlGC0gASgJEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMo",
|
||||
"CzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIjoKDE9w",
|
||||
"dGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVf",
|
||||
"UlVOVElNRRADKgkI6AcQgICAgAJKBAgmECci8gEKDk1lc3NhZ2VPcHRpb25z",
|
||||
"UlVOVElNRRADKgkI6AcQgICAgAJKBAgmECcihAIKDk1lc3NhZ2VPcHRpb25z",
|
||||
"EiYKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZRIuCh9u",
|
||||
"b19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yGAIgASgIOgVmYWxzZRIZ",
|
||||
"CgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRIRCgltYXBfZW50cnkYByABKAgS",
|
||||
"QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv",
|
||||
"YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAgQCUoECAkQ",
|
||||
"CiKeAwoMRmllbGRPcHRpb25zEjoKBWN0eXBlGAEgASgOMiMuZ29vZ2xlLnBy",
|
||||
"b3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToGU1RSSU5HEg4KBnBhY2tlZBgC",
|
||||
"IAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29nbGUucHJvdG9idWYuRmllbGRP",
|
||||
"cHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMKBGxhenkYBSABKAg6BWZhbHNl",
|
||||
"EhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEhMKBHdlYWsYCiABKAg6BWZh",
|
||||
"bHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5w",
|
||||
"cm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIi8KBUNUeXBlEgoKBlNUUklO",
|
||||
"RxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElFQ0UQAiI1CgZKU1R5cGUSDQoJ",
|
||||
"SlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAESDQoJSlNfTlVNQkVSEAIqCQjo",
|
||||
"BxCAgICAAkoECAQQBSJeCgxPbmVvZk9wdGlvbnMSQwoUdW5pbnRlcnByZXRl",
|
||||
"ZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0",
|
||||
"ZWRPcHRpb24qCQjoBxCAgICAAiKTAQoLRW51bU9wdGlvbnMSEwoLYWxsb3df",
|
||||
"YWxpYXMYAiABKAgSGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USQwoUdW5p",
|
||||
"bnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVu",
|
||||
"aW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAUQBiJ9ChBFbnVtVmFs",
|
||||
"dWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQYASABKAg6BWZhbHNlEkMKFHVuaW50",
|
||||
"ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu",
|
||||
"dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiewoOU2VydmljZU9wdGlvbnMS",
|
||||
"GQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9v",
|
||||
"cHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRP",
|
||||
"cHRpb24qCQjoBxCAgICAAiKtAgoNTWV0aG9kT3B0aW9ucxIZCgpkZXByZWNh",
|
||||
"dGVkGCEgASgIOgVmYWxzZRJfChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIv",
|
||||
"Lmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2",
|
||||
"ZWw6E0lERU1QT1RFTkNZX1VOS05PV04SQwoUdW5pbnRlcnByZXRlZF9vcHRp",
|
||||
"b24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRp",
|
||||
"b24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5DWV9VTktOT1dO",
|
||||
"EAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVOVBACKgkI6AcQ",
|
||||
"gICAgAIingIKE1VuaW50ZXJwcmV0ZWRPcHRpb24SOwoEbmFtZRgCIAMoCzIt",
|
||||
"Lmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0",
|
||||
"EhgKEGlkZW50aWZpZXJfdmFsdWUYAyABKAkSGgoScG9zaXRpdmVfaW50X3Zh",
|
||||
"bHVlGAQgASgEEhoKEm5lZ2F0aXZlX2ludF92YWx1ZRgFIAEoAxIUCgxkb3Vi",
|
||||
"bGVfdmFsdWUYBiABKAESFAoMc3RyaW5nX3ZhbHVlGAcgASgMEhcKD2FnZ3Jl",
|
||||
"Z2F0ZV92YWx1ZRgIIAEoCRozCghOYW1lUGFydBIRCgluYW1lX3BhcnQYASAC",
|
||||
"KAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigIItUBCg5Tb3VyY2VDb2RlSW5mbxI6",
|
||||
"Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2Rl",
|
||||
"SW5mby5Mb2NhdGlvbhqGAQoITG9jYXRpb24SEAoEcGF0aBgBIAMoBUICEAES",
|
||||
"EAoEc3BhbhgCIAMoBUICEAESGAoQbGVhZGluZ19jb21tZW50cxgDIAEoCRIZ",
|
||||
"ChF0cmFpbGluZ19jb21tZW50cxgEIAEoCRIhChlsZWFkaW5nX2RldGFjaGVk",
|
||||
"X2NvbW1lbnRzGAYgAygJIqcBChFHZW5lcmF0ZWRDb2RlSW5mbxJBCgphbm5v",
|
||||
"dGF0aW9uGAEgAygLMi0uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJ",
|
||||
"bmZvLkFubm90YXRpb24aTwoKQW5ub3RhdGlvbhIQCgRwYXRoGAEgAygFQgIQ",
|
||||
"ARITCgtzb3VyY2VfZmlsZRgCIAEoCRINCgViZWdpbhgDIAEoBRILCgNlbmQY",
|
||||
"BCABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rv",
|
||||
"c0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9kZXNjcmlw",
|
||||
"dG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbg=="));
|
||||
"YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAQQBUoECAUQ",
|
||||
"BkoECAYQB0oECAgQCUoECAkQCiKeAwoMRmllbGRPcHRpb25zEjoKBWN0eXBl",
|
||||
"GAEgASgOMiMuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToG",
|
||||
"U1RSSU5HEg4KBnBhY2tlZBgCIAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29n",
|
||||
"bGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMK",
|
||||
"BGxhenkYBSABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNl",
|
||||
"EhMKBHdlYWsYCiABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u",
|
||||
"GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u",
|
||||
"Ii8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElF",
|
||||
"Q0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAES",
|
||||
"DQoJSlNfTlVNQkVSEAIqCQjoBxCAgICAAkoECAQQBSJeCgxPbmVvZk9wdGlv",
|
||||
"bnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnBy",
|
||||
"b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKTAQoLRW51",
|
||||
"bU9wdGlvbnMSEwoLYWxsb3dfYWxpYXMYAiABKAgSGQoKZGVwcmVjYXRlZBgD",
|
||||
"IAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQu",
|
||||
"Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICA",
|
||||
"AkoECAUQBiJ9ChBFbnVtVmFsdWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQYASAB",
|
||||
"KAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv",
|
||||
"b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi",
|
||||
"ewoOU2VydmljZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2US",
|
||||
"QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv",
|
||||
"YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKtAgoNTWV0aG9k",
|
||||
"T3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJfChFpZGVtcG90",
|
||||
"ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRp",
|
||||
"b25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV04SQwoU",
|
||||
"dW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVm",
|
||||
"LlVuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJ",
|
||||
"REVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoK",
|
||||
"SURFTVBPVEVOVBACKgkI6AcQgICAgAIingIKE1VuaW50ZXJwcmV0ZWRPcHRp",
|
||||
"b24SOwoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJl",
|
||||
"dGVkT3B0aW9uLk5hbWVQYXJ0EhgKEGlkZW50aWZpZXJfdmFsdWUYAyABKAkS",
|
||||
"GgoScG9zaXRpdmVfaW50X3ZhbHVlGAQgASgEEhoKEm5lZ2F0aXZlX2ludF92",
|
||||
"YWx1ZRgFIAEoAxIUCgxkb3VibGVfdmFsdWUYBiABKAESFAoMc3RyaW5nX3Zh",
|
||||
"bHVlGAcgASgMEhcKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCRozCghOYW1lUGFy",
|
||||
"dBIRCgluYW1lX3BhcnQYASACKAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigIItUB",
|
||||
"Cg5Tb3VyY2VDb2RlSW5mbxI6Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2dsZS5w",
|
||||
"cm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbhqGAQoITG9jYXRpb24S",
|
||||
"EAoEcGF0aBgBIAMoBUICEAESEAoEc3BhbhgCIAMoBUICEAESGAoQbGVhZGlu",
|
||||
"Z19jb21tZW50cxgDIAEoCRIZChF0cmFpbGluZ19jb21tZW50cxgEIAEoCRIh",
|
||||
"ChlsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzGAYgAygJIqcBChFHZW5lcmF0",
|
||||
"ZWRDb2RlSW5mbxJBCgphbm5vdGF0aW9uGAEgAygLMi0uZ29vZ2xlLnByb3Rv",
|
||||
"YnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24aTwoKQW5ub3RhdGlv",
|
||||
"bhIQCgRwYXRoGAEgAygFQgIQARITCgtzb3VyY2VfZmlsZRgCIAEoCRINCgVi",
|
||||
"ZWdpbhgDIAEoBRILCgNlbmQYBCABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1",
|
||||
"ZkIQRGVzY3JpcHRvclByb3Rvc0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90",
|
||||
"b2J1Zi90eXBlcy9kZXNjcmlwdG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJv",
|
||||
"dG9idWYuUmVmbGVjdGlvbg=="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
|
@ -481,18 +481,21 @@ namespace Google.Protobuf.Reflection
|
||||
/// dependencies must come before the descriptor which depends on them. (If A depends on B, and B
|
||||
/// depends on C, then the descriptors must be presented in the order C, B, A.) This is compatible
|
||||
/// with the order in which protoc provides descriptors to plugins.</param>
|
||||
/// <param name="registry">The extension registry to use when parsing, or null if no extensions are required.</param>
|
||||
/// <returns>The file descriptors corresponding to <paramref name="descriptorData"/>.</returns>
|
||||
public static IReadOnlyList<FileDescriptor> BuildFromByteStrings(IEnumerable<ByteString> descriptorData)
|
||||
public static IReadOnlyList<FileDescriptor> BuildFromByteStrings(IEnumerable<ByteString> descriptorData, ExtensionRegistry registry)
|
||||
{
|
||||
ProtoPreconditions.CheckNotNull(descriptorData, nameof(descriptorData));
|
||||
|
||||
var parser = FileDescriptorProto.Parser.WithExtensionRegistry(registry);
|
||||
|
||||
// TODO: See if we can build a single DescriptorPool instead of building lots of them.
|
||||
// This will all behave correctly, but it's less efficient than we'd like.
|
||||
var descriptors = new List<FileDescriptor>();
|
||||
var descriptorsByName = new Dictionary<string, FileDescriptor>();
|
||||
foreach (var data in descriptorData)
|
||||
{
|
||||
var proto = FileDescriptorProto.Parser.ParseFrom(data);
|
||||
var proto = parser.ParseFrom(data);
|
||||
var dependencies = new List<FileDescriptor>();
|
||||
foreach (var dependencyName in proto.Dependency)
|
||||
{
|
||||
@ -518,6 +521,18 @@ namespace Google.Protobuf.Reflection
|
||||
return new ReadOnlyCollection<FileDescriptor>(descriptors);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given descriptor binary data into FileDescriptor objects.
|
||||
/// Note: reflection using the returned FileDescriptors is not currently supported.
|
||||
/// </summary>
|
||||
/// <param name="descriptorData">The binary file descriptor proto data. Must not be null, and any
|
||||
/// dependencies must come before the descriptor which depends on them. (If A depends on B, and B
|
||||
/// depends on C, then the descriptors must be presented in the order C, B, A.) This is compatible
|
||||
/// with the order in which protoc provides descriptors to plugins.</param>
|
||||
/// <returns>The file descriptors corresponding to <paramref name="descriptorData"/>.</returns>
|
||||
public static IReadOnlyList<FileDescriptor> BuildFromByteStrings(IEnumerable<ByteString> descriptorData) =>
|
||||
BuildFromByteStrings(descriptorData, null);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||
/// </summary>
|
||||
|
@ -32,8 +32,14 @@
|
||||
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
#if GOOGLE_PROTOBUF_SIMD
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.Arm;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
#endif
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
@ -45,8 +51,11 @@ namespace Google.Protobuf
|
||||
[SecuritySafeCritical]
|
||||
internal static class WritingPrimitives
|
||||
{
|
||||
// "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
|
||||
internal static readonly Encoding Utf8Encoding = Encoding.UTF8;
|
||||
#if NET5_0
|
||||
internal static Encoding Utf8Encoding => Encoding.UTF8; // allows JIT to devirtualize
|
||||
#else
|
||||
internal static readonly Encoding Utf8Encoding = Encoding.UTF8; // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
|
||||
#endif
|
||||
|
||||
#region Writing of values (not including tags)
|
||||
|
||||
@ -163,39 +172,34 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public static void WriteString(ref Span<byte> buffer, ref WriterInternalState state, string value)
|
||||
{
|
||||
// Optimise the case where we have enough space to write
|
||||
// the string directly to the buffer, which should be common.
|
||||
const int MaxBytesPerChar = 3;
|
||||
const int MaxSmallStringLength = 128 / MaxBytesPerChar;
|
||||
|
||||
// The string is small enough that the length will always be a 1 byte varint.
|
||||
// Also there is enough space to write length + bytes to buffer.
|
||||
// Write string directly to the buffer, and then write length.
|
||||
// This saves calling GetByteCount on the string. We get the string length from GetBytes.
|
||||
if (value.Length <= MaxSmallStringLength && buffer.Length - state.position - 1 >= value.Length * MaxBytesPerChar)
|
||||
{
|
||||
int indexOfLengthDelimiter = state.position++;
|
||||
buffer[indexOfLengthDelimiter] = (byte)WriteStringToBuffer(buffer, ref state, value);
|
||||
return;
|
||||
}
|
||||
|
||||
int length = Utf8Encoding.GetByteCount(value);
|
||||
WriteLength(ref buffer, ref state, length);
|
||||
|
||||
// Optimise the case where we have enough space to write
|
||||
// the string directly to the buffer, which should be common.
|
||||
if (buffer.Length - state.position >= length)
|
||||
{
|
||||
if (length == value.Length) // Must be all ASCII...
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
buffer[state.position + i] = (byte)value[i];
|
||||
}
|
||||
state.position += length;
|
||||
WriteAsciiStringToBuffer(buffer, ref state, value, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if NETSTANDARD1_1
|
||||
// slowpath when Encoding.GetBytes(Char*, Int32, Byte*, Int32) is not available
|
||||
byte[] bytes = Utf8Encoding.GetBytes(value);
|
||||
WriteRawBytes(ref buffer, ref state, bytes);
|
||||
#else
|
||||
ReadOnlySpan<char> source = value.AsSpan();
|
||||
int bytesUsed;
|
||||
unsafe
|
||||
{
|
||||
fixed (char* sourceChars = &MemoryMarshal.GetReference(source))
|
||||
fixed (byte* destinationBytes = &MemoryMarshal.GetReference(buffer.Slice(state.position)))
|
||||
{
|
||||
bytesUsed = Utf8Encoding.GetBytes(sourceChars, source.Length, destinationBytes, buffer.Length);
|
||||
}
|
||||
}
|
||||
state.position += bytesUsed;
|
||||
#endif
|
||||
WriteStringToBuffer(buffer, ref state, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -209,6 +213,131 @@ namespace Google.Protobuf
|
||||
}
|
||||
}
|
||||
|
||||
// Calling this method with non-ASCII content will break.
|
||||
// Content must be verified to be all ASCII before using this method.
|
||||
private static void WriteAsciiStringToBuffer(Span<byte> buffer, ref WriterInternalState state, string value, int length)
|
||||
{
|
||||
ref char sourceChars = ref MemoryMarshal.GetReference(value.AsSpan());
|
||||
ref byte destinationBytes = ref MemoryMarshal.GetReference(buffer.Slice(state.position));
|
||||
|
||||
int currentIndex = 0;
|
||||
// If 64bit, process 4 chars at a time.
|
||||
// The logic inside this check will be elided by JIT in 32bit programs.
|
||||
if (IntPtr.Size == 8)
|
||||
{
|
||||
// Need at least 4 chars available to use this optimization.
|
||||
if (length >= 4)
|
||||
{
|
||||
ref byte sourceBytes = ref Unsafe.As<char, byte>(ref sourceChars);
|
||||
|
||||
// Process 4 chars at a time until there are less than 4 remaining.
|
||||
// We already know all characters are ASCII so there is no need to validate the source.
|
||||
int lastIndexWhereCanReadFourChars = value.Length - 4;
|
||||
do
|
||||
{
|
||||
NarrowFourUtf16CharsToAsciiAndWriteToBuffer(
|
||||
ref Unsafe.AddByteOffset(ref destinationBytes, (IntPtr)currentIndex),
|
||||
Unsafe.ReadUnaligned<ulong>(ref Unsafe.AddByteOffset(ref sourceBytes, (IntPtr)(currentIndex * 2))));
|
||||
|
||||
} while ((currentIndex += 4) <= lastIndexWhereCanReadFourChars);
|
||||
}
|
||||
}
|
||||
|
||||
// Process any remaining, 1 char at a time.
|
||||
// Avoid bounds checking with ref + Unsafe
|
||||
for (; currentIndex < length; currentIndex++)
|
||||
{
|
||||
Unsafe.AddByteOffset(ref destinationBytes, (IntPtr)currentIndex) = (byte)Unsafe.AddByteOffset(ref sourceChars, (IntPtr)(currentIndex * 2));
|
||||
}
|
||||
|
||||
state.position += length;
|
||||
}
|
||||
|
||||
// Copied with permission from https://github.com/dotnet/runtime/blob/1cdafd27e4afd2c916af5df949c13f8b373c4335/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs#L1119-L1171
|
||||
//
|
||||
/// <summary>
|
||||
/// Given a QWORD which represents a buffer of 4 ASCII chars in machine-endian order,
|
||||
/// narrows each WORD to a BYTE, then writes the 4-byte result to the output buffer
|
||||
/// also in machine-endian order.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void NarrowFourUtf16CharsToAsciiAndWriteToBuffer(ref byte outputBuffer, ulong value)
|
||||
{
|
||||
#if GOOGLE_PROTOBUF_SIMD
|
||||
if (Sse2.X64.IsSupported)
|
||||
{
|
||||
// Narrows a vector of words [ w0 w1 w2 w3 ] to a vector of bytes
|
||||
// [ b0 b1 b2 b3 b0 b1 b2 b3 ], then writes 4 bytes (32 bits) to the destination.
|
||||
|
||||
Vector128<short> vecWide = Sse2.X64.ConvertScalarToVector128UInt64(value).AsInt16();
|
||||
Vector128<uint> vecNarrow = Sse2.PackUnsignedSaturate(vecWide, vecWide).AsUInt32();
|
||||
Unsafe.WriteUnaligned<uint>(ref outputBuffer, Sse2.ConvertToUInt32(vecNarrow));
|
||||
}
|
||||
else if (AdvSimd.IsSupported)
|
||||
{
|
||||
// Narrows a vector of words [ w0 w1 w2 w3 ] to a vector of bytes
|
||||
// [ b0 b1 b2 b3 * * * * ], then writes 4 bytes (32 bits) to the destination.
|
||||
|
||||
Vector128<short> vecWide = Vector128.CreateScalarUnsafe(value).AsInt16();
|
||||
Vector64<byte> lower = AdvSimd.ExtractNarrowingSaturateUnsignedLower(vecWide);
|
||||
Unsafe.WriteUnaligned<uint>(ref outputBuffer, lower.AsUInt32().ToScalar());
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Fallback to non-SIMD approach when SIMD is not available.
|
||||
// This could happen either because the APIs are not available, or hardware doesn't support it.
|
||||
// Processing 4 chars at a time in this fallback is still faster than casting one char at a time.
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
outputBuffer = (byte)value;
|
||||
value >>= 16;
|
||||
Unsafe.Add(ref outputBuffer, 1) = (byte)value;
|
||||
value >>= 16;
|
||||
Unsafe.Add(ref outputBuffer, 2) = (byte)value;
|
||||
value >>= 16;
|
||||
Unsafe.Add(ref outputBuffer, 3) = (byte)value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Unsafe.Add(ref outputBuffer, 3) = (byte)value;
|
||||
value >>= 16;
|
||||
Unsafe.Add(ref outputBuffer, 2) = (byte)value;
|
||||
value >>= 16;
|
||||
Unsafe.Add(ref outputBuffer, 1) = (byte)value;
|
||||
value >>= 16;
|
||||
outputBuffer = (byte)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int WriteStringToBuffer(Span<byte> buffer, ref WriterInternalState state, string value)
|
||||
{
|
||||
#if NETSTANDARD1_1
|
||||
// slowpath when Encoding.GetBytes(Char*, Int32, Byte*, Int32) is not available
|
||||
byte[] bytes = Utf8Encoding.GetBytes(value);
|
||||
WriteRawBytes(ref buffer, ref state, bytes);
|
||||
return bytes.Length;
|
||||
#else
|
||||
ReadOnlySpan<char> source = value.AsSpan();
|
||||
int bytesUsed;
|
||||
unsafe
|
||||
{
|
||||
fixed (char* sourceChars = &MemoryMarshal.GetReference(source))
|
||||
fixed (byte* destinationBytes = &MemoryMarshal.GetReference(buffer))
|
||||
{
|
||||
bytesUsed = Utf8Encoding.GetBytes(
|
||||
sourceChars,
|
||||
source.Length,
|
||||
destinationBytes + state.position,
|
||||
buffer.Length - state.position);
|
||||
}
|
||||
}
|
||||
state.position += bytesUsed;
|
||||
return bytesUsed;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a byte string, without a tag, to the stream.
|
||||
/// The data is length-prefixed.
|
||||
|
@ -261,7 +261,7 @@ bool FieldHasPresence(const google::protobuf::FieldDescriptor* field) {
|
||||
Old:
|
||||
|
||||
```c++
|
||||
bool FieldIsInOneof(const google::protobuf::FielDescriptor* field) {
|
||||
bool FieldIsInOneof(const google::protobuf::FieldDescriptor* field) {
|
||||
return field->containing_oneof() != nullptr;
|
||||
}
|
||||
```
|
||||
@ -269,7 +269,7 @@ bool FieldIsInOneof(const google::protobuf::FielDescriptor* field) {
|
||||
New:
|
||||
|
||||
```c++
|
||||
bool FieldIsInOneof(const google::protobuf::FielDescriptor* field) {
|
||||
bool FieldIsInOneof(const google::protobuf::FieldDescriptor* field) {
|
||||
// real_containing_oneof() returns nullptr for synthetic oneofs.
|
||||
return field->real_containing_oneof() != nullptr;
|
||||
}
|
||||
|
18
docs/jvm_aot.md
Normal file
18
docs/jvm_aot.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Ahead Of Time (AOT) compilation for the Java Virtual Machine (JVM)"
|
||||
|
||||
Ahead Of Time (AOT) compilation build tools such as those provided by [GraalVM's `native-image`](https://www.graalvm.org/reference-manual/native-image/) can require some configuration when using protobuf.
|
||||
Protobuf for the JVM uses reflection and some of its target classes are not possible to determine in advance.
|
||||
Historically, there were good reasons to use reflection based on APIs that were published effectively requiring them, and this situation is unlikely to change.
|
||||
|
||||
[The Lite version of protobuf for the JVM](https://github.com/protocolbuffers/protobuf/blob/master/java/lite.md)
|
||||
avoids reflection and may be better suited for use with AOT compilation tooling. This Lite version was originally targeted for use on Android which has similar AOT compilation
|
||||
goals as GraalVM's native-image tool.
|
||||
|
||||
## GraalVM native-image
|
||||
|
||||
This section addresses GraalVM's `native-image` configuration specifically as this AOT compilation tool due to its popularity. The `native-image` tool can be configured
|
||||
with respect to: the [Java Native Interface](https://en.wikipedia.org/wiki/Java_Native_Interface) (JNI), http proxying, reflection, and other resources. While these
|
||||
considerations can be manually declared as JSON files, we recommend that a JVM application is exercised along with
|
||||
[the assisted configuration agent](https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/#assisted-configuration-of-native-image-builds). The agent
|
||||
will generate files that you can then subsequently point at when invoking `native-image`. We recommend that the generated files are retained with a project's source
|
||||
code.
|
@ -252,11 +252,27 @@ with info about your project (name and website) so we can add an entry for you.
|
||||
1. Confluent Schema Registry
|
||||
* Website: https://github.com/confluentinc/schema-registry
|
||||
* Extensions: 1088
|
||||
|
||||
|
||||
1. ScalaPB Validate
|
||||
* Website: https://scalapb.github.io/docs/validation
|
||||
* Extension: 1089
|
||||
|
||||
|
||||
1. Astounding (Currently Private)
|
||||
* Website: https://github.com/PbPipes/Astounding
|
||||
* Website: https://github.com/PbPipes/Astounding
|
||||
* Extension: 1090
|
||||
|
||||
1. Protoc-gen-psql
|
||||
* Website: https://github.com/Intrinsec/protoc-gen-psql
|
||||
* Extension: 1091-1101
|
||||
|
||||
1. Protoc-gen-sanitize
|
||||
* Website: https://github.com/Intrinsec/protoc-gen-sanitize
|
||||
* Extension: 1102-1106
|
||||
|
||||
1. Coach Client Connect (planned release in March 2021)
|
||||
* Website: https://www.coachclientconnect.com
|
||||
* Extension: 1107
|
||||
|
||||
1. Kratos API Errors
|
||||
* Website: https://go-kratos.dev
|
||||
* Extension: 1108
|
||||
|
@ -11,6 +11,7 @@ These are projects we know about implementing Protocol Buffers for other program
|
||||
* Action Script: https://code.google.com/p/protoc-gen-as3/
|
||||
* Action Script: https://github.com/matrix3d/JProtoc
|
||||
* Action Script: https://github.com/zhongfq/protobuf-as3/
|
||||
* Ada: https://github.com/reznikmm/protobuf
|
||||
* C: https://github.com/protobuf-c/protobuf-c
|
||||
* C: http://koti.kapsi.fi/jpa/nanopb/
|
||||
* C: https://github.com/cloudwu/pbc/
|
||||
@ -101,7 +102,6 @@ These are projects we know about implementing Protocol Buffers for other program
|
||||
* Solidity: https://github.com/celer-network/pb3-gen-sol
|
||||
* Swift: https://github.com/alexeyxo/protobuf-swift
|
||||
* Swift: https://github.com/apple/swift-protobuf/
|
||||
* Typescript: https://github.com/y3llowcake/protoc-gen-ts
|
||||
* Vala: https://launchpad.net/protobuf-vala
|
||||
* Visual Basic: http://code.google.com/p/protobuf-net/
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "3.0.100",
|
||||
"version": "5.0.102",
|
||||
"rollForward": "latestMinor"
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ If you are using Maven, use the following:
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<version>3.15.3</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@ -37,7 +37,7 @@ protobuf-java-util package:
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java-util</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<version>3.15.3</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-bom</artifactId>
|
||||
<version>3.14.0</version>
|
||||
<version>3.15.6</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Protocol Buffers [BOM]</name>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-parent</artifactId>
|
||||
<version>3.14.0</version>
|
||||
<version>3.15.6</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
|
@ -31,14 +31,21 @@
|
||||
package com.google.protobuf;
|
||||
|
||||
final class Android {
|
||||
private Android() {
|
||||
}
|
||||
|
||||
// Set to true in lite_proguard_android.pgcfg.
|
||||
@SuppressWarnings("ConstantField")
|
||||
private static boolean ASSUME_ANDROID;
|
||||
|
||||
private static final Class<?> MEMORY_CLASS = getClassForName("libcore.io.Memory");
|
||||
|
||||
private static final boolean IS_ROBOLECTRIC =
|
||||
getClassForName("org.robolectric.Robolectric") != null;
|
||||
!ASSUME_ANDROID && getClassForName("org.robolectric.Robolectric") != null;
|
||||
|
||||
/** Returns {@code true} if running on an Android device. */
|
||||
static boolean isOnAndroidDevice() {
|
||||
return MEMORY_CLASS != null && !IS_ROBOLECTRIC;
|
||||
return ASSUME_ANDROID || (MEMORY_CLASS != null && !IS_ROBOLECTRIC);
|
||||
}
|
||||
|
||||
/** Returns the memory class or {@code null} if not on Android device. */
|
||||
|
@ -1043,8 +1043,10 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a byte string. Its size is the current size of this output stream and its output has
|
||||
* been copied to it.
|
||||
* Creates a byte string with the size and contents of this output stream. This does not create
|
||||
* a new copy of the underlying bytes. If the stream size grows dynamically, the runtime is
|
||||
* O(log n) in respect to the number of bytes written to the {@link Output}. If the stream size
|
||||
* stays within the initial capacity, the runtime is O(1).
|
||||
*
|
||||
* @return the current contents of this output stream, as a byte string.
|
||||
*/
|
||||
|
@ -2055,6 +2055,44 @@ public abstract class CodedInputStream {
|
||||
totalBytesRetired = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following wrapper methods exist so that InvalidProtocolBufferExceptions thrown by the
|
||||
* InputStream can be differentiated from ones thrown by CodedInputStream itself. Each call to
|
||||
* an InputStream method that can throw IOException must be wrapped like this. We do this
|
||||
* because we sometimes need to modify IPBE instances after they are thrown far away from where
|
||||
* they are thrown (ex. to add unfinished messages) and we use this signal elsewhere in the
|
||||
* exception catch chain to know when to perform these operations directly or to wrap the
|
||||
* exception in their own IPBE so the extra information can be communicated without trampling
|
||||
* downstream information.
|
||||
*/
|
||||
private static int read(InputStream input, byte[] data, int offset, int length)
|
||||
throws IOException {
|
||||
try {
|
||||
return input.read(data, offset, length);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
e.setThrownFromInputStream();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static long skip(InputStream input, long length) throws IOException {
|
||||
try {
|
||||
return input.skip(length);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
e.setThrownFromInputStream();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static int available(InputStream input) throws IOException {
|
||||
try {
|
||||
return input.available();
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
e.setThrownFromInputStream();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readTag() throws IOException {
|
||||
if (isAtEnd()) {
|
||||
@ -2783,7 +2821,8 @@ public abstract class CodedInputStream {
|
||||
|
||||
// Here we should refill the buffer as many bytes as possible.
|
||||
int bytesRead =
|
||||
input.read(
|
||||
read(
|
||||
input,
|
||||
buffer,
|
||||
bufferSize,
|
||||
Math.min(
|
||||
@ -2905,7 +2944,7 @@ public abstract class CodedInputStream {
|
||||
// Determine the number of bytes we need to read from the input stream.
|
||||
int sizeLeft = size - bufferedBytes;
|
||||
// TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
|
||||
if (sizeLeft < DEFAULT_BUFFER_SIZE || sizeLeft <= input.available()) {
|
||||
if (sizeLeft < DEFAULT_BUFFER_SIZE || sizeLeft <= available(input)) {
|
||||
// Either the bytes we need are known to be available, or the required buffer is
|
||||
// within an allowed threshold - go ahead and allocate the buffer now.
|
||||
final byte[] bytes = new byte[size];
|
||||
@ -2919,7 +2958,7 @@ public abstract class CodedInputStream {
|
||||
// Fill the remaining bytes from the input stream.
|
||||
int tempPos = bufferedBytes;
|
||||
while (tempPos < bytes.length) {
|
||||
int n = input.read(bytes, tempPos, size - tempPos);
|
||||
int n = read(input, bytes, tempPos, size - tempPos);
|
||||
if (n == -1) {
|
||||
throw InvalidProtocolBufferException.truncatedMessage();
|
||||
}
|
||||
@ -3047,7 +3086,7 @@ public abstract class CodedInputStream {
|
||||
try {
|
||||
while (totalSkipped < size) {
|
||||
int toSkip = size - totalSkipped;
|
||||
long skipped = input.skip(toSkip);
|
||||
long skipped = skip(input, toSkip);
|
||||
if (skipped < 0 || skipped > toSkip) {
|
||||
throw new IllegalStateException(
|
||||
input.getClass()
|
||||
|
@ -282,7 +282,7 @@ final class FieldSet<T extends FieldSet.FieldDescriptorLite<T>> {
|
||||
|
||||
// Wrap the contents in a new list so that the caller cannot change
|
||||
// the list's contents after setting it.
|
||||
final List newList = new ArrayList();
|
||||
final List newList = new ArrayList<>();
|
||||
newList.addAll((List) value);
|
||||
for (final Object element : newList) {
|
||||
verifyType(descriptor, element);
|
||||
|
@ -1537,11 +1537,16 @@ public abstract class GeneratedMessageLite<
|
||||
Schema<T> schema = Protobuf.getInstance().schemaFor(result);
|
||||
schema.mergeFrom(result, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
|
||||
schema.makeImmutable(result);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
if (e.getThrownFromInputStream()) {
|
||||
e = new InvalidProtocolBufferException(e);
|
||||
}
|
||||
throw e.setUnfinishedMessage(result);
|
||||
} catch (IOException e) {
|
||||
if (e.getCause() instanceof InvalidProtocolBufferException) {
|
||||
throw (InvalidProtocolBufferException) e.getCause();
|
||||
}
|
||||
throw new InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(result);
|
||||
throw new InvalidProtocolBufferException(e).setUnfinishedMessage(result);
|
||||
} catch (RuntimeException e) {
|
||||
if (e.getCause() instanceof InvalidProtocolBufferException) {
|
||||
throw (InvalidProtocolBufferException) e.getCause();
|
||||
@ -1565,11 +1570,16 @@ public abstract class GeneratedMessageLite<
|
||||
if (result.memoizedHashCode != 0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
if (e.getThrownFromInputStream()) {
|
||||
e = new InvalidProtocolBufferException(e);
|
||||
}
|
||||
throw e.setUnfinishedMessage(result);
|
||||
} catch (IOException e) {
|
||||
if (e.getCause() instanceof InvalidProtocolBufferException) {
|
||||
throw (InvalidProtocolBufferException) e.getCause();
|
||||
}
|
||||
throw new InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(result);
|
||||
throw new InvalidProtocolBufferException(e).setUnfinishedMessage(result);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw InvalidProtocolBufferException.truncatedMessage().setUnfinishedMessage(result);
|
||||
}
|
||||
@ -1727,8 +1737,13 @@ public abstract class GeneratedMessageLite<
|
||||
return null;
|
||||
}
|
||||
size = CodedInputStream.readRawVarint32(firstByte, input);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
if (e.getThrownFromInputStream()) {
|
||||
e = new InvalidProtocolBufferException(e);
|
||||
}
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new InvalidProtocolBufferException(e.getMessage());
|
||||
throw new InvalidProtocolBufferException(e);
|
||||
}
|
||||
InputStream limitedInput = new LimitedInputStream(input, size);
|
||||
CodedInputStream codedInput = CodedInputStream.newInstance(limitedInput);
|
||||
|
@ -41,6 +41,7 @@ import java.io.IOException;
|
||||
public class InvalidProtocolBufferException extends IOException {
|
||||
private static final long serialVersionUID = -1616151763072450476L;
|
||||
private MessageLite unfinishedMessage = null;
|
||||
private boolean wasThrownFromInputStream;
|
||||
|
||||
public InvalidProtocolBufferException(final String description) {
|
||||
super(description);
|
||||
@ -72,6 +73,28 @@ public class InvalidProtocolBufferException extends IOException {
|
||||
return unfinishedMessage;
|
||||
}
|
||||
|
||||
/** Set by CodedInputStream */
|
||||
void setThrownFromInputStream() {
|
||||
/* This write can be racy if the same exception is stored and then thrown by multiple custom
|
||||
* InputStreams on different threads. But since it only ever moves from false->true, there's no
|
||||
* problem. A thread checking this condition after catching this exception from a delegate
|
||||
* stream of CodedInputStream is guaranteed to always observe true, because a write on the same
|
||||
* thread set the value when the exception left the delegate. A thread checking the same
|
||||
* condition with an exception created by CodedInputStream is guaranteed to always see false,
|
||||
* because the exception has not been exposed to any code that could publish it to other threads
|
||||
* and cause a write.
|
||||
*/
|
||||
wasThrownFromInputStream = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows code catching IOException from CodedInputStream to tell whether this instance was thrown
|
||||
* by a delegate InputStream, rather than directly by a parse failure.
|
||||
*/
|
||||
boolean getThrownFromInputStream() {
|
||||
return wasThrownFromInputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwraps the underlying {@link IOException} if this exception was caused by an I/O problem.
|
||||
* Otherwise, returns {@code this}.
|
||||
|
@ -184,20 +184,20 @@ final class RawMessageInfo implements MessageInfo {
|
||||
int value;
|
||||
try {
|
||||
value = (int) info.charAt(0);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
} catch (StringIndexOutOfBoundsException e) {
|
||||
// This is a fix for issues
|
||||
// that error out on a subset of phones on charAt(0) with an index out of bounds exception.
|
||||
char[] infoChars = info.toCharArray();
|
||||
info = new String(infoChars);
|
||||
try {
|
||||
value = (int) info.charAt(0);
|
||||
} catch (ArrayIndexOutOfBoundsException e2) {
|
||||
} catch (StringIndexOutOfBoundsException e2) {
|
||||
try {
|
||||
char[] infoChars2 = new char[info.length()];
|
||||
info.getChars(0, info.length(), infoChars2, 0);
|
||||
info = new String(infoChars2);
|
||||
value = (int) info.charAt(0);
|
||||
} catch (ArrayIndexOutOfBoundsException e3) {
|
||||
} catch (StringIndexOutOfBoundsException | ArrayIndexOutOfBoundsException e3) {
|
||||
throw new IllegalStateException(
|
||||
String.format(
|
||||
"Failed parsing '%s' with charArray.length of %d", info, infoChars.length),
|
||||
|
@ -603,7 +603,12 @@ final class RopeByteString extends ByteString {
|
||||
|
||||
@Override
|
||||
public CodedInputStream newCodedInput() {
|
||||
return CodedInputStream.newInstance(new RopeInputStream());
|
||||
// Passing along direct references to internal ByteBuffers can support more efficient parsing
|
||||
// via aliasing in CodedInputStream for users who wish to use it.
|
||||
//
|
||||
// Otherwise we force data copies, both in copying as an input stream and in buffering in the
|
||||
// CodedInputSteam.
|
||||
return CodedInputStream.newInstance(asReadOnlyByteBufferList(), /* bufferIsImmutable= */ true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -346,7 +346,7 @@ final class UnsafeUtil {
|
||||
return MEMORY_ACCESSOR.supportsUnsafeByteBufferOperations();
|
||||
}
|
||||
|
||||
private static boolean determineAndroidSupportByAddressSize(Class<?> addressClass) {
|
||||
static boolean determineAndroidSupportByAddressSize(Class<?> addressClass) {
|
||||
if (!Android.isOnAndroidDevice()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ public class AbstractMessageTest extends TestCase {
|
||||
Message.Builder abstractMessageBuilder =
|
||||
new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder());
|
||||
// mergeFrom() should not throw initialization error.
|
||||
abstractMessageBuilder.mergeFrom(bytes).buildPartial();
|
||||
Message unused1 = abstractMessageBuilder.mergeFrom(bytes).buildPartial();
|
||||
try {
|
||||
abstractMessageBuilder.mergeFrom(bytes).build();
|
||||
fail();
|
||||
@ -295,7 +295,7 @@ public class AbstractMessageTest extends TestCase {
|
||||
Message.Builder dynamicMessageBuilder =
|
||||
DynamicMessage.newBuilder(TestRequiredForeign.getDescriptor());
|
||||
// mergeFrom() should not throw initialization error.
|
||||
dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
|
||||
Message unused2 = dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
|
||||
try {
|
||||
dynamicMessageBuilder.mergeFrom(bytes).build();
|
||||
fail();
|
||||
|
@ -69,7 +69,7 @@ public class DynamicMessageTest extends TestCase {
|
||||
Message.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
|
||||
Message firstMessage = builder.build();
|
||||
// double build()
|
||||
builder.build();
|
||||
Message unused = builder.build();
|
||||
// clear() after build()
|
||||
builder.clear();
|
||||
// setters after build()
|
||||
|
@ -76,6 +76,7 @@ import junit.framework.TestCase;
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
@SuppressWarnings({"ProtoBuilderReturnValueIgnored", "ReturnValueIgnored"})
|
||||
public class GeneratedMessageTest extends TestCase {
|
||||
TestUtil.ReflectionTester reflectionTester =
|
||||
new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
|
||||
|
@ -1163,8 +1163,8 @@ public class MapForProto2Test extends TestCase {
|
||||
}
|
||||
|
||||
public void testReservedWordsFieldNames() {
|
||||
ReservedAsMapField.newBuilder().build();
|
||||
ReservedAsMapFieldWithEnumValue.newBuilder().build();
|
||||
ReservedAsMapField unused1 = ReservedAsMapField.newBuilder().build();
|
||||
ReservedAsMapFieldWithEnumValue unused2 = ReservedAsMapFieldWithEnumValue.newBuilder().build();
|
||||
}
|
||||
|
||||
public void testGetMap() {
|
||||
|
@ -1294,8 +1294,8 @@ public class MapTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testReservedWordsFieldNames() {
|
||||
ReservedAsMapField.newBuilder().build();
|
||||
ReservedAsMapFieldWithEnumValue.newBuilder().build();
|
||||
ReservedAsMapField unused1 = ReservedAsMapField.newBuilder().build();
|
||||
ReservedAsMapFieldWithEnumValue unused2 = ReservedAsMapFieldWithEnumValue.newBuilder().build();
|
||||
}
|
||||
|
||||
public void testDeterministicSerialziation() throws Exception {
|
||||
|
@ -43,8 +43,10 @@ public class TestBadIdentifiers extends TestCase {
|
||||
|
||||
public void testCompilation() {
|
||||
// If this compiles, it means the generation was correct.
|
||||
TestBadIdentifiersProto.Deprecated.newBuilder();
|
||||
TestBadIdentifiersProto.Override.newBuilder();
|
||||
TestBadIdentifiersProto.Deprecated unused1 =
|
||||
TestBadIdentifiersProto.Deprecated.newBuilder().build();
|
||||
TestBadIdentifiersProto.Override unused2 =
|
||||
TestBadIdentifiersProto.Override.getDefaultInstance();
|
||||
}
|
||||
|
||||
public void testGetDescriptor() {
|
||||
|
@ -45,8 +45,10 @@ public final class TestBadIdentifiersLite extends TestCase {
|
||||
|
||||
public void testCompilation() {
|
||||
// If this compiles, it means the generation was correct.
|
||||
TestBadIdentifiersProto.Deprecated.newBuilder();
|
||||
TestBadIdentifiersProto.Override.newBuilder();
|
||||
TestBadIdentifiersProto.Deprecated.Builder builder1 =
|
||||
TestBadIdentifiersProto.Deprecated.newBuilder();
|
||||
TestBadIdentifiersProto.Override.Builder builder2 =
|
||||
TestBadIdentifiersProto.Override.newBuilder();
|
||||
}
|
||||
|
||||
public void testConflictingFieldNames() throws Exception {
|
||||
|
@ -1,56 +0,0 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: Darick Tong (darick@google.com)
|
||||
syntax = "proto2";
|
||||
|
||||
package protobuf_unittest;
|
||||
|
||||
message Proto1 {
|
||||
option experimental_java_message_interface =
|
||||
"com.google.protobuf.ExtraInterfaces.HasBoolValue";
|
||||
option experimental_java_message_interface =
|
||||
"com.google.protobuf.ExtraInterfaces.HasStringValue<Proto1>";
|
||||
option experimental_java_builder_interface =
|
||||
"com.google.protobuf.ExtraInterfaces.HasStringValueBuilder"
|
||||
"<Proto1, Builder>";
|
||||
|
||||
optional string string_value = 1;
|
||||
optional bool bool_value = 2;
|
||||
optional bytes byte_value = 3;
|
||||
optional int32 int_value = 4;
|
||||
}
|
||||
|
||||
message Proto2 {
|
||||
option experimental_java_message_interface =
|
||||
"com.google.protobuf.ExtraInterfaces.HasBoolValue";
|
||||
|
||||
optional bool bool_value = 1;
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
<arg value="--proto_path=${protobuf.source.dir}"/>
|
||||
<arg value="--proto_path=${protobuf.basedir}/java/core/${test.proto.dir}"/>
|
||||
<arg value="--experimental_allow_proto3_optional"/>
|
||||
<arg value="${protobuf.source.dir}/google/protobuf/descriptor.proto"/>
|
||||
<arg value="${protobuf.source.dir}/google/protobuf/map_lite_unittest.proto"/>
|
||||
<arg value="${protobuf.source.dir}/google/protobuf/unittest.proto"/>
|
||||
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import.proto"/>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-parent</artifactId>
|
||||
<version>3.14.0</version>
|
||||
<version>3.15.6</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>protobuf-javalite</artifactId>
|
||||
|
@ -1,3 +1,8 @@
|
||||
|
||||
# Skip runtime check for isOnAndroidDevice().
|
||||
# One line to make it easy to remove with sed.
|
||||
-assumevalues class com.google.protobuf.Android { static boolean ASSUME_ANDROID return true; }
|
||||
|
||||
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
|
||||
<fields>;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ import com.google.protobuf.UnittestImportLite.ImportEnumLite;
|
||||
import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
|
||||
import com.google.protobuf.UnittestLite.ForeignEnumLite;
|
||||
import com.google.protobuf.UnittestLite.ForeignMessageLite;
|
||||
import com.google.protobuf.UnittestLite.RecursiveMessage;
|
||||
import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
|
||||
import com.google.protobuf.UnittestLite.TestAllTypesLite;
|
||||
import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum;
|
||||
@ -61,6 +62,7 @@ import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOne
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -1638,6 +1640,160 @@ public class LiteTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testParseFromStream_IOExceptionNotLost() throws Exception {
|
||||
final IOException readException = new IOException();
|
||||
try {
|
||||
TestAllTypesLite.parseFrom(
|
||||
CodedInputStream.newInstance(
|
||||
new InputStream() {
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
throw readException;
|
||||
}
|
||||
}));
|
||||
fail();
|
||||
} catch (InvalidProtocolBufferException expected) {
|
||||
boolean found = false;
|
||||
for (Throwable exception = expected; exception != null; exception = exception.getCause()) {
|
||||
if (exception == readException) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw new AssertionError("Lost cause of parsing error", expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testParseDelimitedFromStream_IOExceptionNotLost() throws Exception {
|
||||
final IOException readException = new IOException();
|
||||
try {
|
||||
TestAllTypesLite.parseDelimitedFrom(
|
||||
new InputStream() {
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
throw readException;
|
||||
}
|
||||
});
|
||||
fail();
|
||||
} catch (InvalidProtocolBufferException expected) {
|
||||
boolean found = false;
|
||||
for (Throwable exception = expected; exception != null; exception = exception.getCause()) {
|
||||
if (exception == readException) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw new AssertionError("Lost cause of parsing error", expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testParseFromArray_manyNestedMessagesError() throws Exception {
|
||||
RecursiveMessage.Builder recursiveMessage =
|
||||
RecursiveMessage.newBuilder().setPayload(ByteString.copyFrom(new byte[1]));
|
||||
for (int i = 0; i < 20; i++) {
|
||||
recursiveMessage = RecursiveMessage.newBuilder().setRecurse(recursiveMessage.build());
|
||||
}
|
||||
byte[] result = recursiveMessage.build().toByteArray();
|
||||
result[
|
||||
result.length
|
||||
- CodedOutputStream.computeTagSize(RecursiveMessage.PAYLOAD_FIELD_NUMBER)
|
||||
- CodedOutputStream.computeLengthDelimitedFieldSize(1)] =
|
||||
0; // Set invalid tag
|
||||
try {
|
||||
RecursiveMessage.parseFrom(result);
|
||||
fail("Result was: " + Arrays.toString(result));
|
||||
} catch (InvalidProtocolBufferException expected) {
|
||||
boolean found = false;
|
||||
int exceptionCount = 0;
|
||||
for (Throwable exception = expected; exception != null; exception = exception.getCause()) {
|
||||
if (exception instanceof InvalidProtocolBufferException) {
|
||||
exceptionCount++;
|
||||
}
|
||||
for (StackTraceElement element : exception.getStackTrace()) {
|
||||
if (InvalidProtocolBufferException.class.getName().equals(element.getClassName())
|
||||
&& "invalidTag".equals(element.getMethodName())) {
|
||||
found = true;
|
||||
} else if (Android.isOnAndroidDevice()
|
||||
&& "decodeUnknownField".equals(element.getMethodName())) {
|
||||
// Android is missing the first element of the stack trace - b/181147885
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw new AssertionError("Lost cause of parsing error", expected);
|
||||
}
|
||||
if (exceptionCount > 1) {
|
||||
throw new AssertionError(exceptionCount + " nested parsing exceptions", expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testParseFromStream_manyNestedMessagesError() throws Exception {
|
||||
RecursiveMessage.Builder recursiveMessage =
|
||||
RecursiveMessage.newBuilder().setPayload(ByteString.copyFrom(new byte[1]));
|
||||
for (int i = 0; i < 20; i++) {
|
||||
recursiveMessage = RecursiveMessage.newBuilder().setRecurse(recursiveMessage.build());
|
||||
}
|
||||
byte[] result = recursiveMessage.build().toByteArray();
|
||||
result[
|
||||
result.length
|
||||
- CodedOutputStream.computeTagSize(RecursiveMessage.PAYLOAD_FIELD_NUMBER)
|
||||
- CodedOutputStream.computeLengthDelimitedFieldSize(1)] =
|
||||
0; // Set invalid tag
|
||||
try {
|
||||
RecursiveMessage.parseFrom(CodedInputStream.newInstance(new ByteArrayInputStream(result)));
|
||||
fail("Result was: " + Arrays.toString(result));
|
||||
} catch (InvalidProtocolBufferException expected) {
|
||||
boolean found = false;
|
||||
int exceptionCount = 0;
|
||||
for (Throwable exception = expected; exception != null; exception = exception.getCause()) {
|
||||
if (exception instanceof InvalidProtocolBufferException) {
|
||||
exceptionCount++;
|
||||
}
|
||||
for (StackTraceElement element : exception.getStackTrace()) {
|
||||
if (InvalidProtocolBufferException.class.getName().equals(element.getClassName())
|
||||
&& "invalidTag".equals(element.getMethodName())) {
|
||||
found = true;
|
||||
} else if (Android.isOnAndroidDevice() && "readTag".equals(element.getMethodName())) {
|
||||
// Android is missing the first element of the stack trace - b/181147885
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw new AssertionError("Lost cause of parsing error", expected);
|
||||
}
|
||||
if (exceptionCount > 1) {
|
||||
throw new AssertionError(exceptionCount + " nested parsing exceptions", expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testParseFromStream_sneakyNestedException() throws Exception {
|
||||
final InvalidProtocolBufferException sketchy =
|
||||
new InvalidProtocolBufferException("Created in a sketchy way!")
|
||||
.setUnfinishedMessage(TestAllTypesLite.getDefaultInstance());
|
||||
try {
|
||||
RecursiveMessage.parseFrom(
|
||||
CodedInputStream.newInstance(
|
||||
new InputStream() {
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
throw sketchy;
|
||||
}
|
||||
}));
|
||||
fail();
|
||||
} catch (InvalidProtocolBufferException expected) {
|
||||
assertNotSame(expected, sketchy);
|
||||
}
|
||||
assertEquals(sketchy.getUnfinishedMessage(), TestAllTypesLite.getDefaultInstance());
|
||||
}
|
||||
|
||||
public void testMergeFrom_sanity() throws Exception {
|
||||
TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build();
|
||||
byte[] bytes = one.toByteArray();
|
||||
@ -2250,24 +2406,26 @@ public class LiteTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testAddAllIteratesOnce() {
|
||||
TestAllTypesLite.newBuilder()
|
||||
.addAllRepeatedBool(new OneTimeIterableList<>(false))
|
||||
.addAllRepeatedInt32(new OneTimeIterableList<>(0))
|
||||
.addAllRepeatedInt64(new OneTimeIterableList<>(0L))
|
||||
.addAllRepeatedFloat(new OneTimeIterableList<>(0f))
|
||||
.addAllRepeatedDouble(new OneTimeIterableList<>(0d))
|
||||
.addAllRepeatedBytes(new OneTimeIterableList<>(ByteString.EMPTY))
|
||||
.addAllRepeatedString(new OneTimeIterableList<>(""))
|
||||
.addAllRepeatedNestedMessage(new OneTimeIterableList<>(NestedMessage.getDefaultInstance()))
|
||||
.addAllRepeatedBool(new OneTimeIterable<>(false))
|
||||
.addAllRepeatedInt32(new OneTimeIterable<>(0))
|
||||
.addAllRepeatedInt64(new OneTimeIterable<>(0L))
|
||||
.addAllRepeatedFloat(new OneTimeIterable<>(0f))
|
||||
.addAllRepeatedDouble(new OneTimeIterable<>(0d))
|
||||
.addAllRepeatedBytes(new OneTimeIterable<>(ByteString.EMPTY))
|
||||
.addAllRepeatedString(new OneTimeIterable<>(""))
|
||||
.addAllRepeatedNestedMessage(new OneTimeIterable<>(NestedMessage.getDefaultInstance()))
|
||||
.build();
|
||||
TestAllTypesLite unused =
|
||||
TestAllTypesLite.newBuilder()
|
||||
.addAllRepeatedBool(new OneTimeIterableList<>(false))
|
||||
.addAllRepeatedInt32(new OneTimeIterableList<>(0))
|
||||
.addAllRepeatedInt64(new OneTimeIterableList<>(0L))
|
||||
.addAllRepeatedFloat(new OneTimeIterableList<>(0f))
|
||||
.addAllRepeatedDouble(new OneTimeIterableList<>(0d))
|
||||
.addAllRepeatedBytes(new OneTimeIterableList<>(ByteString.EMPTY))
|
||||
.addAllRepeatedString(new OneTimeIterableList<>(""))
|
||||
.addAllRepeatedNestedMessage(
|
||||
new OneTimeIterableList<>(NestedMessage.getDefaultInstance()))
|
||||
.addAllRepeatedBool(new OneTimeIterable<>(false))
|
||||
.addAllRepeatedInt32(new OneTimeIterable<>(0))
|
||||
.addAllRepeatedInt64(new OneTimeIterable<>(0L))
|
||||
.addAllRepeatedFloat(new OneTimeIterable<>(0f))
|
||||
.addAllRepeatedDouble(new OneTimeIterable<>(0d))
|
||||
.addAllRepeatedBytes(new OneTimeIterable<>(ByteString.EMPTY))
|
||||
.addAllRepeatedString(new OneTimeIterable<>(""))
|
||||
.addAllRepeatedNestedMessage(new OneTimeIterable<>(NestedMessage.getDefaultInstance()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public void testAddAllIteratesOnce_throwsOnNull() {
|
||||
|
10
java/pom.xml
10
java/pom.xml
@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-parent</artifactId>
|
||||
<version>3.14.0</version>
|
||||
<version>3.15.6</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Protocol Buffers [Parent]</name>
|
||||
@ -75,7 +75,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -93,18 +93,18 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>30.0-android</version>
|
||||
<version>30.1-android</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava-testlib</artifactId>
|
||||
<version>30.0-android</version>
|
||||
<version>30.1-android</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.truth</groupId>
|
||||
<artifactId>truth</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<version>1.1.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-parent</artifactId>
|
||||
<version>3.14.0</version>
|
||||
<version>3.15.6</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>protobuf-java-util</artifactId>
|
||||
|
@ -46,7 +46,8 @@ goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryDecoder');
|
||||
goog.require('jspb.BinaryReader');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
|
||||
goog.require('jspb.utils');
|
||||
goog.requireType('jspb.BinaryMessage');
|
||||
|
||||
|
||||
describe('binaryReaderTest', function() {
|
||||
@ -55,7 +56,7 @@ describe('binaryReaderTest', function() {
|
||||
*/
|
||||
it('testInstanceCaches', /** @suppress {visibility} */ function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
writer.writeMessage(1, dummyMessage, goog.nullFunction);
|
||||
writer.writeMessage(2, dummyMessage, goog.nullFunction);
|
||||
|
||||
@ -135,7 +136,7 @@ describe('binaryReaderTest', function() {
|
||||
// Calling readMessage on a non-delimited field should trigger an
|
||||
// assertion.
|
||||
var reader = jspb.BinaryReader.alloc([8, 1]);
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
reader.nextField();
|
||||
assertThrows(function() {
|
||||
reader.readMessage(dummyMessage, goog.nullFunction);
|
||||
@ -144,47 +145,91 @@ describe('binaryReaderTest', function() {
|
||||
// Reading past the end of the stream should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([9, 1]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readFixed64()});
|
||||
assertThrows(function() {
|
||||
reader.readFixed64()
|
||||
});
|
||||
|
||||
// Reading past the end of a submessage should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
|
||||
reader.nextField();
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readFixed32()});
|
||||
assertThrows(function() {
|
||||
reader.readFixed32()
|
||||
});
|
||||
});
|
||||
|
||||
// Skipping an invalid field should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([12, 1]);
|
||||
reader.nextWireType_ = 1000;
|
||||
assertThrows(function() {reader.skipField()});
|
||||
assertThrows(function() {
|
||||
reader.skipField()
|
||||
});
|
||||
|
||||
// Reading fields with the wrong wire type should assert.
|
||||
reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readInt32()});
|
||||
assertThrows(function() {reader.readInt32String()});
|
||||
assertThrows(function() {reader.readInt64()});
|
||||
assertThrows(function() {reader.readInt64String()});
|
||||
assertThrows(function() {reader.readUint32()});
|
||||
assertThrows(function() {reader.readUint32String()});
|
||||
assertThrows(function() {reader.readUint64()});
|
||||
assertThrows(function() {reader.readUint64String()});
|
||||
assertThrows(function() {reader.readSint32()});
|
||||
assertThrows(function() {reader.readBool()});
|
||||
assertThrows(function() {reader.readEnum()});
|
||||
assertThrows(function() {
|
||||
reader.readInt32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readInt32String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readInt64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readInt64String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint32String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint64String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readSint32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readBool()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readEnum()
|
||||
});
|
||||
|
||||
reader = jspb.BinaryReader.alloc([8, 1]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readFixed32()});
|
||||
assertThrows(function() {reader.readFixed64()});
|
||||
assertThrows(function() {reader.readSfixed32()});
|
||||
assertThrows(function() {reader.readSfixed64()});
|
||||
assertThrows(function() {reader.readFloat()});
|
||||
assertThrows(function() {reader.readDouble()});
|
||||
assertThrows(function() {
|
||||
reader.readFixed32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readFixed64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readSfixed32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readSfixed64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readFloat()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readDouble()
|
||||
});
|
||||
|
||||
assertThrows(function() {reader.readString()});
|
||||
assertThrows(function() {reader.readBytes()});
|
||||
assertThrows(function() {
|
||||
reader.readString()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readBytes()
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -198,8 +243,8 @@ describe('binaryReaderTest', function() {
|
||||
* @private
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
var doTestUnsignedField_ = function(readField,
|
||||
writeField, epsilon, upperLimit, filter) {
|
||||
var doTestUnsignedField_ = function(
|
||||
readField, writeField, epsilon, upperLimit, filter) {
|
||||
assertNotNull(readField);
|
||||
assertNotNull(writeField);
|
||||
|
||||
@ -250,8 +295,8 @@ describe('binaryReaderTest', function() {
|
||||
* @private
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
var doTestSignedField_ = function(readField,
|
||||
writeField, epsilon, lowerLimit, upperLimit, filter) {
|
||||
var doTestSignedField_ = function(
|
||||
readField, writeField, epsilon, lowerLimit, upperLimit, filter) {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
// Encode zero and limits.
|
||||
@ -267,20 +312,14 @@ describe('binaryReaderTest', function() {
|
||||
for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeField.call(writer, 6, val);
|
||||
inputValues.push({
|
||||
fieldNumber: 6,
|
||||
value: val
|
||||
});
|
||||
inputValues.push({fieldNumber: 6, value: val});
|
||||
}
|
||||
|
||||
// Encode positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeField.call(writer, 7, val);
|
||||
inputValues.push({
|
||||
fieldNumber: 7,
|
||||
value: val
|
||||
});
|
||||
inputValues.push({fieldNumber: 7, value: val});
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
@ -327,33 +366,34 @@ describe('binaryReaderTest', function() {
|
||||
assertNotUndefined(jspb.BinaryWriter.prototype.writeBool);
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readUint32,
|
||||
jspb.BinaryWriter.prototype.writeUint32,
|
||||
1, Math.pow(2, 32) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeUint32, 1, Math.pow(2, 32) - 1,
|
||||
Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readUint64,
|
||||
jspb.BinaryWriter.prototype.writeUint64,
|
||||
1, Math.pow(2, 64) - 1025, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeUint64, 1, Math.pow(2, 64) - 1025,
|
||||
Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readInt32,
|
||||
jspb.BinaryWriter.prototype.writeInt32,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeInt32, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readInt64,
|
||||
jspb.BinaryWriter.prototype.writeInt64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeInt64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readEnum,
|
||||
jspb.BinaryWriter.prototype.writeEnum,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeEnum, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readBool,
|
||||
jspb.BinaryWriter.prototype.writeBool,
|
||||
1, 1, function(x) { return !!x; });
|
||||
jspb.BinaryWriter.prototype.writeBool, 1, 1, function(x) {
|
||||
return !!x;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -387,24 +427,22 @@ describe('binaryReaderTest', function() {
|
||||
// uint32 and sint32 take no more than 5 bytes
|
||||
// 08 - field prefix (type = 0 means varint)
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readUint32,
|
||||
12, '08 8C 80 80 80 00');
|
||||
jspb.BinaryReader.prototype.readUint32, 12, '08 8C 80 80 80 00');
|
||||
|
||||
// 11 stands for -6 in zigzag encoding
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readSint32,
|
||||
-6, '08 8B 80 80 80 00');
|
||||
jspb.BinaryReader.prototype.readSint32, -6, '08 8B 80 80 80 00');
|
||||
|
||||
// uint64 and sint64 take no more than 10 bytes
|
||||
// 08 - field prefix (type = 0 means varint)
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readUint64,
|
||||
12, '08 8C 80 80 80 80 80 80 80 80 00');
|
||||
jspb.BinaryReader.prototype.readUint64, 12,
|
||||
'08 8C 80 80 80 80 80 80 80 80 00');
|
||||
|
||||
// 11 stands for -6 in zigzag encoding
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readSint64,
|
||||
-6, '08 8B 80 80 80 80 80 80 80 80 00');
|
||||
jspb.BinaryReader.prototype.readSint64, -6,
|
||||
'08 8B 80 80 80 80 80 80 80 80 00');
|
||||
});
|
||||
|
||||
/**
|
||||
@ -440,27 +478,15 @@ describe('binaryReaderTest', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var testSignedData = [
|
||||
'2730538252207801776',
|
||||
'-2688470994844604560',
|
||||
'3398529779486536359',
|
||||
'3568577411627971000',
|
||||
'272477188847484900',
|
||||
'-6649058714086158188',
|
||||
'-7695254765712060806',
|
||||
'-4525541438037104029',
|
||||
'-4993706538836508568',
|
||||
'2730538252207801776', '-2688470994844604560', '3398529779486536359',
|
||||
'3568577411627971000', '272477188847484900', '-6649058714086158188',
|
||||
'-7695254765712060806', '-4525541438037104029', '-4993706538836508568',
|
||||
'4990160321893729138'
|
||||
];
|
||||
var testUnsignedData = [
|
||||
'7822732630241694882',
|
||||
'6753602971916687352',
|
||||
'2399935075244442116',
|
||||
'8724292567325338867',
|
||||
'16948784802625696584',
|
||||
'4136275908516066934',
|
||||
'3575388346793700364',
|
||||
'5167142028379259461',
|
||||
'1557573948689737699',
|
||||
'7822732630241694882', '6753602971916687352', '2399935075244442116',
|
||||
'8724292567325338867', '16948784802625696584', '4136275908516066934',
|
||||
'3575388346793700364', '5167142028379259461', '1557573948689737699',
|
||||
'17100725280812548567'
|
||||
];
|
||||
|
||||
@ -488,13 +514,13 @@ describe('binaryReaderTest', function() {
|
||||
it('testZigzagFields', function() {
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSint32,
|
||||
jspb.BinaryWriter.prototype.writeSint32,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeSint32, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSint64,
|
||||
jspb.BinaryWriter.prototype.writeSint64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeSint64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSintHash64,
|
||||
@ -509,23 +535,23 @@ describe('binaryReaderTest', function() {
|
||||
it('testFixedFields', function() {
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readFixed32,
|
||||
jspb.BinaryWriter.prototype.writeFixed32,
|
||||
1, Math.pow(2, 32) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeFixed32, 1, Math.pow(2, 32) - 1,
|
||||
Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readFixed64,
|
||||
jspb.BinaryWriter.prototype.writeFixed64,
|
||||
1, Math.pow(2, 64) - 1025, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeFixed64, 1, Math.pow(2, 64) - 1025,
|
||||
Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSfixed32,
|
||||
jspb.BinaryWriter.prototype.writeSfixed32,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeSfixed32, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSfixed64,
|
||||
jspb.BinaryWriter.prototype.writeSfixed64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeSfixed64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, Math.round);
|
||||
});
|
||||
|
||||
|
||||
@ -536,18 +562,17 @@ describe('binaryReaderTest', function() {
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readFloat,
|
||||
jspb.BinaryWriter.prototype.writeFloat,
|
||||
jspb.BinaryConstants.FLOAT32_MIN,
|
||||
-jspb.BinaryConstants.FLOAT32_MAX,
|
||||
jspb.BinaryConstants.FLOAT32_MAX,
|
||||
truncate);
|
||||
jspb.BinaryConstants.FLOAT32_MIN, -jspb.BinaryConstants.FLOAT32_MAX,
|
||||
jspb.BinaryConstants.FLOAT32_MAX, truncate);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readDouble,
|
||||
jspb.BinaryWriter.prototype.writeDouble,
|
||||
jspb.BinaryConstants.FLOAT64_EPS * 10,
|
||||
-jspb.BinaryConstants.FLOAT64_MIN,
|
||||
jspb.BinaryConstants.FLOAT64_MIN,
|
||||
function(x) { return x; });
|
||||
-jspb.BinaryConstants.FLOAT64_MIN, jspb.BinaryConstants.FLOAT64_MIN,
|
||||
function(x) {
|
||||
return x;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -614,7 +639,7 @@ describe('binaryReaderTest', function() {
|
||||
*/
|
||||
it('testNesting', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
writer.writeInt32(1, 100);
|
||||
|
||||
@ -707,7 +732,7 @@ describe('binaryReaderTest', function() {
|
||||
|
||||
// Write a group with a nested group inside.
|
||||
writer.writeInt32(5, sentinel);
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
writer.writeGroup(5, dummyMessage, function() {
|
||||
// Previously the skipGroup implementation was wrong, which only consume
|
||||
// the decoder by nextField. This case is for making the previous
|
||||
@ -726,7 +751,7 @@ describe('binaryReaderTest', function() {
|
||||
writer.writeInt64(84, 42);
|
||||
writer.writeInt64(84, 44);
|
||||
writer.writeBytes(
|
||||
43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
|
||||
43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -875,7 +900,7 @@ describe('binaryReaderTest', function() {
|
||||
var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
|
||||
var blob = [1, 2, 3, 4, 5];
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
writer.writeMessage(1, dummyMessage, function() {
|
||||
writer.writeMessage(1, dummyMessage, function() {
|
||||
@ -908,7 +933,7 @@ describe('binaryReaderTest', function() {
|
||||
*/
|
||||
it('testReadCallbacks', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
// Add an int, a submessage, and another int.
|
||||
writer.writeInt32(1, 100);
|
||||
|
@ -44,7 +44,8 @@ goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryReader');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
goog.require('jspb.utils');
|
||||
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.requireType('jspb.BinaryMessage');
|
||||
|
||||
/**
|
||||
* @param {function()} func This function should throw an error when run.
|
||||
@ -61,7 +62,7 @@ describe('binaryWriterTest', function() {
|
||||
it('testWriteErrors', function() {
|
||||
// Submessages with invalid field indices should assert.
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeMessage(-1, dummyMessage, goog.nullFunction);
|
||||
@ -69,40 +70,82 @@ describe('binaryWriterTest', function() {
|
||||
|
||||
// Writing invalid field indices should assert.
|
||||
writer = new jspb.BinaryWriter();
|
||||
assertFails(function() {writer.writeUint64(-1, 1);});
|
||||
assertFails(function() {
|
||||
writer.writeUint64(-1, 1);
|
||||
});
|
||||
|
||||
// Writing out-of-range field values should assert.
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
assertFails(function() {writer.writeInt32(1, -Infinity);});
|
||||
assertFails(function() {writer.writeInt32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeInt32(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeInt32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeInt64(1, -Infinity);});
|
||||
assertFails(function() {writer.writeInt64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeInt64(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeInt64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeUint32(1, -1);});
|
||||
assertFails(function() {writer.writeUint32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeUint32(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeUint32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeUint64(1, -1);});
|
||||
assertFails(function() {writer.writeUint64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeUint64(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeUint64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeSint32(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSint32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeSint32(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSint32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeSint64(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSint64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeSint64(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSint64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeFixed32(1, -1);});
|
||||
assertFails(function() {writer.writeFixed32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeFixed32(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeFixed32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeFixed64(1, -1);});
|
||||
assertFails(function() {writer.writeFixed64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeFixed64(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeFixed64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeSfixed32(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSfixed32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed32(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeSfixed64(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSfixed64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed64(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed64(1, Infinity);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@ -80,6 +80,8 @@ lineReader.on('line', function(line) {
|
||||
if (isRequire) {
|
||||
if (module) { // Skip goog.require() lines before the first directive.
|
||||
var fullSym = isRequire[1];
|
||||
// Skip lines importing from jspb.*, these are handled by the header above.
|
||||
if (fullSym.match(/^jspb\./)) return;
|
||||
var sym = tryStripPrefix(fullSym, pkg);
|
||||
console.log("googleProtobuf.exportSymbol('" + fullSym + "', " + module + sym + ', global);');
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryDecoder');
|
||||
goog.require('jspb.BinaryReader');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
|
||||
goog.requireType('jspb.BinaryMessage');
|
||||
|
||||
|
||||
describe('binaryReaderTest', function() {
|
||||
@ -55,7 +55,7 @@ describe('binaryReaderTest', function() {
|
||||
*/
|
||||
it('testInstanceCaches', /** @suppress {visibility} */ function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
writer.writeMessage(1, dummyMessage, goog.nullFunction);
|
||||
writer.writeMessage(2, dummyMessage, goog.nullFunction);
|
||||
|
||||
@ -135,7 +135,7 @@ describe('binaryReaderTest', function() {
|
||||
// Calling readMessage on a non-delimited field should trigger an
|
||||
// assertion.
|
||||
var reader = jspb.BinaryReader.alloc([8, 1]);
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
reader.nextField();
|
||||
assertThrows(function() {
|
||||
reader.readMessage(dummyMessage, goog.nullFunction);
|
||||
@ -144,47 +144,91 @@ describe('binaryReaderTest', function() {
|
||||
// Reading past the end of the stream should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([9, 1]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readFixed64()});
|
||||
assertThrows(function() {
|
||||
reader.readFixed64()
|
||||
});
|
||||
|
||||
// Reading past the end of a submessage should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
|
||||
reader.nextField();
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readFixed32()});
|
||||
assertThrows(function() {
|
||||
reader.readFixed32()
|
||||
});
|
||||
});
|
||||
|
||||
// Skipping an invalid field should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([12, 1]);
|
||||
reader.nextWireType_ = 1000;
|
||||
assertThrows(function() {reader.skipField()});
|
||||
assertThrows(function() {
|
||||
reader.skipField()
|
||||
});
|
||||
|
||||
// Reading fields with the wrong wire type should assert.
|
||||
reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readInt32()});
|
||||
assertThrows(function() {reader.readInt32String()});
|
||||
assertThrows(function() {reader.readInt64()});
|
||||
assertThrows(function() {reader.readInt64String()});
|
||||
assertThrows(function() {reader.readUint32()});
|
||||
assertThrows(function() {reader.readUint32String()});
|
||||
assertThrows(function() {reader.readUint64()});
|
||||
assertThrows(function() {reader.readUint64String()});
|
||||
assertThrows(function() {reader.readSint32()});
|
||||
assertThrows(function() {reader.readBool()});
|
||||
assertThrows(function() {reader.readEnum()});
|
||||
assertThrows(function() {
|
||||
reader.readInt32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readInt32String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readInt64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readInt64String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint32String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint64String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readSint32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readBool()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readEnum()
|
||||
});
|
||||
|
||||
reader = jspb.BinaryReader.alloc([8, 1]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readFixed32()});
|
||||
assertThrows(function() {reader.readFixed64()});
|
||||
assertThrows(function() {reader.readSfixed32()});
|
||||
assertThrows(function() {reader.readSfixed64()});
|
||||
assertThrows(function() {reader.readFloat()});
|
||||
assertThrows(function() {reader.readDouble()});
|
||||
assertThrows(function() {
|
||||
reader.readFixed32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readFixed64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readSfixed32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readSfixed64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readFloat()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readDouble()
|
||||
});
|
||||
|
||||
assertThrows(function() {reader.readString()});
|
||||
assertThrows(function() {reader.readBytes()});
|
||||
assertThrows(function() {
|
||||
reader.readString()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readBytes()
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -198,8 +242,8 @@ describe('binaryReaderTest', function() {
|
||||
* @private
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
var doTestUnsignedField_ = function(readField,
|
||||
writeField, epsilon, upperLimit, filter) {
|
||||
var doTestUnsignedField_ = function(
|
||||
readField, writeField, epsilon, upperLimit, filter) {
|
||||
assertNotNull(readField);
|
||||
assertNotNull(writeField);
|
||||
|
||||
@ -250,8 +294,8 @@ describe('binaryReaderTest', function() {
|
||||
* @private
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
var doTestSignedField_ = function(readField,
|
||||
writeField, epsilon, lowerLimit, upperLimit, filter) {
|
||||
var doTestSignedField_ = function(
|
||||
readField, writeField, epsilon, lowerLimit, upperLimit, filter) {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
// Encode zero and limits.
|
||||
@ -267,20 +311,14 @@ describe('binaryReaderTest', function() {
|
||||
for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeField.call(writer, 6, val);
|
||||
inputValues.push({
|
||||
fieldNumber: 6,
|
||||
value: val
|
||||
});
|
||||
inputValues.push({fieldNumber: 6, value: val});
|
||||
}
|
||||
|
||||
// Encode positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeField.call(writer, 7, val);
|
||||
inputValues.push({
|
||||
fieldNumber: 7,
|
||||
value: val
|
||||
});
|
||||
inputValues.push({fieldNumber: 7, value: val});
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
@ -327,33 +365,34 @@ describe('binaryReaderTest', function() {
|
||||
assertNotUndefined(jspb.BinaryWriter.prototype.writeBool);
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readUint32,
|
||||
jspb.BinaryWriter.prototype.writeUint32,
|
||||
1, Math.pow(2, 32) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeUint32, 1, Math.pow(2, 32) - 1,
|
||||
Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readUint64,
|
||||
jspb.BinaryWriter.prototype.writeUint64,
|
||||
1, Math.pow(2, 64) - 1025, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeUint64, 1, Math.pow(2, 64) - 1025,
|
||||
Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readInt32,
|
||||
jspb.BinaryWriter.prototype.writeInt32,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeInt32, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readInt64,
|
||||
jspb.BinaryWriter.prototype.writeInt64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeInt64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readEnum,
|
||||
jspb.BinaryWriter.prototype.writeEnum,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeEnum, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readBool,
|
||||
jspb.BinaryWriter.prototype.writeBool,
|
||||
1, 1, function(x) { return !!x; });
|
||||
jspb.BinaryWriter.prototype.writeBool, 1, 1, function(x) {
|
||||
return !!x;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -387,24 +426,22 @@ describe('binaryReaderTest', function() {
|
||||
// uint32 and sint32 take no more than 5 bytes
|
||||
// 08 - field prefix (type = 0 means varint)
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readUint32,
|
||||
12, '08 8C 80 80 80 00');
|
||||
jspb.BinaryReader.prototype.readUint32, 12, '08 8C 80 80 80 00');
|
||||
|
||||
// 11 stands for -6 in zigzag encoding
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readSint32,
|
||||
-6, '08 8B 80 80 80 00');
|
||||
jspb.BinaryReader.prototype.readSint32, -6, '08 8B 80 80 80 00');
|
||||
|
||||
// uint64 and sint64 take no more than 10 bytes
|
||||
// 08 - field prefix (type = 0 means varint)
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readUint64,
|
||||
12, '08 8C 80 80 80 80 80 80 80 80 00');
|
||||
jspb.BinaryReader.prototype.readUint64, 12,
|
||||
'08 8C 80 80 80 80 80 80 80 80 00');
|
||||
|
||||
// 11 stands for -6 in zigzag encoding
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readSint64,
|
||||
-6, '08 8B 80 80 80 80 80 80 80 80 00');
|
||||
jspb.BinaryReader.prototype.readSint64, -6,
|
||||
'08 8B 80 80 80 80 80 80 80 80 00');
|
||||
});
|
||||
|
||||
|
||||
@ -415,27 +452,15 @@ describe('binaryReaderTest', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var testSignedData = [
|
||||
'2730538252207801776',
|
||||
'-2688470994844604560',
|
||||
'3398529779486536359',
|
||||
'3568577411627971000',
|
||||
'272477188847484900',
|
||||
'-6649058714086158188',
|
||||
'-7695254765712060806',
|
||||
'-4525541438037104029',
|
||||
'-4993706538836508568',
|
||||
'2730538252207801776', '-2688470994844604560', '3398529779486536359',
|
||||
'3568577411627971000', '272477188847484900', '-6649058714086158188',
|
||||
'-7695254765712060806', '-4525541438037104029', '-4993706538836508568',
|
||||
'4990160321893729138'
|
||||
];
|
||||
var testUnsignedData = [
|
||||
'7822732630241694882',
|
||||
'6753602971916687352',
|
||||
'2399935075244442116',
|
||||
'8724292567325338867',
|
||||
'16948784802625696584',
|
||||
'4136275908516066934',
|
||||
'3575388346793700364',
|
||||
'5167142028379259461',
|
||||
'1557573948689737699',
|
||||
'7822732630241694882', '6753602971916687352', '2399935075244442116',
|
||||
'8724292567325338867', '16948784802625696584', '4136275908516066934',
|
||||
'3575388346793700364', '5167142028379259461', '1557573948689737699',
|
||||
'17100725280812548567'
|
||||
];
|
||||
|
||||
@ -463,13 +488,13 @@ describe('binaryReaderTest', function() {
|
||||
it('testZigzagFields', function() {
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSint32,
|
||||
jspb.BinaryWriter.prototype.writeSint32,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeSint32, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSint64,
|
||||
jspb.BinaryWriter.prototype.writeSint64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeSint64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, Math.round);
|
||||
});
|
||||
|
||||
|
||||
@ -479,23 +504,23 @@ describe('binaryReaderTest', function() {
|
||||
it('testFixedFields', function() {
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readFixed32,
|
||||
jspb.BinaryWriter.prototype.writeFixed32,
|
||||
1, Math.pow(2, 32) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeFixed32, 1, Math.pow(2, 32) - 1,
|
||||
Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readFixed64,
|
||||
jspb.BinaryWriter.prototype.writeFixed64,
|
||||
1, Math.pow(2, 64) - 1025, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeFixed64, 1, Math.pow(2, 64) - 1025,
|
||||
Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSfixed32,
|
||||
jspb.BinaryWriter.prototype.writeSfixed32,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeSfixed32, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSfixed64,
|
||||
jspb.BinaryWriter.prototype.writeSfixed64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
jspb.BinaryWriter.prototype.writeSfixed64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, Math.round);
|
||||
});
|
||||
|
||||
|
||||
@ -506,18 +531,17 @@ describe('binaryReaderTest', function() {
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readFloat,
|
||||
jspb.BinaryWriter.prototype.writeFloat,
|
||||
jspb.BinaryConstants.FLOAT32_MIN,
|
||||
-jspb.BinaryConstants.FLOAT32_MAX,
|
||||
jspb.BinaryConstants.FLOAT32_MAX,
|
||||
truncate);
|
||||
jspb.BinaryConstants.FLOAT32_MIN, -jspb.BinaryConstants.FLOAT32_MAX,
|
||||
jspb.BinaryConstants.FLOAT32_MAX, truncate);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readDouble,
|
||||
jspb.BinaryWriter.prototype.writeDouble,
|
||||
jspb.BinaryConstants.FLOAT64_EPS * 10,
|
||||
-jspb.BinaryConstants.FLOAT64_MIN,
|
||||
jspb.BinaryConstants.FLOAT64_MIN,
|
||||
function(x) { return x; });
|
||||
-jspb.BinaryConstants.FLOAT64_MIN, jspb.BinaryConstants.FLOAT64_MIN,
|
||||
function(x) {
|
||||
return x;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -584,7 +608,7 @@ describe('binaryReaderTest', function() {
|
||||
*/
|
||||
it('testNesting', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
writer.writeInt32(1, 100);
|
||||
|
||||
@ -677,7 +701,7 @@ describe('binaryReaderTest', function() {
|
||||
|
||||
// Write a group with a nested group inside.
|
||||
writer.writeInt32(5, sentinel);
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
writer.writeGroup(5, dummyMessage, function() {
|
||||
writer.writeInt64(42, 42);
|
||||
writer.writeGroup(6, dummyMessage, function() {
|
||||
@ -830,7 +854,7 @@ describe('binaryReaderTest', function() {
|
||||
var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
|
||||
var blob = [1, 2, 3, 4, 5];
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
writer.writeMessage(1, dummyMessage, function() {
|
||||
writer.writeMessage(1, dummyMessage, function() {
|
||||
@ -863,7 +887,7 @@ describe('binaryReaderTest', function() {
|
||||
*/
|
||||
it('testReadCallbacks', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
// Add an int, a submessage, and another int.
|
||||
writer.writeInt32(1, 100);
|
||||
|
@ -41,14 +41,14 @@
|
||||
goog.require('goog.crypt');
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
|
||||
goog.requireType('jspb.BinaryMessage');
|
||||
|
||||
/**
|
||||
* @param {function()} func This function should throw an error when run.
|
||||
*/
|
||||
function assertFails(func) {
|
||||
var e = assertThrows(func);
|
||||
//assertNotNull(e.toString().match(/Error/));
|
||||
// assertNotNull(e.toString().match(/Error/));
|
||||
}
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ describe('binaryWriterTest', function() {
|
||||
it('testWriteErrors', function() {
|
||||
// Submessages with invalid field indices should assert.
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeMessage(-1, dummyMessage, goog.nullFunction);
|
||||
@ -67,40 +67,82 @@ describe('binaryWriterTest', function() {
|
||||
|
||||
// Writing invalid field indices should assert.
|
||||
writer = new jspb.BinaryWriter();
|
||||
assertFails(function() {writer.writeUint64(-1, 1);});
|
||||
assertFails(function() {
|
||||
writer.writeUint64(-1, 1);
|
||||
});
|
||||
|
||||
// Writing out-of-range field values should assert.
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
assertFails(function() {writer.writeInt32(1, -Infinity);});
|
||||
assertFails(function() {writer.writeInt32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeInt32(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeInt32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeInt64(1, -Infinity);});
|
||||
assertFails(function() {writer.writeInt64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeInt64(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeInt64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeUint32(1, -1);});
|
||||
assertFails(function() {writer.writeUint32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeUint32(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeUint32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeUint64(1, -1);});
|
||||
assertFails(function() {writer.writeUint64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeUint64(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeUint64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeSint32(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSint32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeSint32(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSint32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeSint64(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSint64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeSint64(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSint64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeFixed32(1, -1);});
|
||||
assertFails(function() {writer.writeFixed32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeFixed32(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeFixed32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeFixed64(1, -1);});
|
||||
assertFails(function() {writer.writeFixed64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeFixed64(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeFixed64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeSfixed32(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSfixed32(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed32(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {writer.writeSfixed64(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSfixed64(1, Infinity);});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed64(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed64(1, Infinity);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@ -40,6 +40,8 @@ goog.require('proto.jspb.test.TestMapFields');
|
||||
goog.require('proto.jspb.test.MapValueMessageNoBinary');
|
||||
goog.require('proto.jspb.test.TestMapFieldsNoBinary');
|
||||
|
||||
goog.requireType('jspb.Map');
|
||||
|
||||
/**
|
||||
* Helper: check that the given map has exactly this set of (sorted) entries.
|
||||
* @param {!jspb.Map} map
|
||||
@ -98,7 +100,9 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
msg.getMapStringMsgMap().get('k').setFoo(42);
|
||||
msg.getMapStringMsgMap().get('l').setFoo(84);
|
||||
msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b');
|
||||
msg.getMapInt64StringMap().set(0x123456789abc, 'c').set(0xcba987654321, 'd');
|
||||
msg.getMapInt64StringMap()
|
||||
.set(0x123456789abc, 'c')
|
||||
.set(0xcba987654321, 'd');
|
||||
msg.getMapBoolStringMap().set(false, 'e').set(true, 'f');
|
||||
};
|
||||
|
||||
@ -107,42 +111,24 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
* @param {?} msg
|
||||
*/
|
||||
var checkMapFields = function(msg) {
|
||||
checkMapEquals(msg.getMapStringStringMap(), [
|
||||
['asdf', 'jkl;'],
|
||||
['key 2', 'hello world']
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringInt32Map(), [
|
||||
['a', 1],
|
||||
['b', -2]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringInt64Map(), [
|
||||
['c', 0x100000000],
|
||||
['d', 0x200000000]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringBoolMap(), [
|
||||
['e', true],
|
||||
['f', false]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringDoubleMap(), [
|
||||
['g', 3.14159],
|
||||
['h', 2.71828]
|
||||
]);
|
||||
checkMapEquals(
|
||||
msg.getMapStringStringMap(),
|
||||
[['asdf', 'jkl;'], ['key 2', 'hello world']]);
|
||||
checkMapEquals(msg.getMapStringInt32Map(), [['a', 1], ['b', -2]]);
|
||||
checkMapEquals(
|
||||
msg.getMapStringInt64Map(), [['c', 0x100000000], ['d', 0x200000000]]);
|
||||
checkMapEquals(msg.getMapStringBoolMap(), [['e', true], ['f', false]]);
|
||||
checkMapEquals(
|
||||
msg.getMapStringDoubleMap(), [['g', 3.14159], ['h', 2.71828]]);
|
||||
checkMapEquals(msg.getMapStringEnumMap(), [
|
||||
['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
|
||||
['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
|
||||
]);
|
||||
checkMapEquals(msg.getMapInt32StringMap(), [
|
||||
[-1, 'a'],
|
||||
[42, 'b']
|
||||
]);
|
||||
checkMapEquals(msg.getMapInt64StringMap(), [
|
||||
[0x123456789abc, 'c'],
|
||||
[0xcba987654321, 'd']
|
||||
]);
|
||||
checkMapEquals(msg.getMapBoolStringMap(), [
|
||||
[false, 'e'],
|
||||
[true, 'f']
|
||||
['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
|
||||
['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
|
||||
]);
|
||||
checkMapEquals(msg.getMapInt32StringMap(), [[-1, 'a'], [42, 'b']]);
|
||||
checkMapEquals(
|
||||
msg.getMapInt64StringMap(),
|
||||
[[0x123456789abc, 'c'], [0xcba987654321, 'd']]);
|
||||
checkMapEquals(msg.getMapBoolStringMap(), [[false, 'e'], [true, 'f']]);
|
||||
|
||||
assertEquals(msg.getMapStringMsgMap().getLength(), 2);
|
||||
assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42);
|
||||
@ -187,10 +173,7 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
assertElementsEquals(it.next().value, ['asdf', 'hello world']);
|
||||
assertElementsEquals(it.next().value, ['jkl;', 'key 2']);
|
||||
assertEquals(it.next().done, true);
|
||||
checkMapEquals(m, [
|
||||
['asdf', 'hello world'],
|
||||
['jkl;', 'key 2']
|
||||
]);
|
||||
checkMapEquals(m, [['asdf', 'hello world'], ['jkl;', 'key 2']]);
|
||||
m.del('jkl;');
|
||||
assertEquals(m.has('jkl;'), false);
|
||||
assertEquals(m.get('jkl;'), undefined);
|
||||
@ -242,11 +225,11 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
msg.getMapStringStringMap().set('A', 'a');
|
||||
var serialized = msg.serializeBinary();
|
||||
var expectedSerialized = [
|
||||
0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
|
||||
0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
|
||||
0x41, // ASCII 'A'
|
||||
0x12, 0x1, // field 2 in submessage (value), delimited, length 1
|
||||
0x61 // ASCII 'a'
|
||||
0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
|
||||
0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
|
||||
0x41, // ASCII 'A'
|
||||
0x12, 0x1, // field 2 in submessage (value), delimited, length 1
|
||||
0x61 // ASCII 'a'
|
||||
];
|
||||
assertEquals(serialized.length, expectedSerialized.length);
|
||||
for (var i = 0; i < serialized.length; i++) {
|
||||
@ -267,11 +250,7 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
*/
|
||||
it('testLazyMapSync' + suffix, function() {
|
||||
// Start with a JSPB array containing a few map entries.
|
||||
var entries = [
|
||||
['a', 'entry 1'],
|
||||
['c', 'entry 2'],
|
||||
['b', 'entry 3']
|
||||
];
|
||||
var entries = [['a', 'entry 1'], ['c', 'entry 2'], ['b', 'entry 3']];
|
||||
var msg = new msgInfo.constructor([entries]);
|
||||
assertEquals(entries.length, 3);
|
||||
assertEquals(entries[0][0], 'a');
|
||||
@ -279,9 +258,9 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
assertEquals(entries[2][0], 'b');
|
||||
msg.getMapStringStringMap().del('a');
|
||||
assertEquals(entries.length, 3); // not yet sync'd
|
||||
msg.toArray(); // force a sync
|
||||
msg.toArray(); // force a sync
|
||||
assertEquals(entries.length, 2);
|
||||
assertEquals(entries[0][0], 'b'); // now in sorted order
|
||||
assertEquals(entries[0][0], 'b'); // now in sorted order
|
||||
assertEquals(entries[1][0], 'c');
|
||||
|
||||
var a = msg.toArray();
|
||||
@ -290,12 +269,16 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
}
|
||||
|
||||
describe('mapsTest', function() {
|
||||
makeTests({
|
||||
constructor: proto.jspb.test.TestMapFields,
|
||||
deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary
|
||||
}, proto.jspb.test.MapValueMessage, "_Binary");
|
||||
makeTests({
|
||||
constructor: proto.jspb.test.TestMapFieldsNoBinary,
|
||||
deserializeBinary: null
|
||||
}, proto.jspb.test.MapValueMessageNoBinary, "_NoBinary");
|
||||
makeTests(
|
||||
{
|
||||
constructor: proto.jspb.test.TestMapFields,
|
||||
deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary
|
||||
},
|
||||
proto.jspb.test.MapValueMessage, '_Binary');
|
||||
makeTests(
|
||||
{
|
||||
constructor: proto.jspb.test.TestMapFieldsNoBinary,
|
||||
deserializeBinary: null
|
||||
},
|
||||
proto.jspb.test.MapValueMessageNoBinary, '_NoBinary');
|
||||
});
|
||||
|
@ -67,7 +67,6 @@ goog.require('proto.jspb.test.Simple1');
|
||||
goog.require('proto.jspb.test.Simple2');
|
||||
goog.require('proto.jspb.test.SpecialCases');
|
||||
goog.require('proto.jspb.test.TestClone');
|
||||
goog.require('proto.jspb.test.TestEndsWithBytes');
|
||||
goog.require('proto.jspb.test.TestGroup');
|
||||
goog.require('proto.jspb.test.TestGroup1');
|
||||
goog.require('proto.jspb.test.TestMessageWithOneof');
|
||||
@ -77,7 +76,7 @@ goog.require('proto.jspb.test.TestReservedNamesExtension');
|
||||
// CommonJS-LoadFromFile: test2_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.ExtensionMessage');
|
||||
goog.require('proto.jspb.test.TestExtensionsMessage');
|
||||
|
||||
goog.require('proto.jspb.test.simple1');
|
||||
|
||||
|
||||
|
||||
@ -102,59 +101,59 @@ describe('Message test suite', function() {
|
||||
});
|
||||
|
||||
it('testComplexConversion', function() {
|
||||
var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, true];
|
||||
var data2 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, true];
|
||||
var data1 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , true];
|
||||
var data2 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , true];
|
||||
var foo = new proto.jspb.test.Complex(data1);
|
||||
var bar = new proto.jspb.test.Complex(data2);
|
||||
var result = foo.toObject();
|
||||
assertObjectEquals({
|
||||
aString: 'a',
|
||||
anOutOfOrderBool: true,
|
||||
aNestedMessage: {
|
||||
anInt: 11
|
||||
},
|
||||
aRepeatedMessageList: [{anInt: 22}, {anInt: 33}],
|
||||
aRepeatedStringList: ['s1', 's2']
|
||||
}, result);
|
||||
assertObjectEquals(
|
||||
{
|
||||
aString: 'a',
|
||||
anOutOfOrderBool: true,
|
||||
aNestedMessage: {anInt: 11},
|
||||
aRepeatedMessageList: [{anInt: 22}, {anInt: 33}],
|
||||
aRepeatedStringList: ['s1', 's2']
|
||||
},
|
||||
result);
|
||||
|
||||
// Now test with the jspb instances included.
|
||||
result = foo.toObject(true /* opt_includeInstance */);
|
||||
assertObjectEquals({
|
||||
aString: 'a',
|
||||
anOutOfOrderBool: true,
|
||||
aNestedMessage: {
|
||||
anInt: 11,
|
||||
$jspbMessageInstance: foo.getANestedMessage()
|
||||
},
|
||||
aRepeatedMessageList: [
|
||||
{anInt: 22, $jspbMessageInstance: foo.getARepeatedMessageList()[0]},
|
||||
{anInt: 33, $jspbMessageInstance: foo.getARepeatedMessageList()[1]}
|
||||
],
|
||||
aRepeatedStringList: ['s1', 's2'],
|
||||
$jspbMessageInstance: foo
|
||||
}, result);
|
||||
|
||||
assertObjectEquals(
|
||||
{
|
||||
aString: 'a',
|
||||
anOutOfOrderBool: true,
|
||||
aNestedMessage:
|
||||
{anInt: 11, $jspbMessageInstance: foo.getANestedMessage()},
|
||||
aRepeatedMessageList: [
|
||||
{anInt: 22, $jspbMessageInstance: foo.getARepeatedMessageList()[0]},
|
||||
{anInt: 33, $jspbMessageInstance: foo.getARepeatedMessageList()[1]}
|
||||
],
|
||||
aRepeatedStringList: ['s1', 's2'],
|
||||
$jspbMessageInstance: foo
|
||||
},
|
||||
result);
|
||||
});
|
||||
|
||||
it('testMissingFields', function() {
|
||||
var foo = new proto.jspb.test.Complex([
|
||||
undefined, undefined, undefined, [],
|
||||
undefined, undefined, undefined, undefined]);
|
||||
undefined, undefined, undefined, [], undefined, undefined, undefined,
|
||||
undefined
|
||||
]);
|
||||
var bar = new proto.jspb.test.Complex([
|
||||
undefined, undefined, undefined, [],
|
||||
undefined, undefined, undefined, undefined]);
|
||||
undefined, undefined, undefined, [], undefined, undefined, undefined,
|
||||
undefined
|
||||
]);
|
||||
var result = foo.toObject();
|
||||
assertObjectEquals({
|
||||
aString: undefined,
|
||||
anOutOfOrderBool: undefined,
|
||||
aNestedMessage: {
|
||||
anInt: undefined
|
||||
},
|
||||
// Note: JsPb converts undefined repeated fields to empty arrays.
|
||||
aRepeatedMessageList: [],
|
||||
aRepeatedStringList: []
|
||||
}, result);
|
||||
|
||||
assertObjectEquals(
|
||||
{
|
||||
aString: undefined,
|
||||
anOutOfOrderBool: undefined,
|
||||
aNestedMessage: {anInt: undefined},
|
||||
// Note: JsPb converts undefined repeated fields to empty arrays.
|
||||
aRepeatedMessageList: [],
|
||||
aRepeatedStringList: []
|
||||
},
|
||||
result);
|
||||
});
|
||||
|
||||
it('testNestedComplexMessage', function() {
|
||||
@ -167,20 +166,21 @@ describe('Message test suite', function() {
|
||||
it('testSpecialCases', function() {
|
||||
// Note: Some property names are reserved in JavaScript.
|
||||
// These names are converted to the Js property named pb_<reserved_name>.
|
||||
var special =
|
||||
new proto.jspb.test.SpecialCases(['normal', 'default', 'function',
|
||||
'var']);
|
||||
var special = new proto.jspb.test.SpecialCases(
|
||||
['normal', 'default', 'function', 'var']);
|
||||
var result = special.toObject();
|
||||
assertObjectEquals({
|
||||
normal: 'normal',
|
||||
pb_default: 'default',
|
||||
pb_function: 'function',
|
||||
pb_var: 'var'
|
||||
}, result);
|
||||
assertObjectEquals(
|
||||
{
|
||||
normal: 'normal',
|
||||
pb_default: 'default',
|
||||
pb_function: 'function',
|
||||
pb_var: 'var'
|
||||
},
|
||||
result);
|
||||
});
|
||||
|
||||
it('testDefaultValues', function() {
|
||||
var defaultString = "default<>\'\"abc";
|
||||
var defaultString = 'default<>\'"abc';
|
||||
var response = new proto.jspb.test.DefaultValues();
|
||||
|
||||
// Test toObject
|
||||
@ -244,8 +244,10 @@ describe('Message test suite', function() {
|
||||
|
||||
// Test that clearing the values reverts them to the default state.
|
||||
response = makeDefault(['blah', false, 111, 77]);
|
||||
response.clearStringField(); response.clearBoolField();
|
||||
response.clearIntField(); response.clearEnumField();
|
||||
response.clearStringField();
|
||||
response.clearBoolField();
|
||||
response.clearIntField();
|
||||
response.clearEnumField();
|
||||
assertEquals(defaultString, response.getStringField());
|
||||
assertEquals(true, response.getBoolField());
|
||||
assertEquals(11, response.getIntField());
|
||||
@ -257,8 +259,10 @@ describe('Message test suite', function() {
|
||||
|
||||
// Test that setFoo(null) clears the values.
|
||||
response = makeDefault(['blah', false, 111, 77]);
|
||||
response.setStringField(null); response.setBoolField(null);
|
||||
response.setIntField(undefined); response.setEnumField(undefined);
|
||||
response.setStringField(null);
|
||||
response.setBoolField(null);
|
||||
response.setIntField(undefined);
|
||||
response.setEnumField(undefined);
|
||||
assertEquals(defaultString, response.getStringField());
|
||||
assertEquals(true, response.getBoolField());
|
||||
assertEquals(11, response.getIntField());
|
||||
@ -288,15 +292,15 @@ describe('Message test suite', function() {
|
||||
// but we actually get a sparse array instead. We could use something
|
||||
// like [1,undefined,2] to avoid this, except that this is still
|
||||
// sparse on IE. No comment...
|
||||
var expected = [,,, [], []];
|
||||
var expected = [, , , [], []];
|
||||
expected[0] = expected[1] = expected[2] = undefined;
|
||||
assertObjectEquals(expected, foo.toArray());
|
||||
});
|
||||
|
||||
it('testDifferenceRawObject', /** @suppress {visibility} */ function() {
|
||||
var p1 = new proto.jspb.test.HasExtensions(['hi', 'diff', {}]);
|
||||
var p2 = new proto.jspb.test.HasExtensions(['hi', 'what',
|
||||
{1000: 'unique'}]);
|
||||
var p2 =
|
||||
new proto.jspb.test.HasExtensions(['hi', 'what', {1000: 'unique'}]);
|
||||
var diff = /** @type {proto.jspb.test.HasExtensions} */
|
||||
(jspb.Message.difference(p1, p2));
|
||||
assertEquals('', diff.getStr1());
|
||||
@ -310,13 +314,13 @@ describe('Message test suite', function() {
|
||||
assertTrue(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi'])));
|
||||
assertFalse(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['bye'])));
|
||||
var s1b = new proto.jspb.test.Simple1(['hi', ['hello']]);
|
||||
assertTrue(jspb.Message.equals(s1b,
|
||||
new proto.jspb.test.Simple1(['hi', ['hello']])));
|
||||
assertTrue(jspb.Message.equals(s1b,
|
||||
new proto.jspb.test.Simple1(['hi', ['hello', undefined,
|
||||
undefined, undefined]])));
|
||||
assertFalse(jspb.Message.equals(s1b,
|
||||
new proto.jspb.test.Simple1(['no', ['hello']])));
|
||||
assertTrue(jspb.Message.equals(
|
||||
s1b, new proto.jspb.test.Simple1(['hi', ['hello']])));
|
||||
assertTrue(jspb.Message.equals(s1b, new proto.jspb.test.Simple1([
|
||||
'hi', ['hello', undefined, undefined, undefined]
|
||||
])));
|
||||
assertFalse(jspb.Message.equals(
|
||||
s1b, new proto.jspb.test.Simple1(['no', ['hello']])));
|
||||
// Test with messages of different types
|
||||
var s2 = new proto.jspb.test.Simple2(['hi']);
|
||||
assertFalse(jspb.Message.equals(s1, s2));
|
||||
@ -324,18 +328,18 @@ describe('Message test suite', function() {
|
||||
|
||||
it('testEquals_softComparison', function() {
|
||||
var s1 = new proto.jspb.test.Simple1(['hi', [], null]);
|
||||
assertTrue(jspb.Message.equals(s1,
|
||||
new proto.jspb.test.Simple1(['hi', []])));
|
||||
assertTrue(
|
||||
jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi', []])));
|
||||
|
||||
var s1b = new proto.jspb.test.Simple1(['hi', [], true]);
|
||||
assertTrue(jspb.Message.equals(s1b,
|
||||
new proto.jspb.test.Simple1(['hi', [], 1])));
|
||||
assertTrue(
|
||||
jspb.Message.equals(s1b, new proto.jspb.test.Simple1(['hi', [], 1])));
|
||||
});
|
||||
|
||||
it('testEqualsComplex', function() {
|
||||
var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
|
||||
var data2 = ['a',,, [, 11], [[, 22], [, 34]],, ['s1', 's2'],, 1];
|
||||
var data3 = ['a',,, [, 11], [[, 22]],, ['s1', 's2'],, 1];
|
||||
var data1 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , 1];
|
||||
var data2 = ['a', , , [, 11], [[, 22], [, 34]], , ['s1', 's2'], , 1];
|
||||
var data3 = ['a', , , [, 11], [[, 22]], , ['s1', 's2'], , 1];
|
||||
var data4 = ['hi'];
|
||||
var c1a = new proto.jspb.test.Complex(data1);
|
||||
var c1b = new proto.jspb.test.Complex(data1);
|
||||
@ -352,42 +356,34 @@ describe('Message test suite', function() {
|
||||
it('testEqualsExtensionsConstructed', function() {
|
||||
assertTrue(jspb.Message.equals(
|
||||
new proto.jspb.test.HasExtensions([]),
|
||||
new proto.jspb.test.HasExtensions([{}])
|
||||
));
|
||||
new proto.jspb.test.HasExtensions([{}])));
|
||||
assertTrue(jspb.Message.equals(
|
||||
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
|
||||
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
|
||||
));
|
||||
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])));
|
||||
assertFalse(jspb.Message.equals(
|
||||
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
|
||||
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}])
|
||||
));
|
||||
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}])));
|
||||
assertTrue(jspb.Message.equals(
|
||||
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
|
||||
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
|
||||
));
|
||||
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])));
|
||||
assertTrue(jspb.Message.equals(
|
||||
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
|
||||
new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}])
|
||||
));
|
||||
new proto.jspb.test.HasExtensions([, , , {100: [{200: 'a'}]}])));
|
||||
assertTrue(jspb.Message.equals(
|
||||
new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}]),
|
||||
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
|
||||
));
|
||||
new proto.jspb.test.HasExtensions([, , , {100: [{200: 'a'}]}]),
|
||||
new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])));
|
||||
assertTrue(jspb.Message.equals(
|
||||
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
|
||||
new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}])
|
||||
));
|
||||
new proto.jspb.test.HasExtensions(['hi', , , {100: [{200: 'a'}]}])));
|
||||
assertTrue(jspb.Message.equals(
|
||||
new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}]),
|
||||
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
|
||||
));
|
||||
new proto.jspb.test.HasExtensions(['hi', , , {100: [{200: 'a'}]}]),
|
||||
new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])));
|
||||
});
|
||||
|
||||
it('testEqualsExtensionsUnconstructed', function() {
|
||||
assertTrue(jspb.Message.compareFields([], [{}]));
|
||||
assertTrue(jspb.Message.compareFields([,,, {}], []));
|
||||
assertTrue(jspb.Message.compareFields([,,, {}], [,, {}]));
|
||||
assertTrue(jspb.Message.compareFields([, , , {}], []));
|
||||
assertTrue(jspb.Message.compareFields([, , , {}], [, , {}]));
|
||||
assertTrue(jspb.Message.compareFields(
|
||||
['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
|
||||
assertFalse(jspb.Message.compareFields(
|
||||
@ -395,25 +391,25 @@ describe('Message test suite', function() {
|
||||
assertTrue(jspb.Message.compareFields(
|
||||
[{100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
|
||||
assertTrue(jspb.Message.compareFields(
|
||||
[{100: [{200: 'a'}]}], [,,, {100: [{200: 'a'}]}]));
|
||||
[{100: [{200: 'a'}]}], [, , , {100: [{200: 'a'}]}]));
|
||||
assertTrue(jspb.Message.compareFields(
|
||||
[,,, {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
|
||||
[, , , {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
|
||||
assertTrue(jspb.Message.compareFields(
|
||||
['hi', {100: [{200: 'a'}]}], ['hi',,, {100: [{200: 'a'}]}]));
|
||||
['hi', {100: [{200: 'a'}]}], ['hi', , , {100: [{200: 'a'}]}]));
|
||||
assertTrue(jspb.Message.compareFields(
|
||||
['hi',,, {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
|
||||
['hi', , , {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
|
||||
});
|
||||
|
||||
it('testToMap', function() {
|
||||
var p1 = new proto.jspb.test.Simple1(['k', ['v']]);
|
||||
var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]);
|
||||
var soymap = jspb.Message.toMap([p1, p2],
|
||||
proto.jspb.test.Simple1.prototype.getAString,
|
||||
var soymap = jspb.Message.toMap(
|
||||
[p1, p2], proto.jspb.test.Simple1.prototype.getAString,
|
||||
proto.jspb.test.Simple1.prototype.toObject);
|
||||
assertEquals('k', soymap['k'].aString);
|
||||
assertArrayEquals(['v'], soymap['k'].aRepeatedStringList);
|
||||
var protomap = jspb.Message.toMap([p1, p2],
|
||||
proto.jspb.test.Simple1.prototype.getAString);
|
||||
var protomap = jspb.Message.toMap(
|
||||
[p1, p2], proto.jspb.test.Simple1.prototype.getAString);
|
||||
assertEquals('k', protomap['k'].getAString());
|
||||
assertArrayEquals(['v'], protomap['k'].getARepeatedStringList());
|
||||
});
|
||||
@ -434,8 +430,12 @@ describe('Message test suite', function() {
|
||||
extension.setExt('e1');
|
||||
original.setExtension(proto.jspb.test.IsExtension.extField, extension);
|
||||
var clone = original.clone();
|
||||
assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
|
||||
[['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }],
|
||||
assertArrayEquals(
|
||||
[
|
||||
'v1', , ['x1', ['y1', 'z1']], ,
|
||||
[['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1, ,
|
||||
{100: [, 'e1']}
|
||||
],
|
||||
clone.toArray());
|
||||
clone.setStr('v2');
|
||||
var simple4 = new proto.jspb.test.Simple1(['a1', ['b1', 'c1']]);
|
||||
@ -452,11 +452,19 @@ describe('Message test suite', function() {
|
||||
var newExtension = new proto.jspb.test.CloneExtension();
|
||||
newExtension.setExt('e2');
|
||||
clone.setExtension(proto.jspb.test.CloneExtension.extField, newExtension);
|
||||
assertArrayEquals(['v2',, ['a1', ['b1', 'c1']],,
|
||||
[['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]], bytes2,, { 100: [, 'e2'] }],
|
||||
assertArrayEquals(
|
||||
[
|
||||
'v2', , ['a1', ['b1', 'c1']], ,
|
||||
[['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]], bytes2, ,
|
||||
{100: [, 'e2']}
|
||||
],
|
||||
clone.toArray());
|
||||
assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
|
||||
[['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }],
|
||||
assertArrayEquals(
|
||||
[
|
||||
'v1', , ['x1', ['y1', 'z1']], ,
|
||||
[['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1, ,
|
||||
{100: [, 'e1']}
|
||||
],
|
||||
original.toArray());
|
||||
});
|
||||
|
||||
@ -488,11 +496,12 @@ describe('Message test suite', function() {
|
||||
jspb.Message.copyInto(original, dest);
|
||||
assertArrayEquals(original.toArray(), dest.toArray());
|
||||
assertEquals('x1', dest.getSimple1().getAString());
|
||||
assertEquals('e1',
|
||||
assertEquals(
|
||||
'e1',
|
||||
dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt());
|
||||
dest.getSimple1().setAString('new value');
|
||||
assertNotEquals(dest.getSimple1().getAString(),
|
||||
original.getSimple1().getAString());
|
||||
assertNotEquals(
|
||||
dest.getSimple1().getAString(), original.getSimple1().getAString());
|
||||
if (supportsUint8Array) {
|
||||
dest.getBytesField()[0] = 7;
|
||||
assertObjectEquals(bytes1, original.getBytesField());
|
||||
@ -502,12 +511,12 @@ describe('Message test suite', function() {
|
||||
assertObjectEquals(bytes1, original.getBytesField());
|
||||
assertObjectEquals('789', dest.getBytesField());
|
||||
}
|
||||
dest.getExtension(proto.jspb.test.CloneExtension.extField).
|
||||
setExt('new value');
|
||||
dest.getExtension(proto.jspb.test.CloneExtension.extField)
|
||||
.setExt('new value');
|
||||
assertNotEquals(
|
||||
dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt(),
|
||||
original.getExtension(
|
||||
proto.jspb.test.CloneExtension.extField).getExt());
|
||||
original.getExtension(proto.jspb.test.CloneExtension.extField)
|
||||
.getExt());
|
||||
});
|
||||
|
||||
it('testCopyInto_notSameType', function() {
|
||||
@ -525,26 +534,32 @@ describe('Message test suite', function() {
|
||||
var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2']]);
|
||||
var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
|
||||
extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
|
||||
extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
|
||||
extension2);
|
||||
extendable.setExtension(
|
||||
proto.jspb.test.IndirectExtension.simple, extension2);
|
||||
extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
|
||||
extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
|
||||
['a', 'b']);
|
||||
extendable.setExtension(
|
||||
proto.jspb.test.IndirectExtension.repeatedStrList, ['a', 'b']);
|
||||
var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
|
||||
var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2']]);
|
||||
extendable.setExtension(
|
||||
proto.jspb.test.IndirectExtension.repeatedSimpleList,
|
||||
[s1, s2]);
|
||||
assertObjectEquals(extension1,
|
||||
proto.jspb.test.IndirectExtension.repeatedSimpleList, [s1, s2]);
|
||||
assertObjectEquals(
|
||||
extension1,
|
||||
extendable.getExtension(proto.jspb.test.IsExtension.extField));
|
||||
assertObjectEquals(extension2,
|
||||
assertObjectEquals(
|
||||
extension2,
|
||||
extendable.getExtension(proto.jspb.test.IndirectExtension.simple));
|
||||
assertObjectEquals('xyzzy',
|
||||
assertObjectEquals(
|
||||
'xyzzy',
|
||||
extendable.getExtension(proto.jspb.test.IndirectExtension.str));
|
||||
assertObjectEquals(['a', 'b'], extendable.getExtension(
|
||||
proto.jspb.test.IndirectExtension.repeatedStrList));
|
||||
assertObjectEquals([s1, s2], extendable.getExtension(
|
||||
proto.jspb.test.IndirectExtension.repeatedSimpleList));
|
||||
assertObjectEquals(
|
||||
['a', 'b'],
|
||||
extendable.getExtension(
|
||||
proto.jspb.test.IndirectExtension.repeatedStrList));
|
||||
assertObjectEquals(
|
||||
[s1, s2],
|
||||
extendable.getExtension(
|
||||
proto.jspb.test.IndirectExtension.repeatedSimpleList));
|
||||
// Not supported yet, but it should work...
|
||||
extendable.setExtension(proto.jspb.test.IndirectExtension.simple, null);
|
||||
assertNull(
|
||||
@ -563,18 +578,18 @@ describe('Message test suite', function() {
|
||||
var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
|
||||
var extension = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
|
||||
extendable.setExtension(proto.jspb.test.simple1, extension);
|
||||
assertObjectEquals(extension,
|
||||
extendable.getExtension(proto.jspb.test.simple1));
|
||||
assertObjectEquals(
|
||||
extension, extendable.getExtension(proto.jspb.test.simple1));
|
||||
|
||||
// From _lib mode.
|
||||
extension = new proto.jspb.test.ExtensionMessage(['s1']);
|
||||
extendable = new proto.jspb.test.TestExtensionsMessage([16]);
|
||||
extendable.setExtension(proto.jspb.test.floatingMsgField, extension);
|
||||
extendable.setExtension(proto.jspb.test.floatingStrField, 's2');
|
||||
assertObjectEquals(extension,
|
||||
extendable.getExtension(proto.jspb.test.floatingMsgField));
|
||||
assertObjectEquals('s2',
|
||||
extendable.getExtension(proto.jspb.test.floatingStrField));
|
||||
assertObjectEquals(
|
||||
extension, extendable.getExtension(proto.jspb.test.floatingMsgField));
|
||||
assertObjectEquals(
|
||||
's2', extendable.getExtension(proto.jspb.test.floatingStrField));
|
||||
assertNotUndefined(proto.jspb.exttest.floatingMsgField);
|
||||
assertNotUndefined(proto.jspb.exttest.floatingMsgFieldTwo);
|
||||
assertNotUndefined(proto.jspb.exttest.beta.floatingStrField);
|
||||
@ -585,60 +600,72 @@ describe('Message test suite', function() {
|
||||
var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2'], true]);
|
||||
var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
|
||||
extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
|
||||
extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
|
||||
extension2);
|
||||
extendable.setExtension(
|
||||
proto.jspb.test.IndirectExtension.simple, extension2);
|
||||
extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
|
||||
extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
|
||||
['a', 'b']);
|
||||
extendable.setExtension(
|
||||
proto.jspb.test.IndirectExtension.repeatedStrList, ['a', 'b']);
|
||||
var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2'], true]);
|
||||
var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2'], false]);
|
||||
extendable.setExtension(
|
||||
proto.jspb.test.IndirectExtension.repeatedSimpleList,
|
||||
[s1, s2]);
|
||||
assertObjectEquals({
|
||||
str1: 'v1', str2: 'v2', str3: 'v3',
|
||||
extField: { ext1: 'ext1field' },
|
||||
simple: {
|
||||
aString: 'str', aRepeatedStringList: ['s1', 's2'], aBoolean: true
|
||||
},
|
||||
str: 'xyzzy',
|
||||
repeatedStrList: ['a', 'b'],
|
||||
repeatedSimpleList: [
|
||||
{ aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true},
|
||||
{ aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false}
|
||||
]
|
||||
}, extendable.toObject());
|
||||
proto.jspb.test.IndirectExtension.repeatedSimpleList, [s1, s2]);
|
||||
assertObjectEquals(
|
||||
{
|
||||
str1: 'v1',
|
||||
str2: 'v2',
|
||||
str3: 'v3',
|
||||
extField: {ext1: 'ext1field'},
|
||||
simple: {
|
||||
aString: 'str',
|
||||
aRepeatedStringList: ['s1', 's2'],
|
||||
aBoolean: true
|
||||
},
|
||||
str: 'xyzzy',
|
||||
repeatedStrList: ['a', 'b'],
|
||||
repeatedSimpleList: [
|
||||
{aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true},
|
||||
{aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false}
|
||||
]
|
||||
},
|
||||
extendable.toObject());
|
||||
|
||||
// Now, with instances included.
|
||||
assertObjectEquals({
|
||||
str1: 'v1', str2: 'v2', str3: 'v3',
|
||||
extField: {
|
||||
ext1: 'ext1field',
|
||||
$jspbMessageInstance:
|
||||
extendable.getExtension(proto.jspb.test.IsExtension.extField)
|
||||
},
|
||||
simple: {
|
||||
aString: 'str',
|
||||
aRepeatedStringList: ['s1', 's2'],
|
||||
aBoolean: true,
|
||||
$jspbMessageInstance:
|
||||
extendable.getExtension(proto.jspb.test.IndirectExtension.simple)
|
||||
},
|
||||
str: 'xyzzy',
|
||||
repeatedStrList: ['a', 'b'],
|
||||
repeatedSimpleList: [{
|
||||
aString: 'foo',
|
||||
aRepeatedStringList: ['s1', 's2'],
|
||||
aBoolean: true,
|
||||
$jspbMessageInstance: s1
|
||||
}, {
|
||||
aString: 'bar',
|
||||
aRepeatedStringList: ['t1', 't2'],
|
||||
aBoolean: false,
|
||||
$jspbMessageInstance: s2
|
||||
}],
|
||||
$jspbMessageInstance: extendable
|
||||
}, extendable.toObject(true /* opt_includeInstance */));
|
||||
assertObjectEquals(
|
||||
{
|
||||
str1: 'v1',
|
||||
str2: 'v2',
|
||||
str3: 'v3',
|
||||
extField: {
|
||||
ext1: 'ext1field',
|
||||
$jspbMessageInstance:
|
||||
extendable.getExtension(proto.jspb.test.IsExtension.extField)
|
||||
},
|
||||
simple: {
|
||||
aString: 'str',
|
||||
aRepeatedStringList: ['s1', 's2'],
|
||||
aBoolean: true,
|
||||
$jspbMessageInstance: extendable.getExtension(
|
||||
proto.jspb.test.IndirectExtension.simple)
|
||||
},
|
||||
str: 'xyzzy',
|
||||
repeatedStrList: ['a', 'b'],
|
||||
repeatedSimpleList: [
|
||||
{
|
||||
aString: 'foo',
|
||||
aRepeatedStringList: ['s1', 's2'],
|
||||
aBoolean: true,
|
||||
$jspbMessageInstance: s1
|
||||
},
|
||||
{
|
||||
aString: 'bar',
|
||||
aRepeatedStringList: ['t1', 't2'],
|
||||
aBoolean: false,
|
||||
$jspbMessageInstance: s2
|
||||
}
|
||||
],
|
||||
$jspbMessageInstance: extendable
|
||||
},
|
||||
extendable.toObject(true /* opt_includeInstance */));
|
||||
});
|
||||
|
||||
it('testInitialization_emptyArray', function() {
|
||||
@ -690,8 +717,7 @@ describe('Message test suite', function() {
|
||||
var extensionMessage = new proto.jspb.test.IsExtension(['is_extension']);
|
||||
data.setExtension(proto.jspb.test.IsExtension.extField, extensionMessage);
|
||||
var obj = data.toObject();
|
||||
assertNotNull(
|
||||
data.getExtension(proto.jspb.test.IsExtension.extField));
|
||||
assertNotNull(data.getExtension(proto.jspb.test.IsExtension.extField));
|
||||
assertEquals('is_extension', obj.extField.ext1);
|
||||
});
|
||||
|
||||
@ -708,16 +734,18 @@ describe('Message test suite', function() {
|
||||
var groups = group.getRepeatedGroupList();
|
||||
assertEquals('g1', groups[0].getId());
|
||||
assertObjectEquals([true, false], groups[0].getSomeBoolList());
|
||||
assertObjectEquals({id: 'g1', someBoolList: [true, false]},
|
||||
groups[0].toObject());
|
||||
assertObjectEquals({
|
||||
repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}],
|
||||
requiredGroup: {id: undefined},
|
||||
optionalGroup: undefined,
|
||||
requiredSimple: {aRepeatedStringList: [], aString: undefined},
|
||||
optionalSimple: undefined,
|
||||
id: undefined
|
||||
}, group.toObject());
|
||||
assertObjectEquals(
|
||||
{id: 'g1', someBoolList: [true, false]}, groups[0].toObject());
|
||||
assertObjectEquals(
|
||||
{
|
||||
repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}],
|
||||
requiredGroup: {id: undefined},
|
||||
optionalGroup: undefined,
|
||||
requiredSimple: {aRepeatedStringList: [], aString: undefined},
|
||||
optionalSimple: undefined,
|
||||
id: undefined
|
||||
},
|
||||
group.toObject());
|
||||
var group1 = new proto.jspb.test.TestGroup1();
|
||||
group1.setGroup(someGroup);
|
||||
assertEquals(someGroup, group1.getGroup());
|
||||
@ -734,25 +762,26 @@ describe('Message test suite', function() {
|
||||
message.setExtension$(11);
|
||||
message.setExtension(proto.jspb.test.TestReservedNamesExtension.foo, 12);
|
||||
assertEquals(11, message.getExtension$());
|
||||
assertEquals(12, message.getExtension(
|
||||
proto.jspb.test.TestReservedNamesExtension.foo));
|
||||
assertEquals(
|
||||
12,
|
||||
message.getExtension(proto.jspb.test.TestReservedNamesExtension.foo));
|
||||
assertObjectEquals({extension: 11, foo: 12}, message.toObject());
|
||||
});
|
||||
|
||||
it('testInitializeMessageWithUnsetOneof', function() {
|
||||
var message = new proto.jspb.test.TestMessageWithOneof([]);
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
|
||||
PARTIAL_ONEOF_NOT_SET,
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase
|
||||
.PARTIAL_ONEOF_NOT_SET,
|
||||
message.getPartialOneofCase());
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
|
||||
RECURSIVE_ONEOF_NOT_SET,
|
||||
proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase
|
||||
.RECURSIVE_ONEOF_NOT_SET,
|
||||
message.getRecursiveOneofCase());
|
||||
});
|
||||
|
||||
it('testInitializeMessageWithSingleValueSetInOneof', function() {
|
||||
var message = new proto.jspb.test.TestMessageWithOneof([,, 'x']);
|
||||
var message = new proto.jspb.test.TestMessageWithOneof([, , 'x']);
|
||||
|
||||
assertEquals('x', message.getPone());
|
||||
assertEquals('', message.getPthree());
|
||||
@ -762,7 +791,7 @@ describe('Message test suite', function() {
|
||||
});
|
||||
|
||||
it('testKeepsLastWireValueSetInUnion_multipleValues', function() {
|
||||
var message = new proto.jspb.test.TestMessageWithOneof([,, 'x',, 'y']);
|
||||
var message = new proto.jspb.test.TestMessageWithOneof([, , 'x', , 'y']);
|
||||
|
||||
assertEquals('', message.getPone());
|
||||
assertEquals('y', message.getPthree());
|
||||
@ -819,8 +848,8 @@ describe('Message test suite', function() {
|
||||
it('testUnsetsOneofCaseWhenFieldIsCleared', function() {
|
||||
var message = new proto.jspb.test.TestMessageWithOneof;
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
|
||||
PARTIAL_ONEOF_NOT_SET,
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase
|
||||
.PARTIAL_ONEOF_NOT_SET,
|
||||
message.getPartialOneofCase());
|
||||
|
||||
message.setPone('hi');
|
||||
@ -830,8 +859,8 @@ describe('Message test suite', function() {
|
||||
|
||||
message.clearPone();
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
|
||||
PARTIAL_ONEOF_NOT_SET,
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase
|
||||
.PARTIAL_ONEOF_NOT_SET,
|
||||
message.getPartialOneofCase());
|
||||
});
|
||||
|
||||
@ -934,39 +963,39 @@ describe('Message test suite', function() {
|
||||
});
|
||||
|
||||
it('testInitializeMessageWithOneofDefaults_defaultNotSetOnFirstField',
|
||||
function() {
|
||||
var message;
|
||||
function() {
|
||||
var message;
|
||||
|
||||
message =
|
||||
new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567));
|
||||
assertEquals(567, message.getBone());
|
||||
assertEquals(1234, message.getBtwo());
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
|
||||
message.getDefaultOneofBCase());
|
||||
message =
|
||||
new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567));
|
||||
assertEquals(567, message.getBone());
|
||||
assertEquals(1234, message.getBtwo());
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
|
||||
message.getDefaultOneofBCase());
|
||||
|
||||
message =
|
||||
new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890));
|
||||
assertEquals(0, message.getBone());
|
||||
assertEquals(890, message.getBtwo());
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
|
||||
message.getDefaultOneofBCase());
|
||||
message =
|
||||
new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890));
|
||||
assertEquals(0, message.getBone());
|
||||
assertEquals(890, message.getBtwo());
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
|
||||
message.getDefaultOneofBCase());
|
||||
|
||||
message = new proto.jspb.test.TestMessageWithOneof(
|
||||
new Array(11).concat(567, 890));
|
||||
assertEquals(0, message.getBone());
|
||||
assertEquals(890, message.getBtwo());
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
|
||||
message.getDefaultOneofBCase());
|
||||
});
|
||||
message = new proto.jspb.test.TestMessageWithOneof(
|
||||
new Array(11).concat(567, 890));
|
||||
assertEquals(0, message.getBone());
|
||||
assertEquals(890, message.getBtwo());
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
|
||||
message.getDefaultOneofBCase());
|
||||
});
|
||||
|
||||
it('testOneofContainingAnotherMessage', function() {
|
||||
var message = new proto.jspb.test.TestMessageWithOneof;
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
|
||||
RECURSIVE_ONEOF_NOT_SET,
|
||||
proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase
|
||||
.RECURSIVE_ONEOF_NOT_SET,
|
||||
message.getRecursiveOneofCase());
|
||||
|
||||
var other = new proto.jspb.test.TestMessageWithOneof;
|
||||
@ -987,25 +1016,25 @@ describe('Message test suite', function() {
|
||||
|
||||
it('testQueryingOneofCaseEnsuresOnlyOneFieldIsSetInUnderlyingArray',
|
||||
function() {
|
||||
var message = new proto.jspb.test.TestMessageWithOneof;
|
||||
message.setPone('x');
|
||||
assertEquals('x', message.getPone());
|
||||
assertEquals('', message.getPthree());
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
|
||||
message.getPartialOneofCase());
|
||||
var message = new proto.jspb.test.TestMessageWithOneof;
|
||||
message.setPone('x');
|
||||
assertEquals('x', message.getPone());
|
||||
assertEquals('', message.getPthree());
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
|
||||
message.getPartialOneofCase());
|
||||
|
||||
var array = message.toArray();
|
||||
assertEquals('x', array[2]);
|
||||
assertUndefined(array[4]);
|
||||
array[4] = 'y';
|
||||
var array = message.toArray();
|
||||
assertEquals('x', array[2]);
|
||||
assertUndefined(array[4]);
|
||||
array[4] = 'y';
|
||||
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
|
||||
message.getPartialOneofCase());
|
||||
assertUndefined(array[2]);
|
||||
assertEquals('y', array[4]);
|
||||
});
|
||||
assertEquals(
|
||||
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
|
||||
message.getPartialOneofCase());
|
||||
assertUndefined(array[2]);
|
||||
assertEquals('y', array[4]);
|
||||
});
|
||||
|
||||
it('testFloatingPointFieldsSupportNan', function() {
|
||||
var assertNan = function(x) {
|
||||
@ -1015,8 +1044,7 @@ describe('Message test suite', function() {
|
||||
};
|
||||
|
||||
var message = new proto.jspb.test.FloatingPointFields([
|
||||
'NaN', 'NaN', ['NaN', 'NaN'], 'NaN',
|
||||
'NaN', 'NaN', ['NaN', 'NaN'], 'NaN'
|
||||
'NaN', 'NaN', ['NaN', 'NaN'], 'NaN', 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN'
|
||||
]);
|
||||
assertNan(message.getOptionalFloatField());
|
||||
assertNan(message.getRequiredFloatField());
|
||||
@ -1029,5 +1057,4 @@ describe('Message test suite', function() {
|
||||
assertNan(message.getRepeatedDoubleFieldList()[1]);
|
||||
assertNan(message.getDefaultDoubleField());
|
||||
});
|
||||
|
||||
});
|
||||
|
161
js/maps_test.js
161
js/maps_test.js
@ -53,6 +53,8 @@ goog.require('proto.jspb.test.MapEntryOptionalValuesMessageValue');
|
||||
goog.require('proto.jspb.test.MapValueMessageNoBinary');
|
||||
goog.require('proto.jspb.test.TestMapFieldsNoBinary');
|
||||
|
||||
goog.requireType('jspb.Map');
|
||||
|
||||
/**
|
||||
* Helper: check that the given map has exactly this set of (sorted) entries.
|
||||
* @param {!jspb.Map} map
|
||||
@ -116,7 +118,9 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
msg.getMapStringMsgMap().get('k').setFoo(42);
|
||||
msg.getMapStringMsgMap().get('l').setFoo(84);
|
||||
msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b');
|
||||
msg.getMapInt64StringMap().set(0x123456789abc, 'c').set(0xcba987654321, 'd');
|
||||
msg.getMapInt64StringMap()
|
||||
.set(0x123456789abc, 'c')
|
||||
.set(0xcba987654321, 'd');
|
||||
msg.getMapBoolStringMap().set(false, 'e').set(true, 'f');
|
||||
};
|
||||
|
||||
@ -125,42 +129,24 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
* @param {?} msg
|
||||
*/
|
||||
var checkMapFields = function(msg) {
|
||||
checkMapEquals(msg.getMapStringStringMap(), [
|
||||
['asdf', 'jkl;'],
|
||||
['key 2', 'hello world']
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringInt32Map(), [
|
||||
['a', 1],
|
||||
['b', -2]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringInt64Map(), [
|
||||
['c', 0x100000000],
|
||||
['d', 0x200000000]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringBoolMap(), [
|
||||
['e', true],
|
||||
['f', false]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringDoubleMap(), [
|
||||
['g', 3.14159],
|
||||
['h', 2.71828]
|
||||
]);
|
||||
checkMapEquals(
|
||||
msg.getMapStringStringMap(),
|
||||
[['asdf', 'jkl;'], ['key 2', 'hello world']]);
|
||||
checkMapEquals(msg.getMapStringInt32Map(), [['a', 1], ['b', -2]]);
|
||||
checkMapEquals(
|
||||
msg.getMapStringInt64Map(), [['c', 0x100000000], ['d', 0x200000000]]);
|
||||
checkMapEquals(msg.getMapStringBoolMap(), [['e', true], ['f', false]]);
|
||||
checkMapEquals(
|
||||
msg.getMapStringDoubleMap(), [['g', 3.14159], ['h', 2.71828]]);
|
||||
checkMapEquals(msg.getMapStringEnumMap(), [
|
||||
['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
|
||||
['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
|
||||
]);
|
||||
checkMapEquals(msg.getMapInt32StringMap(), [
|
||||
[-1, 'a'],
|
||||
[42, 'b']
|
||||
]);
|
||||
checkMapEquals(msg.getMapInt64StringMap(), [
|
||||
[0x123456789abc, 'c'],
|
||||
[0xcba987654321, 'd']
|
||||
]);
|
||||
checkMapEquals(msg.getMapBoolStringMap(), [
|
||||
[false, 'e'],
|
||||
[true, 'f']
|
||||
['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
|
||||
['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
|
||||
]);
|
||||
checkMapEquals(msg.getMapInt32StringMap(), [[-1, 'a'], [42, 'b']]);
|
||||
checkMapEquals(
|
||||
msg.getMapInt64StringMap(),
|
||||
[[0x123456789abc, 'c'], [0xcba987654321, 'd']]);
|
||||
checkMapEquals(msg.getMapBoolStringMap(), [[false, 'e'], [true, 'f']]);
|
||||
|
||||
assertEquals(msg.getMapStringMsgMap().getLength(), 2);
|
||||
assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42);
|
||||
@ -205,10 +191,7 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
assertElementsEquals(it.next().value, ['asdf', 'hello world']);
|
||||
assertElementsEquals(it.next().value, ['jkl;', 'key 2']);
|
||||
assertEquals(it.next().done, true);
|
||||
checkMapEquals(m, [
|
||||
['asdf', 'hello world'],
|
||||
['jkl;', 'key 2']
|
||||
]);
|
||||
checkMapEquals(m, [['asdf', 'hello world'], ['jkl;', 'key 2']]);
|
||||
m.del('jkl;');
|
||||
assertEquals(m.has('jkl;'), false);
|
||||
assertEquals(m.get('jkl;'), undefined);
|
||||
@ -260,11 +243,11 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
msg.getMapStringStringMap().set('A', 'a');
|
||||
var serialized = msg.serializeBinary();
|
||||
var expectedSerialized = [
|
||||
0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
|
||||
0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
|
||||
0x41, // ASCII 'A'
|
||||
0x12, 0x1, // field 2 in submessage (value), delimited, length 1
|
||||
0x61 // ASCII 'a'
|
||||
0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
|
||||
0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
|
||||
0x41, // ASCII 'A'
|
||||
0x12, 0x1, // field 2 in submessage (value), delimited, length 1
|
||||
0x61 // ASCII 'a'
|
||||
];
|
||||
assertEquals(serialized.length, expectedSerialized.length);
|
||||
for (var i = 0; i < serialized.length; i++) {
|
||||
@ -284,34 +267,27 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
* binary format.
|
||||
*/
|
||||
it('testMapDeserializationForUndefinedKeys', function() {
|
||||
var testMessageOptionalKeys = new proto.jspb.test.TestMapFieldsOptionalKeys();
|
||||
var mapEntryStringKey = new proto.jspb.test.MapEntryOptionalKeysStringKey();
|
||||
mapEntryStringKey.setValue("a");
|
||||
var testMessageOptionalKeys =
|
||||
new proto.jspb.test.TestMapFieldsOptionalKeys();
|
||||
var mapEntryStringKey =
|
||||
new proto.jspb.test.MapEntryOptionalKeysStringKey();
|
||||
mapEntryStringKey.setValue('a');
|
||||
testMessageOptionalKeys.setMapStringString(mapEntryStringKey);
|
||||
var mapEntryInt32Key = new proto.jspb.test.MapEntryOptionalKeysInt32Key();
|
||||
mapEntryInt32Key.setValue("b");
|
||||
mapEntryInt32Key.setValue('b');
|
||||
testMessageOptionalKeys.setMapInt32String(mapEntryInt32Key);
|
||||
var mapEntryInt64Key = new proto.jspb.test.MapEntryOptionalKeysInt64Key();
|
||||
mapEntryInt64Key.setValue("c");
|
||||
mapEntryInt64Key.setValue('c');
|
||||
testMessageOptionalKeys.setMapInt64String(mapEntryInt64Key);
|
||||
var mapEntryBoolKey = new proto.jspb.test.MapEntryOptionalKeysBoolKey();
|
||||
mapEntryBoolKey.setValue("d");
|
||||
mapEntryBoolKey.setValue('d');
|
||||
testMessageOptionalKeys.setMapBoolString(mapEntryBoolKey);
|
||||
var deserializedMessage = msgInfo.deserializeBinary(
|
||||
testMessageOptionalKeys.serializeBinary()
|
||||
);
|
||||
checkMapEquals(deserializedMessage.getMapStringStringMap(), [
|
||||
['', 'a']
|
||||
]);
|
||||
checkMapEquals(deserializedMessage.getMapInt32StringMap(), [
|
||||
[0, 'b']
|
||||
]);
|
||||
checkMapEquals(deserializedMessage.getMapInt64StringMap(), [
|
||||
[0, 'c']
|
||||
]);
|
||||
checkMapEquals(deserializedMessage.getMapBoolStringMap(), [
|
||||
[false, 'd']
|
||||
]);
|
||||
var deserializedMessage =
|
||||
msgInfo.deserializeBinary(testMessageOptionalKeys.serializeBinary());
|
||||
checkMapEquals(deserializedMessage.getMapStringStringMap(), [['', 'a']]);
|
||||
checkMapEquals(deserializedMessage.getMapInt32StringMap(), [[0, 'b']]);
|
||||
checkMapEquals(deserializedMessage.getMapInt64StringMap(), [[0, 'c']]);
|
||||
checkMapEquals(deserializedMessage.getMapBoolStringMap(), [[false, 'd']]);
|
||||
});
|
||||
|
||||
/**
|
||||
@ -323,56 +299,41 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
new proto.jspb.test.TestMapFieldsOptionalValues();
|
||||
var mapEntryStringValue =
|
||||
new proto.jspb.test.MapEntryOptionalValuesStringValue();
|
||||
mapEntryStringValue.setKey("a");
|
||||
mapEntryStringValue.setKey('a');
|
||||
testMessageOptionalValues.setMapStringString(mapEntryStringValue);
|
||||
var mapEntryInt32Value =
|
||||
new proto.jspb.test.MapEntryOptionalValuesInt32Value();
|
||||
mapEntryInt32Value.setKey("b");
|
||||
mapEntryInt32Value.setKey('b');
|
||||
testMessageOptionalValues.setMapStringInt32(mapEntryInt32Value);
|
||||
var mapEntryInt64Value =
|
||||
new proto.jspb.test.MapEntryOptionalValuesInt64Value();
|
||||
mapEntryInt64Value.setKey("c");
|
||||
mapEntryInt64Value.setKey('c');
|
||||
testMessageOptionalValues.setMapStringInt64(mapEntryInt64Value);
|
||||
var mapEntryBoolValue =
|
||||
new proto.jspb.test.MapEntryOptionalValuesBoolValue();
|
||||
mapEntryBoolValue.setKey("d");
|
||||
mapEntryBoolValue.setKey('d');
|
||||
testMessageOptionalValues.setMapStringBool(mapEntryBoolValue);
|
||||
var mapEntryDoubleValue =
|
||||
new proto.jspb.test.MapEntryOptionalValuesDoubleValue();
|
||||
mapEntryDoubleValue.setKey("e");
|
||||
mapEntryDoubleValue.setKey('e');
|
||||
testMessageOptionalValues.setMapStringDouble(mapEntryDoubleValue);
|
||||
var mapEntryEnumValue =
|
||||
new proto.jspb.test.MapEntryOptionalValuesEnumValue();
|
||||
mapEntryEnumValue.setKey("f");
|
||||
mapEntryEnumValue.setKey('f');
|
||||
testMessageOptionalValues.setMapStringEnum(mapEntryEnumValue);
|
||||
var mapEntryMessageValue =
|
||||
new proto.jspb.test.MapEntryOptionalValuesMessageValue();
|
||||
mapEntryMessageValue.setKey("g");
|
||||
mapEntryMessageValue.setKey('g');
|
||||
testMessageOptionalValues.setMapStringMsg(mapEntryMessageValue);
|
||||
var deserializedMessage = msgInfo.deserializeBinary(
|
||||
testMessageOptionalValues.serializeBinary()
|
||||
);
|
||||
checkMapEquals(deserializedMessage.getMapStringStringMap(), [
|
||||
['a', '']
|
||||
]);
|
||||
checkMapEquals(deserializedMessage.getMapStringInt32Map(), [
|
||||
['b', 0]
|
||||
]);
|
||||
checkMapEquals(deserializedMessage.getMapStringInt64Map(), [
|
||||
['c', 0]
|
||||
]);
|
||||
checkMapEquals(deserializedMessage.getMapStringBoolMap(), [
|
||||
['d', false]
|
||||
]);
|
||||
checkMapEquals(deserializedMessage.getMapStringDoubleMap(), [
|
||||
['e', 0.0]
|
||||
]);
|
||||
checkMapEquals(deserializedMessage.getMapStringEnumMap(), [
|
||||
['f', 0]
|
||||
]);
|
||||
checkMapEquals(deserializedMessage.getMapStringMsgMap(), [
|
||||
['g', []]
|
||||
]);
|
||||
testMessageOptionalValues.serializeBinary());
|
||||
checkMapEquals(deserializedMessage.getMapStringStringMap(), [['a', '']]);
|
||||
checkMapEquals(deserializedMessage.getMapStringInt32Map(), [['b', 0]]);
|
||||
checkMapEquals(deserializedMessage.getMapStringInt64Map(), [['c', 0]]);
|
||||
checkMapEquals(deserializedMessage.getMapStringBoolMap(), [['d', false]]);
|
||||
checkMapEquals(deserializedMessage.getMapStringDoubleMap(), [['e', 0.0]]);
|
||||
checkMapEquals(deserializedMessage.getMapStringEnumMap(), [['f', 0]]);
|
||||
checkMapEquals(deserializedMessage.getMapStringMsgMap(), [['g', []]]);
|
||||
});
|
||||
}
|
||||
|
||||
@ -382,11 +343,7 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
*/
|
||||
it('testLazyMapSync' + suffix, function() {
|
||||
// Start with a JSPB array containing a few map entries.
|
||||
var entries = [
|
||||
['a', 'entry 1'],
|
||||
['c', 'entry 2'],
|
||||
['b', 'entry 3']
|
||||
];
|
||||
var entries = [['a', 'entry 1'], ['c', 'entry 2'], ['b', 'entry 3']];
|
||||
var msg = new msgInfo.constructor([entries]);
|
||||
assertEquals(entries.length, 3);
|
||||
assertEquals(entries[0][0], 'a');
|
||||
@ -394,9 +351,9 @@ function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
assertEquals(entries[2][0], 'b');
|
||||
msg.getMapStringStringMap().del('a');
|
||||
assertEquals(entries.length, 3); // not yet sync'd
|
||||
msg.toArray(); // force a sync
|
||||
msg.toArray(); // force a sync
|
||||
assertEquals(entries.length, 2);
|
||||
assertEquals(entries[0][0], 'b'); // now in sorted order
|
||||
assertEquals(entries[0][0], 'b'); // now in sorted order
|
||||
assertEquals(entries[1][0], 'c');
|
||||
|
||||
var a = msg.toArray();
|
||||
|
@ -121,6 +121,8 @@ goog.require('proto.jspb.test.TestAllowAliasEnum');
|
||||
// CommonJS-LoadFromFile: testlargenumbers_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.MessageWithLargeFieldNumbers');
|
||||
|
||||
goog.require('proto.jspb.test.simple1');
|
||||
|
||||
describe('Message test suite', function() {
|
||||
var stubs = new goog.testing.PropertyReplacer();
|
||||
|
||||
@ -185,7 +187,6 @@ describe('Message test suite', function() {
|
||||
$jspbMessageInstance: foo
|
||||
},
|
||||
result);
|
||||
|
||||
});
|
||||
|
||||
it('testMissingFields', function() {
|
||||
@ -209,7 +210,6 @@ describe('Message test suite', function() {
|
||||
aFloatingPointField: undefined,
|
||||
},
|
||||
result);
|
||||
|
||||
});
|
||||
|
||||
it('testNestedComplexMessage', function() {
|
||||
@ -1108,5 +1108,4 @@ describe('Message test suite', function() {
|
||||
message.setAInt(42);
|
||||
assertEquals(42, message.getAInt());
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "google-protobuf",
|
||||
"version": "3.14.0",
|
||||
"version": "3.15.6",
|
||||
"description": "Protocol Buffers for JavaScript",
|
||||
"main": "google-protobuf.js",
|
||||
"files": [
|
||||
|
@ -41,7 +41,7 @@ goog.require('proto.google.protobuf.Any');
|
||||
goog.require('proto.google.protobuf.Timestamp');
|
||||
// CommonJS-LoadFromFile: google/protobuf/struct_pb proto.google.protobuf
|
||||
goog.require('proto.google.protobuf.Struct');
|
||||
|
||||
goog.require('jspb.Message');
|
||||
|
||||
var BYTES = new Uint8Array([1, 2, 8, 9]);
|
||||
var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
|
||||
@ -70,7 +70,6 @@ function bytesCompare(arr, expected) {
|
||||
|
||||
|
||||
describe('proto3Test', function() {
|
||||
|
||||
/**
|
||||
* Test default values don't affect equality test.
|
||||
*/
|
||||
@ -182,8 +181,8 @@ describe('proto3Test', function() {
|
||||
assertEquals(msg.getOptionalBytes_asU8().length, 0);
|
||||
assertEquals(msg.getOptionalBytes_asB64(), '');
|
||||
|
||||
assertEquals(msg.getOptionalForeignEnum(),
|
||||
proto.jspb.test.Proto3Enum.PROTO3_FOO);
|
||||
assertEquals(
|
||||
msg.getOptionalForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_FOO);
|
||||
assertEquals(msg.getOptionalForeignMessage(), undefined);
|
||||
assertEquals(msg.getOptionalForeignMessage(), undefined);
|
||||
|
||||
@ -309,7 +308,8 @@ describe('proto3Test', function() {
|
||||
assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES));
|
||||
assertEquals(msg.getRepeatedForeignMessageList().length, 1);
|
||||
assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000);
|
||||
assertElementsEquals(msg.getRepeatedForeignEnumList(),
|
||||
assertElementsEquals(
|
||||
msg.getRepeatedForeignEnumList(),
|
||||
[proto.jspb.test.Proto3Enum.PROTO3_BAR]);
|
||||
|
||||
assertEquals(msg.getOneofString(), 'asdf');
|
||||
@ -374,7 +374,8 @@ describe('proto3Test', function() {
|
||||
assertEquals(msg.getOneofUint32(), 0);
|
||||
assertEquals(msg.getOneofForeignMessage(), undefined);
|
||||
assertEquals(msg.getOneofString(), '');
|
||||
assertEquals(msg.getOneofBytes_asB64(),
|
||||
assertEquals(
|
||||
msg.getOneofBytes_asB64(),
|
||||
goog.crypt.base64.encodeString('\u00FF\u00FF'));
|
||||
|
||||
assertFalse(msg.hasOneofUint32());
|
||||
@ -454,24 +455,24 @@ describe('proto3Test', function() {
|
||||
|
||||
it('testStructWellKnownType', function() {
|
||||
var jsObj = {
|
||||
abc: "def",
|
||||
abc: 'def',
|
||||
number: 12345.678,
|
||||
nullKey: null,
|
||||
boolKey: true,
|
||||
listKey: [1, null, true, false, "abc"],
|
||||
structKey: {foo: "bar", somenum: 123},
|
||||
complicatedKey: [{xyz: {abc: [3, 4, null, false]}}, "zzz"]
|
||||
listKey: [1, null, true, false, 'abc'],
|
||||
structKey: {foo: 'bar', somenum: 123},
|
||||
complicatedKey: [{xyz: {abc: [3, 4, null, false]}}, 'zzz']
|
||||
};
|
||||
|
||||
var struct = proto.google.protobuf.Struct.fromJavaScript(jsObj);
|
||||
var jsObj2 = struct.toJavaScript();
|
||||
|
||||
assertEquals("def", jsObj2.abc);
|
||||
assertEquals('def', jsObj2.abc);
|
||||
assertEquals(12345.678, jsObj2.number);
|
||||
assertEquals(null, jsObj2.nullKey);
|
||||
assertEquals(true, jsObj2.boolKey);
|
||||
assertEquals("abc", jsObj2.listKey[4]);
|
||||
assertEquals("bar", jsObj2.structKey.foo);
|
||||
assertEquals('abc', jsObj2.listKey[4]);
|
||||
assertEquals('bar', jsObj2.structKey.foo);
|
||||
assertEquals(4, jsObj2.complicatedKey[0].xyz.abc[1]);
|
||||
});
|
||||
});
|
||||
|
@ -3,4 +3,10 @@ Kokoro Infrastructure
|
||||
----------------------
|
||||
|
||||
The files in this directory serve as plumbing for running Protobuf
|
||||
tests under Kokoro, our internal CI.
|
||||
tests under Kokoro, our internal CI.
|
||||
|
||||
We have shared this part of our CI configuration in hopes that it is
|
||||
helpful to contributors who want to better understand the details of
|
||||
our test and release processes. If there are changes, please file an
|
||||
issue; unfortunately, we may not be able to accept PRs (but feel free
|
||||
to send one if it helps to explain the issue).
|
||||
|
@ -16,6 +16,10 @@ until docker pull $DOCKER_IMAGE_NAME; do sleep 10; done
|
||||
docker run -v $(pwd):/var/local/protobuf --rm $DOCKER_IMAGE_NAME \
|
||||
bash -l /var/local/protobuf/tests.sh cpp || FAILED="true"
|
||||
|
||||
# This directory is owned by root. We need to delete it, because otherwise
|
||||
# Kokoro will attempt to rsync it and fail with a permission error.
|
||||
rm -rf src/core
|
||||
|
||||
if [ "$FAILED" = "true" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM debian:stretch
|
||||
FROM debian:buster
|
||||
|
||||
# Install dependencies. We start with the basic ones require to build protoc
|
||||
# and the C++ build
|
||||
@ -22,14 +22,18 @@ RUN apt-get update && apt-get install -y \
|
||||
wget \
|
||||
&& apt-get clean
|
||||
|
||||
# Update ca-certificates to fix known buster + .NET 5 issue
|
||||
# https://github.com/NuGet/Announcements/issues/49
|
||||
RUN apt-get update && apt-get install -y ca-certificates && apt-get clean
|
||||
|
||||
# dotnet SDK prerequisites
|
||||
RUN apt-get update && apt-get install -y libunwind8 libicu57 && apt-get clean
|
||||
RUN apt-get update && apt-get install -y libunwind8 libicu63 && apt-get clean
|
||||
|
||||
# Install dotnet SDK via install script
|
||||
RUN wget -q https://dot.net/v1/dotnet-install.sh && \
|
||||
chmod u+x dotnet-install.sh && \
|
||||
./dotnet-install.sh --version 2.1.802 && \
|
||||
./dotnet-install.sh --version 3.1.301 && \
|
||||
./dotnet-install.sh --version 5.0.102 && \
|
||||
ln -s /root/.dotnet/dotnet /usr/local/bin
|
||||
|
||||
RUN wget -q www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe
|
||||
|
@ -55,6 +55,26 @@ RUN mv composer.phar /usr/local/bin/composer
|
||||
# Download php source code
|
||||
RUN git clone https://github.com/php/php-src
|
||||
|
||||
# php 5.6
|
||||
RUN cd php-src \
|
||||
&& git checkout PHP-5.6.39 \
|
||||
&& ./buildconf --force
|
||||
RUN cd php-src \
|
||||
&& ./configure \
|
||||
--enable-bcmath \
|
||||
--enable-mbstring \
|
||||
--with-gmp \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
--prefix=/usr/local/php-5.6 \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& make clean
|
||||
|
||||
RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
|
||||
&& chmod +x phpunit \
|
||||
&& mv phpunit /usr/local/php-5.6/bin
|
||||
|
||||
# php 7.0
|
||||
RUN cd php-src \
|
||||
&& git checkout PHP-7.0.33 \
|
||||
|
@ -53,6 +53,25 @@ RUN mv composer.phar /usr/local/bin/composer
|
||||
# Download php source code
|
||||
RUN git clone https://github.com/php/php-src
|
||||
|
||||
# php 5.6
|
||||
RUN cd php-src \
|
||||
&& git checkout PHP-5.6.39 \
|
||||
&& ./buildconf --force
|
||||
RUN cd php-src \
|
||||
&& ./configure \
|
||||
--enable-bcmath \
|
||||
--enable-mbstring \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
--prefix=/usr/local/php-5.6 \
|
||||
&& make \
|
||||
&& make install \
|
||||
&& make clean
|
||||
|
||||
RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
|
||||
&& chmod +x phpunit \
|
||||
&& mv phpunit /usr/local/php-5.6/bin
|
||||
|
||||
# php 7.0
|
||||
RUN wget https://github.com/php/php-src/archive/php-7.0.33.tar.gz -O /var/local/php-7.0.33.tar.gz
|
||||
|
||||
|
31
kokoro/linux/dockerfile/test/python39/Dockerfile
Normal file
31
kokoro/linux/dockerfile/test/python39/Dockerfile
Normal file
@ -0,0 +1,31 @@
|
||||
FROM python:3.9-buster
|
||||
|
||||
# Install dependencies. We start with the basic ones require to build protoc
|
||||
# and the C++ build
|
||||
RUN apt-get update && apt-get install -y \
|
||||
autoconf \
|
||||
autotools-dev \
|
||||
build-essential \
|
||||
bzip2 \
|
||||
ccache \
|
||||
curl \
|
||||
gcc \
|
||||
git \
|
||||
libc6 \
|
||||
libc6-dbg \
|
||||
libc6-dev \
|
||||
libgtest-dev \
|
||||
libtool \
|
||||
make \
|
||||
parallel \
|
||||
time \
|
||||
wget \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Python libraries.
|
||||
RUN python -m pip install --no-cache-dir --upgrade \
|
||||
pip \
|
||||
setuptools \
|
||||
tox \
|
||||
wheel
|
@ -10,8 +10,9 @@
|
||||
# Change to repo root
|
||||
cd $(dirname $0)/../../..
|
||||
|
||||
export DOCKERFILE_DIR=kokoro/linux/64-bit
|
||||
export DOCKERHUB_ORGANIZATION=protobuftesting
|
||||
export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python39
|
||||
export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
|
||||
export OUTPUT_DIR=testoutput
|
||||
export TEST_SET="python"
|
||||
export TEST_SET="python39"
|
||||
./kokoro/linux/build_and_run_docker.sh
|
@ -1,7 +1,7 @@
|
||||
# Config file for running tests in Kokoro
|
||||
|
||||
# Location of the build script in repository
|
||||
build_file: "protobuf/kokoro/linux/python/build.sh"
|
||||
build_file: "protobuf/kokoro/linux/python39/build.sh"
|
||||
timeout_mins: 120
|
||||
|
||||
action {
|
@ -1,7 +1,7 @@
|
||||
# Config file for running tests in Kokoro
|
||||
|
||||
# Location of the build script in repository
|
||||
build_file: "protobuf/kokoro/linux/python/build.sh"
|
||||
build_file: "protobuf/kokoro/linux/python39/build.sh"
|
||||
timeout_mins: 120
|
||||
|
||||
action {
|
18
kokoro/linux/python39_cpp/build.sh
Executable file
18
kokoro/linux/python39_cpp/build.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This is the top-level script we give to Kokoro as the entry point for
|
||||
# running the "pull request" project:
|
||||
#
|
||||
# This script selects a specific Dockerfile (for building a Docker image) and
|
||||
# a script to run inside that image. Then we delegate to the general
|
||||
# build_and_run_docker.sh script.
|
||||
|
||||
# Change to repo root
|
||||
cd $(dirname $0)/../../..
|
||||
|
||||
export DOCKERHUB_ORGANIZATION=protobuftesting
|
||||
export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python39
|
||||
export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
|
||||
export OUTPUT_DIR=testoutput
|
||||
export TEST_SET="python39_cpp"
|
||||
./kokoro/linux/build_and_run_docker.sh
|
11
kokoro/linux/python39_cpp/continuous.cfg
Normal file
11
kokoro/linux/python39_cpp/continuous.cfg
Normal file
@ -0,0 +1,11 @@
|
||||
# Config file for running tests in Kokoro
|
||||
|
||||
# Location of the build script in repository
|
||||
build_file: "protobuf/kokoro/linux/python39_cpp/build.sh"
|
||||
timeout_mins: 120
|
||||
|
||||
action {
|
||||
define_artifacts {
|
||||
regex: "**/sponge_log.xml"
|
||||
}
|
||||
}
|
11
kokoro/linux/python39_cpp/presubmit.cfg
Normal file
11
kokoro/linux/python39_cpp/presubmit.cfg
Normal file
@ -0,0 +1,11 @@
|
||||
# Config file for running tests in Kokoro
|
||||
|
||||
# Location of the build script in repository
|
||||
build_file: "protobuf/kokoro/linux/python39_cpp/build.sh"
|
||||
timeout_mins: 120
|
||||
|
||||
action {
|
||||
define_artifacts {
|
||||
regex: "**/sponge_log.xml"
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user