From 860f8ad1718b69777ea665697dee4cfc93eca853 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 28 Apr 2022 12:08:26 -0700 Subject: [PATCH] Remove the JavaScript implementation (#9874) This implementation is about to be split out into a separate Git repo. --- .gitignore | 15 - BUILD | 2 - Makefile.am | 185 +- README.md | 1 - cmake/extract_includes.bat.in | 2 - cmake/libprotoc.cmake | 3 - configure.ac | 2 +- conformance/Makefile.am | 15 +- generate_changelog.py | 4 - js/BUILD | 29 - js/README.md | 161 - js/binary/arith.js | 413 - js/binary/arith_test.js | 354 - js/binary/constants.js | 377 - js/binary/decoder.js | 951 -- js/binary/decoder_test.js | 481 - js/binary/encoder.js | 510 -- js/binary/message_test.js | 60 - js/binary/proto_test.js | 665 -- js/binary/reader.js | 1296 --- js/binary/reader_test.js | 992 --- js/binary/utils.js | 1071 --- js/binary/utils_test.js | 744 -- js/binary/writer.js | 1833 ---- js/binary/writer_test.js | 412 - js/commonjs/export.js | 32 - js/commonjs/export_asserts.js | 39 - js/commonjs/export_testdeps.js | 22 - js/commonjs/import_test.js | 52 - js/commonjs/jasmine.json | 9 - js/commonjs/rewrite_tests_for_commonjs.js | 99 - js/commonjs/strict_test.js | 67 - js/commonjs/test6/test6.proto | 40 - js/commonjs/test7/test7.proto | 42 - .../v3.0.0/binary/arith_test.js | 355 - .../v3.0.0/binary/decoder_test.js | 317 - .../v3.0.0/binary/proto_test.js | 628 -- .../v3.0.0/binary/reader_test.js | 922 -- .../v3.0.0/binary/utils_test.js | 668 -- .../v3.0.0/binary/writer_test.js | 122 - .../v3.0.0/commonjs/export_asserts.js | 37 - .../v3.0.0/commonjs/export_testdeps.js | 18 - .../v3.0.0/commonjs/import_test.js | 52 - .../v3.0.0/commonjs/jasmine.json | 9 - .../commonjs/rewrite_tests_for_commonjs.js | 97 - .../v3.0.0/commonjs/test6/test6.proto | 40 - .../v3.0.0/commonjs/test7/test7.proto | 42 - js/compatibility_tests/v3.0.0/data.proto | 51 - js/compatibility_tests/v3.0.0/debug_test.js | 105 - js/compatibility_tests/v3.0.0/jasmine1.json | 17 - js/compatibility_tests/v3.0.0/jasmine2.json | 17 - js/compatibility_tests/v3.0.0/jasmine3.json | 17 - js/compatibility_tests/v3.0.0/message_test.js | 1081 --- js/compatibility_tests/v3.0.0/proto3_test.js | 329 - .../v3.0.0/proto3_test.proto | 89 - js/compatibility_tests/v3.0.0/test.proto | 236 - js/compatibility_tests/v3.0.0/test.sh | 104 - js/compatibility_tests/v3.0.0/test2.proto | 54 - js/compatibility_tests/v3.0.0/test3.proto | 53 - js/compatibility_tests/v3.0.0/test4.proto | 42 - js/compatibility_tests/v3.0.0/test5.proto | 44 - .../v3.0.0/testbinary.proto | 212 - js/compatibility_tests/v3.0.0/testempty.proto | 34 - .../v3.1.0/binary/arith_test.js | 355 - .../v3.1.0/binary/decoder_test.js | 327 - .../v3.1.0/binary/proto_test.js | 628 -- .../v3.1.0/binary/reader_test.js | 946 -- .../v3.1.0/binary/utils_test.js | 668 -- .../v3.1.0/binary/writer_test.js | 164 - .../v3.1.0/commonjs/test6/test6.proto | 40 - .../v3.1.0/commonjs/test7/test7.proto | 42 - js/compatibility_tests/v3.1.0/data.proto | 51 - js/compatibility_tests/v3.1.0/debug_test.js | 105 - js/compatibility_tests/v3.1.0/maps_test.js | 284 - js/compatibility_tests/v3.1.0/message_test.js | 1060 --- js/compatibility_tests/v3.1.0/proto3_test.js | 329 - .../v3.1.0/proto3_test.proto | 89 - js/compatibility_tests/v3.1.0/test.proto | 262 - js/compatibility_tests/v3.1.0/test2.proto | 54 - js/compatibility_tests/v3.1.0/test3.proto | 53 - js/compatibility_tests/v3.1.0/test4.proto | 42 - js/compatibility_tests/v3.1.0/test5.proto | 44 - .../v3.1.0/testbinary.proto | 212 - js/compatibility_tests/v3.1.0/testempty.proto | 34 - js/data.proto | 50 - js/debug.js | 159 - js/debug_test.js | 188 - .../code_size/apps_jspb/all_types_proto2.js | 312 - .../code_size/apps_jspb/all_types_proto3.js | 312 - .../apps_jspb/popular_types_proto2.js | 53 - .../apps_jspb/popular_types_proto3.js | 53 - .../benchmarks/code_size/code_size_base.js | 57 - .../benchmarks/code_size/kernel/all_types.js | 227 - .../code_size/kernel/popular_types.js | 68 - js/experimental/runtime/bytestring.js | 183 - .../runtime/bytestring_internal.js | 33 - js/experimental/runtime/bytestring_test.js | 277 - js/experimental/runtime/int64.js | 403 - js/experimental/runtime/int64_test.js | 213 - js/experimental/runtime/internal/checks.js | 708 -- .../runtime/internal/checks_test.js | 58 - .../runtime/kernel/binary_storage.js | 130 - .../runtime/kernel/binary_storage_test.js | 165 - .../runtime/kernel/bool_test_pairs.js | 79 - .../runtime/kernel/buffer_decoder.js | 343 - .../runtime/kernel/buffer_decoder_helper.js | 18 - .../runtime/kernel/buffer_decoder_test.js | 242 - .../kernel/conformance/conformance_request.js | 91 - .../conformance/conformance_response.js | 76 - .../kernel/conformance/conformance_testee.js | 103 - .../conformance_testee_runner_node.js | 62 - .../conformance/test_all_types_proto2.js | 309 - .../conformance/test_all_types_proto3.js | 310 - .../runtime/kernel/conformance/wire_format.js | 16 - .../runtime/kernel/double_test_pairs.js | 89 - js/experimental/runtime/kernel/field.js | 196 - .../runtime/kernel/fixed32_test_pairs.js | 36 - .../runtime/kernel/float_test_pairs.js | 78 - js/experimental/runtime/kernel/indexer.js | 55 - .../runtime/kernel/indexer_test.js | 334 - .../runtime/kernel/int32_test_pairs.js | 71 - .../runtime/kernel/int64_test_pairs.js | 59 - .../runtime/kernel/internal_message.js | 24 - js/experimental/runtime/kernel/kernel.js | 4122 --------- .../kernel/kernel_compatibility_test.js | 266 - .../runtime/kernel/kernel_repeated_test.js | 7807 ----------------- js/experimental/runtime/kernel/kernel_test.js | 2329 ----- js/experimental/runtime/kernel/message_set.js | 285 - .../runtime/kernel/message_set_test.js | 262 - .../runtime/kernel/packed_bool_test_pairs.js | 59 - .../kernel/packed_double_test_pairs.js | 52 - .../kernel/packed_fixed32_test_pairs.js | 34 - .../runtime/kernel/packed_float_test_pairs.js | 34 - .../runtime/kernel/packed_int32_test_pairs.js | 33 - .../runtime/kernel/packed_int64_test_pairs.js | 34 - .../kernel/packed_sfixed32_test_pairs.js | 34 - .../kernel/packed_sfixed64_test_pairs.js | 53 - .../kernel/packed_sint32_test_pairs.js | 33 - .../kernel/packed_sint64_test_pairs.js | 34 - .../kernel/packed_uint32_test_pairs.js | 33 - js/experimental/runtime/kernel/reader.js | 364 - js/experimental/runtime/kernel/reader_test.js | 425 - .../runtime/kernel/sfixed32_test_pairs.js | 46 - .../runtime/kernel/sfixed64_test_pairs.js | 52 - .../runtime/kernel/sint32_test_pairs.js | 57 - .../runtime/kernel/sint64_test_pairs.js | 60 - js/experimental/runtime/kernel/storage.js | 67 - js/experimental/runtime/kernel/tag.js | 144 - js/experimental/runtime/kernel/tag_test.js | 221 - .../runtime/kernel/textencoding.js | 116 - .../runtime/kernel/textencoding_test.js | 113 - .../runtime/kernel/typed_arrays.js | 116 - .../runtime/kernel/typed_arrays_test.js | 191 - .../runtime/kernel/uint32_test_pairs.js | 68 - js/experimental/runtime/kernel/uint8arrays.js | 28 - .../runtime/kernel/uint8arrays_test.js | 47 - js/experimental/runtime/kernel/wire_type.js | 17 - js/experimental/runtime/kernel/writer.js | 743 -- js/experimental/runtime/kernel/writer_test.js | 927 -- .../runtime/testing/binary/test_message.js | 1769 ---- .../testing/ensure_custom_equality_test.js | 44 - .../runtime/testing/jasmine_protobuf.js | 88 - js/gulpfile.js | 273 - js/jasmine.json | 17 - js/map.js | 557 -- js/maps_test.js | 439 - js/message.js | 1890 ---- js/message_test.js | 1111 --- js/node_loader.js | 49 - js/package.json | 27 - js/proto3_test.js | 478 - js/proto3_test.proto | 108 - js/test.proto | 322 - js/test10.proto | 39 - js/test11.proto | 52 - js/test12.proto | 119 - js/test13.proto | 70 - js/test14.proto | 43 - js/test15.proto | 39 - js/test2.proto | 60 - js/test3.proto | 53 - js/test4.proto | 42 - js/test5.proto | 44 - js/test8.proto | 50 - js/test9.proto | 39 - js/test_bootstrap.js | 41 - js/testbinary.proto | 294 - js/testempty.proto | 33 - js/testlargenumbers.proto | 40 - ...t_build_and_run_tests_with_qemu_aarch64.sh | 19 - .../linux/aarch64/test_javascript_aarch64.sh | 29 - .../dockerfile/test/javascript/Dockerfile | 37 - kokoro/linux/javascript/build.sh | 18 - kokoro/linux/javascript/continuous.cfg | 11 - kokoro/linux/javascript/presubmit.cfg | 11 - kokoro/linux/javascript_aarch64/build.sh | 16 - .../linux/javascript_aarch64/continuous.cfg | 11 - kokoro/linux/javascript_aarch64/presubmit.cfg | 11 - kokoro/macos/javascript/build.sh | 11 - kokoro/macos/javascript/continuous.cfg | 5 - kokoro/macos/javascript/presubmit.cfg | 5 - pkg/BUILD | 25 - post_process_dist.sh | 2 +- src/Makefile.am | 4 - .../protobuf/compiler/js/js_generator.cc | 3937 --------- .../protobuf/compiler/js/js_generator.h | 336 - .../compiler/js/well_known_types_embed.cc | 270 - .../compiler/js/well_known_types_embed.h | 43 - src/google/protobuf/compiler/main.cc | 6 - tests.sh | 15 +- update_version.py | 9 - 211 files changed, 10 insertions(+), 61158 deletions(-) delete mode 100644 js/BUILD delete mode 100644 js/README.md delete mode 100644 js/binary/arith.js delete mode 100644 js/binary/arith_test.js delete mode 100644 js/binary/constants.js delete mode 100644 js/binary/decoder.js delete mode 100644 js/binary/decoder_test.js delete mode 100644 js/binary/encoder.js delete mode 100644 js/binary/message_test.js delete mode 100644 js/binary/proto_test.js delete mode 100644 js/binary/reader.js delete mode 100644 js/binary/reader_test.js delete mode 100644 js/binary/utils.js delete mode 100644 js/binary/utils_test.js delete mode 100644 js/binary/writer.js delete mode 100644 js/binary/writer_test.js delete mode 100644 js/commonjs/export.js delete mode 100644 js/commonjs/export_asserts.js delete mode 100644 js/commonjs/export_testdeps.js delete mode 100644 js/commonjs/import_test.js delete mode 100644 js/commonjs/jasmine.json delete mode 100644 js/commonjs/rewrite_tests_for_commonjs.js delete mode 100644 js/commonjs/strict_test.js delete mode 100644 js/commonjs/test6/test6.proto delete mode 100644 js/commonjs/test7/test7.proto delete mode 100644 js/compatibility_tests/v3.0.0/binary/arith_test.js delete mode 100644 js/compatibility_tests/v3.0.0/binary/decoder_test.js delete mode 100644 js/compatibility_tests/v3.0.0/binary/proto_test.js delete mode 100644 js/compatibility_tests/v3.0.0/binary/reader_test.js delete mode 100644 js/compatibility_tests/v3.0.0/binary/utils_test.js delete mode 100644 js/compatibility_tests/v3.0.0/binary/writer_test.js delete mode 100644 js/compatibility_tests/v3.0.0/commonjs/export_asserts.js delete mode 100644 js/compatibility_tests/v3.0.0/commonjs/export_testdeps.js delete mode 100644 js/compatibility_tests/v3.0.0/commonjs/import_test.js delete mode 100644 js/compatibility_tests/v3.0.0/commonjs/jasmine.json delete mode 100644 js/compatibility_tests/v3.0.0/commonjs/rewrite_tests_for_commonjs.js delete mode 100644 js/compatibility_tests/v3.0.0/commonjs/test6/test6.proto delete mode 100644 js/compatibility_tests/v3.0.0/commonjs/test7/test7.proto delete mode 100644 js/compatibility_tests/v3.0.0/data.proto delete mode 100644 js/compatibility_tests/v3.0.0/debug_test.js delete mode 100644 js/compatibility_tests/v3.0.0/jasmine1.json delete mode 100644 js/compatibility_tests/v3.0.0/jasmine2.json delete mode 100644 js/compatibility_tests/v3.0.0/jasmine3.json delete mode 100644 js/compatibility_tests/v3.0.0/message_test.js delete mode 100644 js/compatibility_tests/v3.0.0/proto3_test.js delete mode 100644 js/compatibility_tests/v3.0.0/proto3_test.proto delete mode 100644 js/compatibility_tests/v3.0.0/test.proto delete mode 100755 js/compatibility_tests/v3.0.0/test.sh delete mode 100644 js/compatibility_tests/v3.0.0/test2.proto delete mode 100644 js/compatibility_tests/v3.0.0/test3.proto delete mode 100644 js/compatibility_tests/v3.0.0/test4.proto delete mode 100644 js/compatibility_tests/v3.0.0/test5.proto delete mode 100644 js/compatibility_tests/v3.0.0/testbinary.proto delete mode 100644 js/compatibility_tests/v3.0.0/testempty.proto delete mode 100644 js/compatibility_tests/v3.1.0/binary/arith_test.js delete mode 100644 js/compatibility_tests/v3.1.0/binary/decoder_test.js delete mode 100644 js/compatibility_tests/v3.1.0/binary/proto_test.js delete mode 100644 js/compatibility_tests/v3.1.0/binary/reader_test.js delete mode 100644 js/compatibility_tests/v3.1.0/binary/utils_test.js delete mode 100644 js/compatibility_tests/v3.1.0/binary/writer_test.js delete mode 100644 js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto delete mode 100644 js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto delete mode 100644 js/compatibility_tests/v3.1.0/data.proto delete mode 100644 js/compatibility_tests/v3.1.0/debug_test.js delete mode 100644 js/compatibility_tests/v3.1.0/maps_test.js delete mode 100644 js/compatibility_tests/v3.1.0/message_test.js delete mode 100644 js/compatibility_tests/v3.1.0/proto3_test.js delete mode 100644 js/compatibility_tests/v3.1.0/proto3_test.proto delete mode 100644 js/compatibility_tests/v3.1.0/test.proto delete mode 100644 js/compatibility_tests/v3.1.0/test2.proto delete mode 100644 js/compatibility_tests/v3.1.0/test3.proto delete mode 100644 js/compatibility_tests/v3.1.0/test4.proto delete mode 100644 js/compatibility_tests/v3.1.0/test5.proto delete mode 100644 js/compatibility_tests/v3.1.0/testbinary.proto delete mode 100644 js/compatibility_tests/v3.1.0/testempty.proto delete mode 100644 js/data.proto delete mode 100644 js/debug.js delete mode 100644 js/debug_test.js delete mode 100644 js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js delete mode 100644 js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js delete mode 100644 js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js delete mode 100644 js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js delete mode 100644 js/experimental/benchmarks/code_size/code_size_base.js delete mode 100644 js/experimental/benchmarks/code_size/kernel/all_types.js delete mode 100644 js/experimental/benchmarks/code_size/kernel/popular_types.js delete mode 100644 js/experimental/runtime/bytestring.js delete mode 100644 js/experimental/runtime/bytestring_internal.js delete mode 100644 js/experimental/runtime/bytestring_test.js delete mode 100644 js/experimental/runtime/int64.js delete mode 100644 js/experimental/runtime/int64_test.js delete mode 100644 js/experimental/runtime/internal/checks.js delete mode 100644 js/experimental/runtime/internal/checks_test.js delete mode 100644 js/experimental/runtime/kernel/binary_storage.js delete mode 100644 js/experimental/runtime/kernel/binary_storage_test.js delete mode 100644 js/experimental/runtime/kernel/bool_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/buffer_decoder.js delete mode 100644 js/experimental/runtime/kernel/buffer_decoder_helper.js delete mode 100644 js/experimental/runtime/kernel/buffer_decoder_test.js delete mode 100644 js/experimental/runtime/kernel/conformance/conformance_request.js delete mode 100644 js/experimental/runtime/kernel/conformance/conformance_response.js delete mode 100755 js/experimental/runtime/kernel/conformance/conformance_testee.js delete mode 100755 js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js delete mode 100644 js/experimental/runtime/kernel/conformance/test_all_types_proto2.js delete mode 100644 js/experimental/runtime/kernel/conformance/test_all_types_proto3.js delete mode 100644 js/experimental/runtime/kernel/conformance/wire_format.js delete mode 100644 js/experimental/runtime/kernel/double_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/field.js delete mode 100644 js/experimental/runtime/kernel/fixed32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/float_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/indexer.js delete mode 100644 js/experimental/runtime/kernel/indexer_test.js delete mode 100644 js/experimental/runtime/kernel/int32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/int64_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/internal_message.js delete mode 100644 js/experimental/runtime/kernel/kernel.js delete mode 100644 js/experimental/runtime/kernel/kernel_compatibility_test.js delete mode 100644 js/experimental/runtime/kernel/kernel_repeated_test.js delete mode 100644 js/experimental/runtime/kernel/kernel_test.js delete mode 100644 js/experimental/runtime/kernel/message_set.js delete mode 100644 js/experimental/runtime/kernel/message_set_test.js delete mode 100644 js/experimental/runtime/kernel/packed_bool_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_double_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_fixed32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_float_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_int32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_int64_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_sint32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_sint64_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/packed_uint32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/reader.js delete mode 100644 js/experimental/runtime/kernel/reader_test.js delete mode 100644 js/experimental/runtime/kernel/sfixed32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/sfixed64_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/sint32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/sint64_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/storage.js delete mode 100644 js/experimental/runtime/kernel/tag.js delete mode 100644 js/experimental/runtime/kernel/tag_test.js delete mode 100644 js/experimental/runtime/kernel/textencoding.js delete mode 100644 js/experimental/runtime/kernel/textencoding_test.js delete mode 100644 js/experimental/runtime/kernel/typed_arrays.js delete mode 100644 js/experimental/runtime/kernel/typed_arrays_test.js delete mode 100644 js/experimental/runtime/kernel/uint32_test_pairs.js delete mode 100644 js/experimental/runtime/kernel/uint8arrays.js delete mode 100644 js/experimental/runtime/kernel/uint8arrays_test.js delete mode 100644 js/experimental/runtime/kernel/wire_type.js delete mode 100644 js/experimental/runtime/kernel/writer.js delete mode 100644 js/experimental/runtime/kernel/writer_test.js delete mode 100644 js/experimental/runtime/testing/binary/test_message.js delete mode 100644 js/experimental/runtime/testing/ensure_custom_equality_test.js delete mode 100644 js/experimental/runtime/testing/jasmine_protobuf.js delete mode 100644 js/gulpfile.js delete mode 100644 js/jasmine.json delete mode 100644 js/map.js delete mode 100644 js/maps_test.js delete mode 100644 js/message.js delete mode 100644 js/message_test.js delete mode 100644 js/node_loader.js delete mode 100644 js/package.json delete mode 100644 js/proto3_test.js delete mode 100644 js/proto3_test.proto delete mode 100644 js/test.proto delete mode 100644 js/test10.proto delete mode 100644 js/test11.proto delete mode 100644 js/test12.proto delete mode 100644 js/test13.proto delete mode 100644 js/test14.proto delete mode 100644 js/test15.proto delete mode 100644 js/test2.proto delete mode 100644 js/test3.proto delete mode 100644 js/test4.proto delete mode 100644 js/test5.proto delete mode 100644 js/test8.proto delete mode 100644 js/test9.proto delete mode 100644 js/test_bootstrap.js delete mode 100644 js/testbinary.proto delete mode 100644 js/testempty.proto delete mode 100644 js/testlargenumbers.proto delete mode 100755 kokoro/linux/aarch64/javascript_build_and_run_tests_with_qemu_aarch64.sh delete mode 100755 kokoro/linux/aarch64/test_javascript_aarch64.sh delete mode 100644 kokoro/linux/dockerfile/test/javascript/Dockerfile delete mode 100755 kokoro/linux/javascript/build.sh delete mode 100644 kokoro/linux/javascript/continuous.cfg delete mode 100644 kokoro/linux/javascript/presubmit.cfg delete mode 100755 kokoro/linux/javascript_aarch64/build.sh delete mode 100644 kokoro/linux/javascript_aarch64/continuous.cfg delete mode 100644 kokoro/linux/javascript_aarch64/presubmit.cfg delete mode 100755 kokoro/macos/javascript/build.sh delete mode 100644 kokoro/macos/javascript/continuous.cfg delete mode 100644 kokoro/macos/javascript/presubmit.cfg delete mode 100644 src/google/protobuf/compiler/js/js_generator.cc delete mode 100644 src/google/protobuf/compiler/js/js_generator.h delete mode 100644 src/google/protobuf/compiler/js/well_known_types_embed.cc delete mode 100644 src/google/protobuf/compiler/js/well_known_types_embed.h diff --git a/.gitignore b/.gitignore index 8b764964d..62de6f1bf 100644 --- a/.gitignore +++ b/.gitignore @@ -168,21 +168,6 @@ php/ext/google/protobuf/run-tests.php php/ext/google/protobuf/third_party/ vendor/ -# JavaScript artifacts -js/commonjs_out/ -js/compatibility_tests/v3.0.0/commonjs_out* -js/compatibility_tests/v3.0.0/protoc -js/compatibility_tests/v3.0.0/testproto_libs1.js -js/compatibility_tests/v3.0.0/testproto_libs1_new.js -js/compatibility_tests/v3.0.0/testproto_libs2.js -js/compatibility_tests/v3.0.0/testproto_libs2_new.js -js/deps.js -js/google-protobuf.js -js/google/ -js/node_modules/ -js/testproto_libs1.js -js/testproto_libs2.js - # Ignore the bazel symlinks /bazel-* diff --git a/BUILD b/BUILD index 83ba24011..c63992777 100644 --- a/BUILD +++ b/BUILD @@ -485,8 +485,6 @@ cc_library( "src/google/protobuf/compiler/java/shared_code_generator.cc", "src/google/protobuf/compiler/java/string_field.cc", "src/google/protobuf/compiler/java/string_field_lite.cc", - "src/google/protobuf/compiler/js/js_generator.cc", - "src/google/protobuf/compiler/js/well_known_types_embed.cc", "src/google/protobuf/compiler/objectivec/objectivec_enum.cc", "src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc", "src/google/protobuf/compiler/objectivec/objectivec_extension.cc", diff --git a/Makefile.am b/Makefile.am index ea8ff17a5..6c1bf316c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1218,189 +1218,7 @@ ruby_EXTRA_DIST= \ ruby/tests/type_errors.rb \ ruby/travis-test.sh -# Note: please keep this in sync with the dist_files rule in js/BUILD. -js_EXTRA_DIST= \ - js/README.md \ - js/binary/arith.js \ - js/binary/arith_test.js \ - js/binary/constants.js \ - js/binary/decoder.js \ - js/binary/decoder_test.js \ - js/binary/encoder.js \ - js/binary/message_test.js \ - js/binary/proto_test.js \ - js/binary/reader.js \ - js/binary/reader_test.js \ - js/binary/utils.js \ - js/binary/utils_test.js \ - js/binary/writer.js \ - js/binary/writer_test.js \ - js/commonjs/export.js \ - js/commonjs/export_asserts.js \ - js/commonjs/export_testdeps.js \ - js/commonjs/import_test.js \ - js/commonjs/jasmine.json \ - js/commonjs/rewrite_tests_for_commonjs.js \ - js/commonjs/strict_test.js \ - js/commonjs/test6/test6.proto \ - js/commonjs/test7/test7.proto \ - js/compatibility_tests/v3.0.0/binary/arith_test.js \ - js/compatibility_tests/v3.0.0/binary/decoder_test.js \ - js/compatibility_tests/v3.0.0/binary/proto_test.js \ - js/compatibility_tests/v3.0.0/binary/reader_test.js \ - js/compatibility_tests/v3.0.0/binary/utils_test.js \ - js/compatibility_tests/v3.0.0/binary/writer_test.js \ - js/compatibility_tests/v3.0.0/commonjs/export_asserts.js \ - js/compatibility_tests/v3.0.0/commonjs/export_testdeps.js \ - js/compatibility_tests/v3.0.0/commonjs/import_test.js \ - js/compatibility_tests/v3.0.0/commonjs/jasmine.json \ - js/compatibility_tests/v3.0.0/commonjs/rewrite_tests_for_commonjs.js \ - js/compatibility_tests/v3.0.0/commonjs/test6/test6.proto \ - js/compatibility_tests/v3.0.0/commonjs/test7/test7.proto \ - js/compatibility_tests/v3.0.0/data.proto \ - js/compatibility_tests/v3.0.0/debug_test.js \ - js/compatibility_tests/v3.0.0/jasmine1.json \ - js/compatibility_tests/v3.0.0/jasmine2.json \ - js/compatibility_tests/v3.0.0/jasmine3.json \ - js/compatibility_tests/v3.0.0/message_test.js \ - js/compatibility_tests/v3.0.0/proto3_test.js \ - js/compatibility_tests/v3.0.0/proto3_test.proto \ - js/compatibility_tests/v3.0.0/test2.proto \ - js/compatibility_tests/v3.0.0/test3.proto \ - js/compatibility_tests/v3.0.0/test4.proto \ - js/compatibility_tests/v3.0.0/test5.proto \ - js/compatibility_tests/v3.0.0/testbinary.proto \ - js/compatibility_tests/v3.0.0/testempty.proto \ - js/compatibility_tests/v3.0.0/test.proto \ - js/compatibility_tests/v3.0.0/test.sh \ - js/compatibility_tests/v3.1.0/testempty.proto \ - js/compatibility_tests/v3.1.0/testbinary.proto \ - js/compatibility_tests/v3.1.0/test5.proto \ - js/compatibility_tests/v3.1.0/test4.proto \ - js/compatibility_tests/v3.1.0/test3.proto \ - js/compatibility_tests/v3.1.0/test2.proto \ - js/compatibility_tests/v3.1.0/test.proto \ - js/compatibility_tests/v3.1.0/proto3_test.proto \ - js/compatibility_tests/v3.1.0/proto3_test.js \ - js/compatibility_tests/v3.1.0/message_test.js \ - js/compatibility_tests/v3.1.0/maps_test.js \ - js/compatibility_tests/v3.1.0/debug_test.js \ - js/compatibility_tests/v3.1.0/data.proto \ - js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto \ - js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto \ - js/compatibility_tests/v3.1.0/binary/writer_test.js \ - js/compatibility_tests/v3.1.0/binary/utils_test.js \ - js/compatibility_tests/v3.1.0/binary/reader_test.js \ - js/compatibility_tests/v3.1.0/binary/proto_test.js \ - js/compatibility_tests/v3.1.0/binary/decoder_test.js \ - js/compatibility_tests/v3.1.0/binary/arith_test.js \ - js/data.proto \ - js/debug.js \ - js/debug_test.js \ - js/experimental/runtime/kernel/message_set.js \ - js/experimental/runtime/kernel/message_set_test.js \ - js/experimental/runtime/kernel/tag.js \ - js/experimental/runtime/kernel/tag_test.js \ - js/gulpfile.js \ - js/jasmine.json \ - js/map.js \ - js/maps_test.js \ - js/message.js \ - js/message_test.js \ - js/node_loader.js \ - js/package.json \ - js/proto3_test.js \ - js/proto3_test.proto \ - js/test.proto \ - js/test2.proto \ - js/test3.proto \ - js/test4.proto \ - js/test5.proto \ - js/test8.proto \ - js/test9.proto \ - js/test10.proto \ - js/test11.proto \ - js/test12.proto \ - js/test13.proto \ - js/test14.proto \ - js/test15.proto \ - js/test_bootstrap.js \ - js/testbinary.proto \ - js/testempty.proto \ - js/testlargenumbers.proto \ - js/experimental/runtime/testing/jasmine_protobuf.js \ - js/experimental/runtime/testing/ensure_custom_equality_test.js \ - js/experimental/runtime/testing/binary/test_message.js \ - js/experimental/runtime/kernel/writer_test.js \ - js/experimental/runtime/kernel/writer.js \ - js/experimental/runtime/kernel/wire_type.js \ - js/experimental/runtime/kernel/uint8arrays_test.js \ - js/experimental/runtime/kernel/uint8arrays.js \ - js/experimental/runtime/kernel/uint32_test_pairs.js \ - js/experimental/runtime/kernel/typed_arrays_test.js \ - js/experimental/runtime/kernel/typed_arrays.js \ - js/experimental/runtime/kernel/textencoding_test.js \ - js/experimental/runtime/kernel/textencoding.js \ - js/experimental/runtime/kernel/storage.js \ - js/experimental/runtime/kernel/sint64_test_pairs.js \ - js/experimental/runtime/kernel/sint32_test_pairs.js \ - js/experimental/runtime/kernel/sfixed64_test_pairs.js \ - js/experimental/runtime/kernel/sfixed32_test_pairs.js \ - js/experimental/runtime/kernel/reader_test.js \ - js/experimental/runtime/kernel/reader.js \ - js/experimental/runtime/kernel/packed_uint32_test_pairs.js \ - js/experimental/runtime/kernel/packed_sint64_test_pairs.js \ - js/experimental/runtime/kernel/packed_sint32_test_pairs.js \ - js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js \ - js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js \ - js/experimental/runtime/kernel/packed_int64_test_pairs.js \ - js/experimental/runtime/kernel/packed_int32_test_pairs.js \ - js/experimental/runtime/kernel/packed_float_test_pairs.js \ - js/experimental/runtime/kernel/packed_fixed32_test_pairs.js \ - js/experimental/runtime/kernel/packed_double_test_pairs.js \ - js/experimental/runtime/kernel/packed_bool_test_pairs.js \ - js/experimental/runtime/kernel/kernel_test.js \ - js/experimental/runtime/kernel/kernel_repeated_test.js \ - js/experimental/runtime/kernel/kernel_compatibility_test.js \ - js/experimental/runtime/kernel/kernel.js \ - js/experimental/runtime/kernel/internal_message.js \ - js/experimental/runtime/kernel/int64_test_pairs.js \ - js/experimental/runtime/kernel/int32_test_pairs.js \ - js/experimental/runtime/kernel/indexer_test.js \ - js/experimental/runtime/kernel/indexer.js \ - js/experimental/runtime/kernel/float_test_pairs.js \ - js/experimental/runtime/kernel/fixed32_test_pairs.js \ - js/experimental/runtime/kernel/field.js \ - js/experimental/runtime/kernel/double_test_pairs.js \ - js/experimental/runtime/kernel/conformance/wire_format.js \ - js/experimental/runtime/kernel/conformance/test_all_types_proto3.js \ - js/experimental/runtime/kernel/conformance/test_all_types_proto2.js \ - js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js \ - js/experimental/runtime/kernel/conformance/conformance_testee.js \ - js/experimental/runtime/kernel/conformance/conformance_response.js \ - js/experimental/runtime/kernel/conformance/conformance_request.js \ - js/experimental/runtime/kernel/buffer_decoder_test.js \ - js/experimental/runtime/kernel/buffer_decoder_helper.js \ - js/experimental/runtime/kernel/buffer_decoder.js \ - js/experimental/runtime/kernel/bool_test_pairs.js \ - js/experimental/runtime/kernel/binary_storage_test.js \ - js/experimental/runtime/kernel/binary_storage.js \ - js/experimental/runtime/internal/checks_test.js \ - js/experimental/runtime/internal/checks.js \ - js/experimental/runtime/int64_test.js \ - js/experimental/runtime/int64.js \ - js/experimental/runtime/bytestring_test.js \ - js/experimental/runtime/bytestring_internal.js \ - js/experimental/runtime/bytestring.js \ - js/experimental/benchmarks/code_size/kernel/popular_types.js \ - js/experimental/benchmarks/code_size/kernel/all_types.js \ - js/experimental/benchmarks/code_size/code_size_base.js \ - js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js \ - js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js \ - js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js \ - js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js - -all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) $(js_EXTRA_DIST) +all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) # Note: please keep this in sync with the common_dist_files rule in BUILD. EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ @@ -1462,7 +1280,6 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ examples/list_people.py \ examples/pubspec.yaml \ internal.bzl \ - js/BUILD \ maven_install.json \ php/BUILD \ protobuf.bzl \ diff --git a/README.md b/README.md index fe3430b92..c2e6575f9 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,6 @@ how to install protobuf runtime for that specific language: | Python | [python](python) | | Objective-C | [objectivec](objectivec) | | C# | [csharp](csharp) | -| JavaScript | [js](js) | | Ruby | [ruby](ruby) | | Go | [protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go)| | PHP | [php](php) | diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index 41d4556f7..83058f3e1 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -5,7 +5,6 @@ mkdir include\google\protobuf\compiler mkdir include\google\protobuf\compiler\cpp mkdir include\google\protobuf\compiler\csharp mkdir include\google\protobuf\compiler\java -mkdir include\google\protobuf\compiler\js mkdir include\google\protobuf\compiler\objectivec mkdir include\google\protobuf\compiler\php mkdir include\google\protobuf\compiler\python @@ -34,7 +33,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h" copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\generator.h" include\google\protobuf\compiler\java\generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\kotlin_generator.h" include\google\protobuf\compiler\java\kotlin_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\names.h" include\google\protobuf\compiler\java\names.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\js\js_generator.h" include\google\protobuf\compiler\js\js_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_generator.h" include\google\protobuf\compiler\objectivec\objectivec_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_helpers.h" include\google\protobuf\compiler\objectivec\objectivec_helpers.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\parser.h" include\google\protobuf\compiler\parser.h diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index b098b9492..625d65d54 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -61,8 +61,6 @@ set(libprotoc_files ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/shared_code_generator.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/string_field_lite.cc - ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/js/js_generator.cc - ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/js/well_known_types_embed.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_extension.cc @@ -100,7 +98,6 @@ set(libprotoc_headers ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/kotlin_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/names.h - ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/js/js_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/objectivec_helpers.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/php_generator.h diff --git a/configure.ac b/configure.ac index 7c5c2c799..d5b1f707b 100644 --- a/configure.ac +++ b/configure.ac @@ -31,7 +31,7 @@ AC_CONFIG_MACRO_DIR([m4]) AC_ARG_VAR(DIST_LANG, [language to include in the distribution package (i.e., make dist)]) case "$DIST_LANG" in "") DIST_LANG=all ;; - all | cpp | csharp | java | python | javanano | objectivec | ruby | js | php) ;; + all | cpp | csharp | java | python | javanano | objectivec | ruby | php) ;; *) AC_MSG_FAILURE([unknown language: $DIST_LANG]) ;; esac AC_SUBST(DIST_LANG) diff --git a/conformance/Makefile.am b/conformance/Makefile.am index 940c0a266..415412bca 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -260,9 +260,9 @@ if USE_EXTERNAL_PROTOC # Some implementations include pre-generated versions of well-known types. protoc_middleman: $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf - $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. --js_out=import_style=commonjs,binary:. $(conformance_protoc_inputs) - $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --js_out=import_style=commonjs,binary:. $(conformance_proto2_protoc_inputs) - $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. --js_out=import_style=commonjs,binary:google-protobuf $(well_known_type_protoc_inputs) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. $(conformance_protoc_inputs) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. $(conformance_proto2_protoc_inputs) + $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. $(well_known_type_protoc_inputs) ## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) touch protoc_middleman @@ -272,9 +272,9 @@ else # relative to srcdir, which may not be the same as the current directory when # building out-of-tree. protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf - oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_protoc_inputs) ) - oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd $(conformance_proto2_protoc_inputs) ) - oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd/google-protobuf $(well_known_type_protoc_inputs) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd $(conformance_protoc_inputs) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(conformance_proto2_protoc_inputs) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd $(well_known_type_protoc_inputs) ) ## @mkdir -p lite ## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) ) touch protoc_middleman @@ -364,9 +364,6 @@ test_python: protoc_middleman conformance-test-runner test_python_cpp: protoc_middleman conformance-test-runner ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py -test_nodejs: protoc_middleman conformance-test-runner $(other_language_protoc_outputs) - NODE_PATH=../js:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_js.txt ./conformance_nodejs.js - if OBJC_CONFORMANCE_TEST test_objc: protoc_middleman conformance-test-runner conformance-objc diff --git a/generate_changelog.py b/generate_changelog.py index 60803c59d..fe7e95bc4 100755 --- a/generate_changelog.py +++ b/generate_changelog.py @@ -26,10 +26,6 @@ languages = [ "python", "src/google/protobuf/compiler/python", ]), - Language("JavaScript", [ - "js", - "src/google/protobuf/compiler/js", - ]), Language("PHP", [ "php", "src/google/protobuf/compiler/php", diff --git a/js/BUILD b/js/BUILD deleted file mode 100644 index baa93be9c..000000000 --- a/js/BUILD +++ /dev/null @@ -1,29 +0,0 @@ -# Protobuf JS runtime -# -# See also code generation logic under /src/google/protobuf/compiler/js. - -load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") - -pkg_files( - name = "dist_files", - srcs = glob([ - "*.js", - "*.json", - "*.proto", - "binary/*.js", - "commonjs/*.js*", # js, json - "commonjs/**/*.proto", - "compatibility_tests/v3.0.0/**/*.js*", - "compatibility_tests/v3.0.0/**/*.proto", - "compatibility_tests/v3.0.0/**/*.sh", - "compatibility_tests/v3.1.0/**/*.js*", - "compatibility_tests/v3.1.0/**/*.proto", - "experimental/benchmarks/**/*.js", - "experimental/runtime/**/*.js", - ]) + [ - "BUILD", - "README.md", - ], - strip_prefix = strip_prefix.from_root(""), - visibility = ["//pkg:__pkg__"], -) diff --git a/js/README.md b/js/README.md deleted file mode 100644 index f700237b3..000000000 --- a/js/README.md +++ /dev/null @@ -1,161 +0,0 @@ -Protocol Buffers - Google's data interchange format -=================================================== - -Copyright 2008 Google Inc. - -This directory contains the JavaScript Protocol Buffers runtime library. - -The library is currently compatible with: - -1. CommonJS-style imports (eg. `var protos = require('my-protos');`) -2. Closure-style imports (eg. `goog.require('my.package.MyProto');`) - -Support for ES6-style imports is not implemented yet. Browsers can -be supported by using Browserify, webpack, Closure Compiler, etc. to -resolve imports at compile time. - -To use Protocol Buffers with JavaScript, you need two main components: - -1. The protobuf runtime library. You can install this with - `npm install google-protobuf`, or use the files in this directory. - If npm is not being used, as of 3.3.0, the files needed are located in binary subdirectory; - arith.js, constants.js, decoder.js, encoder.js, map.js, message.js, reader.js, utils.js, writer.js -2. The Protocol Compiler `protoc`. This translates `.proto` files - into `.js` files. The compiler is not currently available via - npm, but you can download a pre-built binary - [on GitHub](https://github.com/protocolbuffers/protobuf/releases) - (look for the `protoc-*.zip` files under **Downloads**). - - -Setup -===== - -First, obtain the Protocol Compiler. The easiest way is to download -a pre-built binary from [https://github.com/protocolbuffers/protobuf/releases](https://github.com/protocolbuffers/protobuf/releases). - -If you want, you can compile `protoc` from source instead. To do this -follow the instructions in [the top-level -README](https://github.com/protocolbuffers/protobuf/blob/main/src/README.md). - -Once you have `protoc` compiled, you can run the tests provided along with our project to examine whether it can run successfully. In order to do this, you should download the Protocol Buffer source code from the release page with the link above. Then extract the source code and navigate to the folder named `js` containing a `package.json` file and a series of test files. In this folder, you can run the commands below to run the tests automatically. - - $ npm install - $ npm test - - # If your protoc is somewhere else than ../src/protoc, instead do this. - # But make sure your protoc is the same version as this (or compatible)! - $ PROTOC=/usr/local/bin/protoc npm test - -This will run two separate copies of the tests: one that uses -Closure Compiler style imports and one that uses CommonJS imports. -You can see all the CommonJS files in `commonjs_out/`. -If all of these tests pass, you know you have a working setup. - - -Using Protocol Buffers in your own project -========================================== - -To use Protocol Buffers in your own project, you need to integrate -the Protocol Compiler into your build system. The details are a -little different depending on whether you are using Closure imports -or CommonJS imports: - -Closure Imports ---------------- - -If you want to use Closure imports, your build should run a command -like this: - - $ protoc --js_out=library=myproto_libs,binary:. messages.proto base.proto - -For Closure imports, `protoc` will generate a single output file -(`myproto_libs.js` in this example). The generated file will `goog.provide()` -all of the types defined in your .proto files. For example, for the unit -tests the generated files contain many `goog.provide` statements like: - - goog.provide('proto.google.protobuf.DescriptorProto'); - goog.provide('proto.google.protobuf.DescriptorProto.ExtensionRange'); - goog.provide('proto.google.protobuf.DescriptorProto.ReservedRange'); - goog.provide('proto.google.protobuf.EnumDescriptorProto'); - goog.provide('proto.google.protobuf.EnumOptions'); - -The generated code will also `goog.require()` many types in the core library, -and they will require many types in the Google Closure library. So make sure -that your `goog.provide()` / `goog.require()` setup can find all of your -generated code, the core library `.js` files in this directory, and the -Google Closure library itself. - -Once you've done this, you should be able to import your types with -statements like: - - goog.require('proto.my.package.MyMessage'); - - var message = proto.my.package.MyMessage(); - -If unfamiliar with Closure or its compiler, consider reviewing -[Closure documentation](https://developers.google.com/closure/library). - -CommonJS imports ----------------- - -If you want to use CommonJS imports, your build should run a command -like this: - - $ protoc --js_out=import_style=commonjs,binary:. messages.proto base.proto - -For CommonJS imports, `protoc` will spit out one file per input file -(so `messages_pb.js` and `base_pb.js` in this example). The generated -code will depend on the core runtime, which should be in a file called -`google-protobuf.js`. If you are installing from `npm`, this file should -already be built and available. If you are running from GitHub, you need -to build it first by running: - - $ gulp dist - -Once you've done this, you should be able to import your types with -statements like: - - var messages = require('./messages_pb'); - - var message = new messages.MyMessage(); - -The `--js_out` flag -------------------- - -The syntax of the `--js_out` flag is: - - --js_out=[OPTIONS:]output_dir - -Where `OPTIONS` are separated by commas. Options are either `opt=val` or -just `opt` (for options that don't take a value). The available options -are specified and documented in the `GeneratorOptions` struct in -[src/google/protobuf/compiler/js/js_generator.h](https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/compiler/js/js_generator.h#L53). - -Some examples: - -- `--js_out=library=myprotos_lib.js,binary:.`: this contains the options - `library=myprotos.lib.js` and `binary` and outputs to the current directory. - The `import_style` option is left to the default, which is `closure`. -- `--js_out=import_style=commonjs,binary:protos`: this contains the options - `import_style=commonjs` and `binary` and outputs to the directory `protos`. - `import_style=commonjs_strict` doesn't expose the output on the global scope. - -API -=== - -The API is not well-documented yet. Here is a quick example to give you an -idea of how the library generally works: - - var message = new MyMessage(); - - message.setName("John Doe"); - message.setAge(25); - message.setPhoneNumbers(["800-555-1212", "800-555-0000"]); - - // Serializes to a UInt8Array. - var bytes = message.serializeBinary(); - - var message2 = MyMessage.deserializeBinary(bytes); - -For more examples, see the tests. You can also look at the generated code -to see what methods are defined for your generated messages. diff --git a/js/binary/arith.js b/js/binary/arith.js deleted file mode 100644 index 62528a263..000000000 --- a/js/binary/arith.js +++ /dev/null @@ -1,413 +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. - -/** - * @fileoverview This file contains helper code used by jspb.utils to - * handle 64-bit integer conversion to/from strings. - * - * @author cfallin@google.com (Chris Fallin) - * - * TODO(haberman): move this to javascript/closure/math? - */ - -goog.provide('jspb.arith.Int64'); -goog.provide('jspb.arith.UInt64'); - -/** - * UInt64 implements some 64-bit arithmetic routines necessary for properly - * handling 64-bit integer fields. It implements lossless integer arithmetic on - * top of JavaScript's number type, which has only 53 bits of precision, by - * representing 64-bit integers as two 32-bit halves. - * - * @param {number} lo The low 32 bits. - * @param {number} hi The high 32 bits. - * @constructor - */ -jspb.arith.UInt64 = function(lo, hi) { - /** - * The low 32 bits. - * @public {number} - */ - this.lo = lo; - /** - * The high 32 bits. - * @public {number} - */ - this.hi = hi; -}; - - -/** - * Compare two 64-bit numbers. Returns -1 if the first is - * less, +1 if the first is greater, or 0 if both are equal. - * @param {!jspb.arith.UInt64} other - * @return {number} - */ -jspb.arith.UInt64.prototype.cmp = function(other) { - if (this.hi < other.hi || (this.hi == other.hi && this.lo < other.lo)) { - return -1; - } else if (this.hi == other.hi && this.lo == other.lo) { - return 0; - } else { - return 1; - } -}; - - -/** - * Right-shift this number by one bit. - * @return {!jspb.arith.UInt64} - */ -jspb.arith.UInt64.prototype.rightShift = function() { - var hi = this.hi >>> 1; - var lo = (this.lo >>> 1) | ((this.hi & 1) << 31); - return new jspb.arith.UInt64(lo >>> 0, hi >>> 0); -}; - - -/** - * Left-shift this number by one bit. - * @return {!jspb.arith.UInt64} - */ -jspb.arith.UInt64.prototype.leftShift = function() { - var lo = this.lo << 1; - var hi = (this.hi << 1) | (this.lo >>> 31); - return new jspb.arith.UInt64(lo >>> 0, hi >>> 0); -}; - - -/** - * Test the MSB. - * @return {boolean} - */ -jspb.arith.UInt64.prototype.msb = function() { - return !!(this.hi & 0x80000000); -}; - - -/** - * Test the LSB. - * @return {boolean} - */ -jspb.arith.UInt64.prototype.lsb = function() { - return !!(this.lo & 1); -}; - - -/** - * Test whether this number is zero. - * @return {boolean} - */ -jspb.arith.UInt64.prototype.zero = function() { - return this.lo == 0 && this.hi == 0; -}; - - -/** - * Add two 64-bit numbers to produce a 64-bit number. - * @param {!jspb.arith.UInt64} other - * @return {!jspb.arith.UInt64} - */ -jspb.arith.UInt64.prototype.add = function(other) { - var lo = ((this.lo + other.lo) & 0xffffffff) >>> 0; - var hi = - (((this.hi + other.hi) & 0xffffffff) >>> 0) + - (((this.lo + other.lo) >= 0x100000000) ? 1 : 0); - return new jspb.arith.UInt64(lo >>> 0, hi >>> 0); -}; - - -/** - * Subtract two 64-bit numbers to produce a 64-bit number. - * @param {!jspb.arith.UInt64} other - * @return {!jspb.arith.UInt64} - */ -jspb.arith.UInt64.prototype.sub = function(other) { - var lo = ((this.lo - other.lo) & 0xffffffff) >>> 0; - var hi = - (((this.hi - other.hi) & 0xffffffff) >>> 0) - - (((this.lo - other.lo) < 0) ? 1 : 0); - return new jspb.arith.UInt64(lo >>> 0, hi >>> 0); -}; - - -/** - * Multiply two 32-bit numbers to produce a 64-bit number. - * @param {number} a The first integer: must be in [0, 2^32-1). - * @param {number} b The second integer: must be in [0, 2^32-1). - * @return {!jspb.arith.UInt64} - */ -jspb.arith.UInt64.mul32x32 = function(a, b) { - // Directly multiplying two 32-bit numbers may produce up to 64 bits of - // precision, thus losing precision because of the 53-bit mantissa of - // JavaScript numbers. So we multiply with 16-bit digits (radix 65536) - // instead. - var aLow = (a & 0xffff); - var aHigh = (a >>> 16); - var bLow = (b & 0xffff); - var bHigh = (b >>> 16); - var productLow = - // 32-bit result, result bits 0-31, take all 32 bits - (aLow * bLow) + - // 32-bit result, result bits 16-47, take bottom 16 as our top 16 - ((aLow * bHigh) & 0xffff) * 0x10000 + - // 32-bit result, result bits 16-47, take bottom 16 as our top 16 - ((aHigh * bLow) & 0xffff) * 0x10000; - var productHigh = - // 32-bit result, result bits 32-63, take all 32 bits - (aHigh * bHigh) + - // 32-bit result, result bits 16-47, take top 16 as our bottom 16 - ((aLow * bHigh) >>> 16) + - // 32-bit result, result bits 16-47, take top 16 as our bottom 16 - ((aHigh * bLow) >>> 16); - - // Carry. Note that we actually have up to *two* carries due to addition of - // three terms. - while (productLow >= 0x100000000) { - productLow -= 0x100000000; - productHigh += 1; - } - - return new jspb.arith.UInt64(productLow >>> 0, productHigh >>> 0); -}; - - -/** - * Multiply this number by a 32-bit number, producing a 96-bit number, then - * truncate the top 32 bits. - * @param {number} a The multiplier. - * @return {!jspb.arith.UInt64} - */ -jspb.arith.UInt64.prototype.mul = function(a) { - // Produce two parts: at bits 0-63, and 32-95. - var lo = jspb.arith.UInt64.mul32x32(this.lo, a); - var hi = jspb.arith.UInt64.mul32x32(this.hi, a); - // Left-shift hi by 32 bits, truncating its top bits. The parts will then be - // aligned for addition. - hi.hi = hi.lo; - hi.lo = 0; - return lo.add(hi); -}; - - -/** - * Divide a 64-bit number by a 32-bit number to produce a - * 64-bit quotient and a 32-bit remainder. - * @param {number} _divisor - * @return {Array} array of [quotient, remainder], - * unless divisor is 0, in which case an empty array is returned. - */ -jspb.arith.UInt64.prototype.div = function(_divisor) { - if (_divisor == 0) { - return []; - } - - // We perform long division using a radix-2 algorithm, for simplicity (i.e., - // one bit at a time). TODO: optimize to a radix-2^32 algorithm, taking care - // to get the variable shifts right. - var quotient = new jspb.arith.UInt64(0, 0); - var remainder = new jspb.arith.UInt64(this.lo, this.hi); - var divisor = new jspb.arith.UInt64(_divisor, 0); - var unit = new jspb.arith.UInt64(1, 0); - - // Left-shift the divisor and unit until the high bit of divisor is set. - while (!divisor.msb()) { - divisor = divisor.leftShift(); - unit = unit.leftShift(); - } - - // Perform long division one bit at a time. - while (!unit.zero()) { - // If divisor < remainder, add unit to quotient and subtract divisor from - // remainder. - if (divisor.cmp(remainder) <= 0) { - quotient = quotient.add(unit); - remainder = remainder.sub(divisor); - } - // Right-shift the divisor and unit. - divisor = divisor.rightShift(); - unit = unit.rightShift(); - } - - return [quotient, remainder]; -}; - - -/** - * Convert a 64-bit number to a string. - * @return {string} - * @override - */ -jspb.arith.UInt64.prototype.toString = function() { - var result = ''; - var num = this; - while (!num.zero()) { - var divResult = num.div(10); - var quotient = divResult[0], remainder = divResult[1]; - result = remainder.lo + result; - num = quotient; - } - if (result == '') { - result = '0'; - } - return result; -}; - - -/** - * Parse a string into a 64-bit number. Returns `null` on a parse error. - * @param {string} s - * @return {?jspb.arith.UInt64} - */ -jspb.arith.UInt64.fromString = function(s) { - var result = new jspb.arith.UInt64(0, 0); - // optimization: reuse this instance for each digit. - var digit64 = new jspb.arith.UInt64(0, 0); - for (var i = 0; i < s.length; i++) { - if (s[i] < '0' || s[i] > '9') { - return null; - } - var digit = parseInt(s[i], 10); - digit64.lo = digit; - result = result.mul(10).add(digit64); - } - return result; -}; - - -/** - * Make a copy of the uint64. - * @return {!jspb.arith.UInt64} - */ -jspb.arith.UInt64.prototype.clone = function() { - return new jspb.arith.UInt64(this.lo, this.hi); -}; - - -/** - * Int64 is like UInt64, but modifies string conversions to interpret the stored - * 64-bit value as a twos-complement-signed integer. It does *not* support the - * full range of operations that UInt64 does: only add, subtract, and string - * conversions. - * - * N.B. that multiply and divide routines are *NOT* supported. They will throw - * exceptions. (They are not necessary to implement string conversions, which - * are the only operations we really need in jspb.) - * - * @param {number} lo The low 32 bits. - * @param {number} hi The high 32 bits. - * @constructor - */ -jspb.arith.Int64 = function(lo, hi) { - /** - * The low 32 bits. - * @public {number} - */ - this.lo = lo; - /** - * The high 32 bits. - * @public {number} - */ - this.hi = hi; -}; - - -/** - * Add two 64-bit numbers to produce a 64-bit number. - * @param {!jspb.arith.Int64} other - * @return {!jspb.arith.Int64} - */ -jspb.arith.Int64.prototype.add = function(other) { - var lo = ((this.lo + other.lo) & 0xffffffff) >>> 0; - var hi = - (((this.hi + other.hi) & 0xffffffff) >>> 0) + - (((this.lo + other.lo) >= 0x100000000) ? 1 : 0); - return new jspb.arith.Int64(lo >>> 0, hi >>> 0); -}; - - -/** - * Subtract two 64-bit numbers to produce a 64-bit number. - * @param {!jspb.arith.Int64} other - * @return {!jspb.arith.Int64} - */ -jspb.arith.Int64.prototype.sub = function(other) { - var lo = ((this.lo - other.lo) & 0xffffffff) >>> 0; - var hi = - (((this.hi - other.hi) & 0xffffffff) >>> 0) - - (((this.lo - other.lo) < 0) ? 1 : 0); - return new jspb.arith.Int64(lo >>> 0, hi >>> 0); -}; - - -/** - * Make a copy of the int64. - * @return {!jspb.arith.Int64} - */ -jspb.arith.Int64.prototype.clone = function() { - return new jspb.arith.Int64(this.lo, this.hi); -}; - - -/** - * Convert a 64-bit number to a string. - * @return {string} - * @override - */ -jspb.arith.Int64.prototype.toString = function() { - // If the number is negative, find its twos-complement inverse. - var sign = (this.hi & 0x80000000) != 0; - var num = new jspb.arith.UInt64(this.lo, this.hi); - if (sign) { - num = new jspb.arith.UInt64(0, 0).sub(num); - } - return (sign ? '-' : '') + num.toString(); -}; - - -/** - * Parse a string into a 64-bit number. Returns `null` on a parse error. - * @param {string} s - * @return {?jspb.arith.Int64} - */ -jspb.arith.Int64.fromString = function(s) { - var hasNegative = (s.length > 0 && s[0] == '-'); - if (hasNegative) { - s = s.substring(1); - } - var num = jspb.arith.UInt64.fromString(s); - if (num === null) { - return null; - } - if (hasNegative) { - num = new jspb.arith.UInt64(0, 0).sub(num); - } - return new jspb.arith.Int64(num.lo, num.hi); -}; diff --git a/js/binary/arith_test.js b/js/binary/arith_test.js deleted file mode 100644 index dd5791a7b..000000000 --- a/js/binary/arith_test.js +++ /dev/null @@ -1,354 +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. - -/** - * @fileoverview Test cases for Int64-manipulation functions. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author cfallin@google.com (Chris Fallin) - */ - -goog.require('jspb.arith.Int64'); -goog.require('jspb.arith.UInt64'); - - -describe('binaryArithTest', function() { - /** - * Tests comparison operations. - */ - it('testCompare', function() { - var a = new jspb.arith.UInt64(1234, 5678); - var b = new jspb.arith.UInt64(1234, 5678); - expect(a.cmp(b)).toEqual(0); - expect(b.cmp(a)).toEqual(0); - b.lo -= 1; - expect(a.cmp(b)).toEqual(1); - expect(b.cmp(a)).toEqual(-1); - b.lo += 2; - expect(a.cmp(b)).toEqual(-1); - expect(b.cmp(a)).toEqual(1); - b.lo = a.lo; - b.hi = a.hi - 1; - expect(a.cmp(b)).toEqual(1); - expect(b.cmp(a)).toEqual(-1); - - expect(a.zero()).toEqual(false); - expect(a.msb()).toEqual(false); - expect(a.lsb()).toEqual(false); - a.hi = 0; - a.lo = 0; - expect(a.zero()).toEqual(true); - a.hi = 0x80000000; - expect(a.zero()).toEqual(false); - expect(a.msb()).toEqual(true); - a.lo = 0x00000001; - expect(a.lsb()).toEqual(true); - }); - - - /** - * Tests shifts. - */ - it('testShifts', function() { - var a = new jspb.arith.UInt64(1, 0); - expect(a.lo).toEqual(1); - expect(a.hi).toEqual(0); - var orig = a; - a = a.leftShift(); - expect(orig.lo).toEqual(1); // original unmodified. - expect(orig.hi).toEqual(0); - expect(a.lo).toEqual(2); - expect(a.hi).toEqual(0); - a = a.leftShift(); - expect(a.lo).toEqual(4); - expect(a.hi).toEqual(0); - for (var i = 0; i < 29; i++) { - a = a.leftShift(); - } - expect(a.lo).toEqual(0x80000000); - expect(a.hi).toEqual(0); - a = a.leftShift(); - expect(a.lo).toEqual(0); - expect(a.hi).toEqual(1); - a = a.leftShift(); - expect(a.lo).toEqual(0); - expect(a.hi).toEqual(2); - a = a.rightShift(); - a = a.rightShift(); - expect(a.lo).toEqual(0x80000000); - expect(a.hi).toEqual(0); - a = a.rightShift(); - expect(a.lo).toEqual(0x40000000); - expect(a.hi).toEqual(0); - }); - - - /** - * Tests additions. - */ - it('testAdd', function() { - var a = new jspb.arith.UInt64(/* lo = */ 0x89abcdef, - /* hi = */ 0x01234567); - var b = new jspb.arith.UInt64(/* lo = */ 0xff52ab91, - /* hi = */ 0x92fa2123); - // Addition with carry. - var c = a.add(b); - expect(a.lo).toEqual(0x89abcdef); // originals unmodified. - expect(a.hi).toEqual(0x01234567); - expect(b.lo).toEqual(0xff52ab91); - expect(b.hi).toEqual(0x92fa2123); - expect(c.lo).toEqual(0x88fe7980); - expect(c.hi).toEqual(0x941d668b); - - // Simple addition without carry. - a.lo = 2; - a.hi = 0; - b.lo = 3; - b.hi = 0; - c = a.add(b); - expect(c.lo).toEqual(5); - expect(c.hi).toEqual(0); - }); - - - /** - * Test subtractions. - */ - it('testSub', function() { - var kLength = 10; - var hiValues = [0x1682ef32, - 0x583902f7, - 0xb62f5955, - 0x6ea99bbf, - 0x25a39c20, - 0x0700a08b, - 0x00f7304d, - 0x91a5b5af, - 0x89077fd2, - 0xe09e347c]; - var loValues = [0xe1538b18, - 0xbeacd556, - 0x74100758, - 0x96e3cb26, - 0x56c37c3f, - 0xe00b3f7d, - 0x859f25d7, - 0xc2ee614a, - 0xe1d21cd7, - 0x30aae6a4]; - for (var i = 0; i < kLength; i++) { - for (var j = 0; j < kLength; j++) { - var a = new jspb.arith.UInt64(loValues[i], hiValues[j]); - var b = new jspb.arith.UInt64(loValues[j], hiValues[i]); - var c = a.add(b).sub(b); - expect(c.hi).toEqual(a.hi); - expect(c.lo).toEqual(a.lo); - } - } - }); - - - /** - * Tests 32-by-32 multiplication. - */ - it('testMul32x32', function() { - var testData = [ - // a b low(a*b) high(a*b) - [0xc0abe2f8, 0x1607898a, 0x5de711b0, 0x109471b8], - [0x915eb3cb, 0x4fb66d0e, 0xbd0d441a, 0x2d43d0bc], - [0xfe4efe70, 0x80b48c37, 0xbcddea10, 0x7fdada0c], - [0xe222fd4a, 0xe43d524a, 0xd5e0eb64, 0xc99d549c], - [0xd171f469, 0xb94ebd01, 0x4be17969, 0x979bc4fa], - [0x829cc1df, 0xe2598b38, 0xf4157dc8, 0x737c12ad], - [0xf10c3767, 0x8382881e, 0x942b3612, 0x7bd428b8], - [0xb0f6dd24, 0x232597e1, 0x079c98a4, 0x184bbce7], - [0xfcdb05a7, 0x902f55bc, 0x636199a4, 0x8e69f412], - [0x0dd0bfa9, 0x916e27b1, 0x6e2542d9, 0x07d92e65] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = testData[i][0] >>> 0; - var b = testData[i][1] >>> 0; - var cLow = testData[i][2] >>> 0; - var cHigh = testData[i][3] >>> 0; - var c = jspb.arith.UInt64.mul32x32(a, b); - expect(c.lo).toEqual(cLow); - expect(c.hi).toEqual(cHigh); - } - }); - - - /** - * Tests 64-by-32 multiplication. - */ - it('testMul', function() { - // 64x32 bits produces 96 bits of product. The multiplication function under - // test truncates the top 32 bits, so we compare against a 64-bit expected - // product. - var testData = [ - // low(a) high(a) low(a*b) high(a*b) - [0xec10955b, 0x360eb168, 0x4b7f3f5b, 0xbfcb7c59, 0x9517da5f], - [0x42b000fc, 0x9d101642, 0x6fa1ab72, 0x2584c438, 0x6a9e6d2b], - [0xf42d4fb4, 0xae366403, 0xa65a1000, 0x92434000, 0x1ff978df], - [0x17e2f56b, 0x25487693, 0xf13f98c7, 0x73794e2d, 0xa96b0c6a], - [0x492f241f, 0x76c0eb67, 0x7377ac44, 0xd4336c3c, 0xfc4b1ebe], - [0xd6b92321, 0xe184fa48, 0xd6e76904, 0x93141584, 0xcbf44da1], - [0x4bf007ea, 0x968c0a9e, 0xf5e4026a, 0x4fdb1ae4, 0x61b9fb7d], - [0x10a83be7, 0x2d685ba6, 0xc9e5fb7f, 0x2ad43499, 0x3742473d], - [0x2f261829, 0x1aca681a, 0x3d3494e3, 0x8213205b, 0x283719f8], - [0xe4f2ce21, 0x2e74b7bd, 0xd801b38b, 0xbc17feeb, 0xc6c44e0f] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); - var prod = a.mul(testData[i][2]); - expect(prod.lo).toEqual(testData[i][3]); - expect(prod.hi).toEqual(testData[i][4]); - } - }); - - - /** - * Tests 64-div-by-32 division. - */ - it('testDiv', function() { - // Compute a/b, yielding quot = a/b and rem = a%b. - var testData = [ - // --- divisors in (0, 2^32-1) to test full divisor range - // low(a) high(a) b low(quot) high(quot) rem - [0x712443f1, 0xe85cefcc, 0xc1a7050b, 0x332c79ad, 0x00000001, 0x92ffa882], - [0x11912915, 0xb2699eb5, 0x30467cbe, 0xb21b4be4, 0x00000003, 0x283465dd], - [0x0d917982, 0x201f2a6e, 0x3f35bf03, 0x8217c8e4, 0x00000000, 0x153402d6], - [0xa072c108, 0x74020c96, 0xc60568fd, 0x95f9613e, 0x00000000, 0x3f4676c2], - [0xd845d5d8, 0xcdd235c4, 0x20426475, 0x6154e78b, 0x00000006, 0x202fb751], - [0xa4dbf71f, 0x9e90465e, 0xf08e022f, 0xa8be947f, 0x00000000, 0xbe43b5ce], - [0x3dbe627f, 0xa791f4b9, 0x28a5bd89, 0x1f5dfe93, 0x00000004, 0x02bf9ed4], - [0x5c1c53ee, 0xccf5102e, 0x198576e7, 0x07e3ae31, 0x00000008, 0x02ea8fb7], - [0xfef1e581, 0x04714067, 0xca6540c1, 0x059e73ec, 0x00000000, 0x31658095], - [0x1e2dd90c, 0x13dd6667, 0x8b2184c3, 0x248d1a42, 0x00000000, 0x4ca6d0c6], - // --- divisors in (0, 2^16-1) to test larger quotient high-words - // low(a) high(a) b low(quot) high(quot) rem - [0x86722b47, 0x2cd57c9a, 0x00003123, 0x2ae41b7a, 0x0000e995, 0x00000f99], - [0x1dd7884c, 0xf5e839bc, 0x00009eeb, 0x5c886242, 0x00018c21, 0x000099b6], - [0x5c53d625, 0x899fc7e5, 0x000087d7, 0xd625007a, 0x0001035c, 0x000019af], - [0x6932d932, 0x9d0a5488, 0x000051fb, 0x9d976143, 0x0001ea63, 0x00004981], - [0x4d18bb85, 0x0c92fb31, 0x00001d9f, 0x03265ab4, 0x00006cac, 0x000001b9], - [0xbe756768, 0xdea67ccb, 0x00008a03, 0x58add442, 0x00019cff, 0x000056a2], - [0xe2466f9a, 0x2521f114, 0x0000c350, 0xa0c0860d, 0x000030ab, 0x0000a48a], - [0xf00ddad1, 0xe2f5446a, 0x00002cfc, 0x762697a6, 0x00050b96, 0x00000b69], - [0xa879152a, 0x0a70e0a5, 0x00007cdf, 0xb44151b3, 0x00001567, 0x0000363d], - [0x7179a74c, 0x46083fff, 0x0000253c, 0x4d39ba6e, 0x0001e17f, 0x00000f84] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); - var result = a.div(testData[i][2]); - var quotient = result[0]; - var remainder = result[1]; - expect(quotient.lo).toEqual(testData[i][3]); - expect(quotient.hi).toEqual(testData[i][4]); - expect(remainder.lo).toEqual(testData[i][5]); - } - }); - - - /** - * Tests .toString() and .fromString(). - */ - it('testStrings', function() { - var testData = [ - [0x5e84c935, 0xcae33d0e, '14619595947299359029'], - [0x62b3b8b8, 0x93480544, '10612738313170434232'], - [0x319bfb13, 0xc01c4172, '13843011313344445203'], - [0x5b8a65fb, 0xa5885b31, '11927883880638080507'], - [0x6bdb80f1, 0xb0d1b16b, '12741159895737008369'], - [0x4b82b442, 0x2e0d8c97, '3318463081876730946'], - [0x780d5208, 0x7d76752c, '9040542135845999112'], - [0x2e46800f, 0x0993778d, '690026616168284175'], - [0xf00a7e32, 0xcd8e3931, '14811839111111540274'], - [0x1baeccd6, 0x923048c4, '10533999535534820566'], - [0x03669d29, 0xbff3ab72, '13831587386756603177'], - [0x2526073e, 0x01affc81, '121593346566522686'], - [0xc24244e0, 0xd7f40d0e, '15561076969511732448'], - [0xc56a341e, 0xa68b66a7, '12000798502816461854'], - [0x8738d64d, 0xbfe78604, '13828168534871037517'], - [0x5baff03b, 0xd7572aea, '15516918227177304123'], - [0x4a843d8a, 0x864e132b, '9677693725920476554'], - [0x25b4e94d, 0x22b54dc6, '2500990681505655117'], - [0x6bbe664b, 0x55a5cc0e, '6171563226690381387'], - [0xee916c81, 0xb00aabb3, '12685140089732426881'] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); - var roundtrip = jspb.arith.UInt64.fromString(a.toString()); - expect(roundtrip.lo).toEqual(a.lo); - expect(roundtrip.hi).toEqual(a.hi); - expect(a.toString()).toEqual(testData[i][2]); - } - }); - - - /** - * Tests signed Int64s. These are built on UInt64s, so we only need to test - * the explicit overrides: .toString() and .fromString(). - */ - it('testSignedInt64', function() { - var testStrings = [ - '-7847499644178593666', - '3771946501229139523', - '2872856549054995060', - '-5780049594274350904', - '3383785956695105201', - '2973055184857072610', - '-3879428459215627206', - '4589812431064156631', - '8484075557333689940', - '1075325817098092407', - '-4346697501012292314', - '2488620459718316637', - '6112655187423520672', - '-3655278273928612104', - '3439154019435803196', - '1004112478843763757', - '-6587790776614368413', - '664320065099714586', - '4760412909973292912', - '-7911903989602274672' - ]; - - for (var i = 0; i < testStrings.length; i++) { - var roundtrip = - jspb.arith.Int64.fromString(testStrings[i]).toString(); - expect(roundtrip).toEqual(testStrings[i]); - } - }); -}); diff --git a/js/binary/constants.js b/js/binary/constants.js deleted file mode 100644 index d2e62e5b0..000000000 --- a/js/binary/constants.js +++ /dev/null @@ -1,377 +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. - -/** - * @fileoverview This file contains constants and typedefs used by - * jspb.BinaryReader and BinaryWriter. - * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.provide('jspb.AnyFieldType'); -goog.provide('jspb.BinaryConstants'); -goog.provide('jspb.BinaryMessage'); -goog.provide('jspb.BuilderFunction'); -goog.provide('jspb.ByteSource'); -goog.provide('jspb.ClonerFunction'); -goog.provide('jspb.ComparerFunction'); -goog.provide('jspb.ConstBinaryMessage'); -goog.provide('jspb.PrunerFunction'); -goog.provide('jspb.ReaderFunction'); -goog.provide('jspb.RecyclerFunction'); -goog.provide('jspb.RepeatedFieldType'); -goog.provide('jspb.ScalarFieldType'); -goog.provide('jspb.WriterFunction'); - - -goog.forwardDeclare('jspb.BinaryMessage'); -goog.forwardDeclare('jspb.BinaryReader'); -goog.forwardDeclare('jspb.BinaryWriter'); -goog.forwardDeclare('jspb.Message'); -goog.forwardDeclare('jsprotolib.BinaryExtension'); - - - -/** - * Base interface class for all const messages. - * @interface - */ -jspb.ConstBinaryMessage = function() {}; - -/** - * Generate a debug string for this proto that is in proto2 text format. - * @return {string} The debug string. - */ -jspb.ConstBinaryMessage.prototype.toDebugString; - -/** - * Helper to generate a debug string for this proto at some indent level. The - * first line is not indented. - * @param {number} indentLevel The number of spaces by which to indent lines. - * @return {string} The debug string. - * @protected - */ -jspb.ConstBinaryMessage.prototype.toDebugStringInternal; - -/** - * Base interface class for all messages. Does __not__ define any methods, as - * doing so on a widely-used interface defeats dead-code elimination. - * @interface - * @extends {jspb.ConstBinaryMessage} - */ -jspb.BinaryMessage = function() {}; - - -/** - * The types convertible to Uint8Arrays. Strings are assumed to be - * base64-encoded. - * @typedef {ArrayBuffer|Uint8Array|Array|string} - */ -jspb.ByteSource; - - -/** - * A scalar field in jspb can be a boolean, number, or string. - * @typedef {boolean|number|string} - */ -jspb.ScalarFieldType; - - -/** - * A repeated field in jspb is an array of scalars, blobs, or messages. - * @typedef {!Array| - !Array| - !Array| - !Array} - */ -jspb.RepeatedFieldType; - - -/** - * A field in jspb can be a scalar, a block of bytes, another proto, or an - * array of any of the above. - * @typedef {jspb.ScalarFieldType| - jspb.RepeatedFieldType| - !Uint8Array| - !jspb.ConstBinaryMessage| - !jspb.BinaryMessage| - !jsprotolib.BinaryExtension} - */ -jspb.AnyFieldType; - - -/** - * A builder function creates an instance of a message object. - * @typedef {function():!jspb.BinaryMessage} - */ -jspb.BuilderFunction; - - -/** - * A cloner function creates a deep copy of a message object. - * @typedef {function(jspb.ConstBinaryMessage):jspb.BinaryMessage} - */ -jspb.ClonerFunction; - - -/** - * A recycler function destroys an instance of a message object. - * @typedef {function(!jspb.BinaryMessage):void} - */ -jspb.RecyclerFunction; - - -/** - * A reader function initializes a message using data from a BinaryReader. - * @typedef {function(!jspb.BinaryMessage, !jspb.BinaryReader):void} - */ -jspb.ReaderFunction; - - -/** - * A writer function serializes a message to a BinaryWriter. - * @typedef {function((!jspb.Message|!jspb.ConstBinaryMessage), - * !jspb.BinaryWriter):void} - */ -jspb.WriterFunction; - - -/** - * A pruner function removes default-valued fields and empty submessages from a - * message and returns either the pruned message or null if the entire message - * was pruned away. - * @typedef {function(?jspb.BinaryMessage):?jspb.BinaryMessage} - */ -jspb.PrunerFunction; - - -/** - * A comparer function returns true if two protos are equal. - * @typedef {function(?jspb.ConstBinaryMessage, - * ?jspb.ConstBinaryMessage):boolean} - */ -jspb.ComparerFunction; - - -/** - * Field type codes, taken from proto2/public/wire_format_lite.h. - * @enum {number} - */ -jspb.BinaryConstants.FieldType = { - INVALID: -1, - DOUBLE: 1, - FLOAT: 2, - INT64: 3, - UINT64: 4, - INT32: 5, - FIXED64: 6, - FIXED32: 7, - BOOL: 8, - STRING: 9, - GROUP: 10, - MESSAGE: 11, - BYTES: 12, - UINT32: 13, - ENUM: 14, - SFIXED32: 15, - SFIXED64: 16, - SINT32: 17, - SINT64: 18, - - // Extended types for Javascript - - FHASH64: 30, // 64-bit hash string, fixed-length encoding. - VHASH64: 31 // 64-bit hash string, varint encoding. -}; - - -/** - * Wire-format type codes, taken from proto2/public/wire_format_lite.h. - * @enum {number} - */ -jspb.BinaryConstants.WireType = { - INVALID: -1, - VARINT: 0, - FIXED64: 1, - DELIMITED: 2, - START_GROUP: 3, - END_GROUP: 4, - FIXED32: 5 -}; - - -/** - * Translates field type to wire type. - * @param {jspb.BinaryConstants.FieldType} fieldType - * @return {jspb.BinaryConstants.WireType} - */ -jspb.BinaryConstants.FieldTypeToWireType = function(fieldType) { - var fieldTypes = jspb.BinaryConstants.FieldType; - var wireTypes = jspb.BinaryConstants.WireType; - switch (fieldType) { - case fieldTypes.INT32: - case fieldTypes.INT64: - case fieldTypes.UINT32: - case fieldTypes.UINT64: - case fieldTypes.SINT32: - case fieldTypes.SINT64: - case fieldTypes.BOOL: - case fieldTypes.ENUM: - case fieldTypes.VHASH64: - return wireTypes.VARINT; - - case fieldTypes.DOUBLE: - case fieldTypes.FIXED64: - case fieldTypes.SFIXED64: - case fieldTypes.FHASH64: - return wireTypes.FIXED64; - - case fieldTypes.STRING: - case fieldTypes.MESSAGE: - case fieldTypes.BYTES: - return wireTypes.DELIMITED; - - case fieldTypes.FLOAT: - case fieldTypes.FIXED32: - case fieldTypes.SFIXED32: - return wireTypes.FIXED32; - - case fieldTypes.INVALID: - case fieldTypes.GROUP: - default: - return wireTypes.INVALID; - } -}; - - -/** - * Flag to indicate a missing field. - * @const {number} - */ -jspb.BinaryConstants.INVALID_FIELD_NUMBER = -1; - - -/** - * The smallest denormal float32 value. - * @const {number} - */ -jspb.BinaryConstants.FLOAT32_EPS = 1.401298464324817e-45; - - -/** - * The smallest normal float64 value. - * @const {number} - */ -jspb.BinaryConstants.FLOAT32_MIN = 1.1754943508222875e-38; - - -/** - * The largest finite float32 value. - * @const {number} - */ -jspb.BinaryConstants.FLOAT32_MAX = 3.4028234663852886e+38; - - -/** - * The smallest denormal float64 value. - * @const {number} - */ -jspb.BinaryConstants.FLOAT64_EPS = 5e-324; - - -/** - * The smallest normal float64 value. - * @const {number} - */ -jspb.BinaryConstants.FLOAT64_MIN = 2.2250738585072014e-308; - - -/** - * The largest finite float64 value. - * @const {number} - */ -jspb.BinaryConstants.FLOAT64_MAX = 1.7976931348623157e+308; - - -/** - * Convenience constant equal to 2^20. - * @const {number} - */ -jspb.BinaryConstants.TWO_TO_20 = 1048576; - - -/** - * Convenience constant equal to 2^23. - * @const {number} - */ -jspb.BinaryConstants.TWO_TO_23 = 8388608; - - -/** - * Convenience constant equal to 2^31. - * @const {number} - */ -jspb.BinaryConstants.TWO_TO_31 = 2147483648; - - -/** - * Convenience constant equal to 2^32. - * @const {number} - */ -jspb.BinaryConstants.TWO_TO_32 = 4294967296; - - -/** - * Convenience constant equal to 2^52. - * @const {number} - */ -jspb.BinaryConstants.TWO_TO_52 = 4503599627370496; - - -/** - * Convenience constant equal to 2^63. - * @const {number} - */ -jspb.BinaryConstants.TWO_TO_63 = 9223372036854775808; - - -/** - * Convenience constant equal to 2^64. - * @const {number} - */ -jspb.BinaryConstants.TWO_TO_64 = 18446744073709551616; - - -/** - * Eight-character string of zeros, used as the default 64-bit hash value. - * @const {string} - */ -jspb.BinaryConstants.ZERO_HASH = '\0\0\0\0\0\0\0\0'; diff --git a/js/binary/decoder.js b/js/binary/decoder.js deleted file mode 100644 index fb40ec99e..000000000 --- a/js/binary/decoder.js +++ /dev/null @@ -1,951 +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. - -/** - * @fileoverview This file contains utilities for decoding primitive values - * (signed and unsigned integers, varints, booleans, enums, hashes, strings, - * and raw bytes) embedded in Uint8Arrays into their corresponding Javascript - * types. - * - * Major caveat - Javascript is unable to accurately represent integers larger - * than 2^53 due to its use of a double-precision floating point format or all - * numbers. If you need to guarantee that 64-bit values survive with all bits - * intact, you _must_ read them using one of the Hash64 methods, which return - * an 8-character string. - * - * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed - * @author aappleby@google.com (Austin Appleby) - */ - -goog.provide('jspb.BinaryDecoder'); - -goog.require('goog.asserts'); -goog.require('goog.crypt'); -goog.require('jspb.utils'); - - - -/** - * BinaryDecoder implements the decoders for all the wire types specified in - * https://developers.google.com/protocol-buffers/docs/encoding. - * - * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from. - * @param {number=} opt_start The optional offset to start reading at. - * @param {number=} opt_length The optional length of the block to read - - * we'll throw an assertion if we go off the end of the block. - * @constructor - * @struct - */ -jspb.BinaryDecoder = function(opt_bytes, opt_start, opt_length) { - /** - * Typed byte-wise view of the source buffer. - * @private {?Uint8Array} - */ - this.bytes_ = null; - - /** - * Start point of the block to read. - * @private {number} - */ - this.start_ = 0; - - /** - * End point of the block to read. - * @private {number} - */ - this.end_ = 0; - - /** - * Current read location in bytes_. - * @private {number} - */ - this.cursor_ = 0; - - /** - * Set to true if this decoder encountered an error due to corrupt data. - * @private {boolean} - */ - this.error_ = false; - - if (opt_bytes) { - this.setBlock(opt_bytes, opt_start, opt_length); - } -}; - - -/** - * Global pool of BinaryDecoder instances. - * @private {!Array} - */ -jspb.BinaryDecoder.instanceCache_ = []; - - -/** - * Pops an instance off the instance cache, or creates one if the cache is - * empty. - * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from. - * @param {number=} opt_start The optional offset to start reading at. - * @param {number=} opt_length The optional length of the block to read - - * we'll throw an assertion if we go off the end of the block. - * @return {!jspb.BinaryDecoder} - */ -jspb.BinaryDecoder.alloc = function(opt_bytes, opt_start, opt_length) { - if (jspb.BinaryDecoder.instanceCache_.length) { - var newDecoder = jspb.BinaryDecoder.instanceCache_.pop(); - if (opt_bytes) { - newDecoder.setBlock(opt_bytes, opt_start, opt_length); - } - return newDecoder; - } else { - return new jspb.BinaryDecoder(opt_bytes, opt_start, opt_length); - } -}; - - -/** - * Puts this instance back in the instance cache. - */ -jspb.BinaryDecoder.prototype.free = function() { - this.clear(); - if (jspb.BinaryDecoder.instanceCache_.length < 100) { - jspb.BinaryDecoder.instanceCache_.push(this); - } -}; - - -/** - * Makes a copy of this decoder. - * @return {!jspb.BinaryDecoder} - */ -jspb.BinaryDecoder.prototype.clone = function() { - return jspb.BinaryDecoder.alloc(this.bytes_, - this.start_, this.end_ - this.start_); -}; - - -/** - * Clears the decoder. - */ -jspb.BinaryDecoder.prototype.clear = function() { - this.bytes_ = null; - this.start_ = 0; - this.end_ = 0; - this.cursor_ = 0; - this.error_ = false; -}; - - -/** - * Returns the raw buffer. - * @return {?Uint8Array} The raw buffer. - */ -jspb.BinaryDecoder.prototype.getBuffer = function() { - return this.bytes_; -}; - - -/** - * Changes the block of bytes we're decoding. - * @param {!jspb.ByteSource} data The bytes we're reading from. - * @param {number=} opt_start The optional offset to start reading at. - * @param {number=} opt_length The optional length of the block to read - - * we'll throw an assertion if we go off the end of the block. - */ -jspb.BinaryDecoder.prototype.setBlock = - function(data, opt_start, opt_length) { - this.bytes_ = jspb.utils.byteSourceToUint8Array(data); - this.start_ = (opt_start !== undefined) ? opt_start : 0; - this.end_ = (opt_length !== undefined) ? this.start_ + opt_length : - this.bytes_.length; - this.cursor_ = this.start_; -}; - - -/** - * @return {number} - */ -jspb.BinaryDecoder.prototype.getEnd = function() { - return this.end_; -}; - - -/** - * @param {number} end - */ -jspb.BinaryDecoder.prototype.setEnd = function(end) { - this.end_ = end; -}; - - -/** - * Moves the read cursor back to the start of the block. - */ -jspb.BinaryDecoder.prototype.reset = function() { - this.cursor_ = this.start_; -}; - - -/** - * Returns the internal read cursor. - * @return {number} The internal read cursor. - */ -jspb.BinaryDecoder.prototype.getCursor = function() { - return this.cursor_; -}; - - -/** - * Returns the internal read cursor. - * @param {number} cursor The new cursor. - */ -jspb.BinaryDecoder.prototype.setCursor = function(cursor) { - this.cursor_ = cursor; -}; - - -/** - * Advances the stream cursor by the given number of bytes. - * @param {number} count The number of bytes to advance by. - */ -jspb.BinaryDecoder.prototype.advance = function(count) { - this.cursor_ += count; - goog.asserts.assert(this.cursor_ <= this.end_); -}; - - -/** - * Returns true if this decoder is at the end of the block. - * @return {boolean} - */ -jspb.BinaryDecoder.prototype.atEnd = function() { - return this.cursor_ == this.end_; -}; - - -/** - * Returns true if this decoder is at the end of the block. - * @return {boolean} - */ -jspb.BinaryDecoder.prototype.pastEnd = function() { - return this.cursor_ > this.end_; -}; - - -/** - * Returns true if this decoder encountered an error due to corrupt data. - * @return {boolean} - */ -jspb.BinaryDecoder.prototype.getError = function() { - return this.error_ || - (this.cursor_ < 0) || - (this.cursor_ > this.end_); -}; - - -/** - * Reads an unsigned varint from the binary stream and invokes the conversion - * function with the value in two signed 32 bit integers to produce the result. - * Since this does not convert the value to a number, no precision is lost. - * - * It's possible for an unsigned varint to be incorrectly encoded - more than - * 64 bits' worth of data could be present. If this happens, this method will - * throw an error. - * - * Decoding varints requires doing some funny base-128 math - for more - * details on the format, see - * https://developers.google.com/protocol-buffers/docs/encoding - * - * @param {function(number, number): T} convert Conversion function to produce - * the result value, takes parameters (lowBits, highBits). - * @return {T} - * @template T - */ -jspb.BinaryDecoder.prototype.readSplitVarint64 = function(convert) { - var temp = 128; - var lowBits = 0; - var highBits = 0; - - // Read the first four bytes of the varint, stopping at the terminator if we - // see it. - for (var i = 0; i < 4 && temp >= 128; i++) { - temp = this.bytes_[this.cursor_++]; - lowBits |= (temp & 0x7F) << (i * 7); - } - - if (temp >= 128) { - // Read the fifth byte, which straddles the low and high dwords. - temp = this.bytes_[this.cursor_++]; - lowBits |= (temp & 0x7F) << 28; - highBits |= (temp & 0x7F) >> 4; - } - - if (temp >= 128) { - // Read the sixth through tenth byte. - for (var i = 0; i < 5 && temp >= 128; i++) { - temp = this.bytes_[this.cursor_++]; - highBits |= (temp & 0x7F) << (i * 7 + 3); - } - } - - if (temp < 128) { - return convert(lowBits >>> 0, highBits >>> 0); - } - - // If we did not see the terminator, the encoding was invalid. - goog.asserts.fail('Failed to read varint, encoding is invalid.'); - this.error_ = true; -}; - - -/** - * Reads a signed zigzag encoded varint from the binary stream and invokes - * the conversion function with the value in two signed 32 bit integers to - * produce the result. Since this does not convert the value to a number, no - * precision is lost. - * - * It's possible for an unsigned varint to be incorrectly encoded - more than - * 64 bits' worth of data could be present. If this happens, this method will - * throw an error. - * - * Zigzag encoding is a modification of varint encoding that reduces the - * storage overhead for small negative integers - for more details on the - * format, see https://developers.google.com/protocol-buffers/docs/encoding - * - * @param {function(number, number): T} convert Conversion function to produce - * the result value, takes parameters (lowBits, highBits). - * @return {T} - * @template T - */ -jspb.BinaryDecoder.prototype.readSplitZigzagVarint64 = function(convert) { - return this.readSplitVarint64(function(low, high) { - return jspb.utils.fromZigzag64(low, high, convert); - }); -}; - - -/** - * Reads a 64-bit fixed-width value from the stream and invokes the conversion - * function with the value in two signed 32 bit integers to produce the result. - * Since this does not convert the value to a number, no precision is lost. - * - * @param {function(number, number): T} convert Conversion function to produce - * the result value, takes parameters (lowBits, highBits). - * @return {T} - * @template T - */ -jspb.BinaryDecoder.prototype.readSplitFixed64 = function(convert) { - var bytes = this.bytes_; - var cursor = this.cursor_; - this.cursor_ += 8; - var lowBits = 0; - var highBits = 0; - for (var i = cursor + 7; i >= cursor; i--) { - lowBits = (lowBits << 8) | bytes[i]; - highBits = (highBits << 8) | bytes[i + 4]; - } - return convert(lowBits, highBits); -}; - - -/** - * Skips over a varint in the block without decoding it. - */ -jspb.BinaryDecoder.prototype.skipVarint = function() { - while (this.bytes_[this.cursor_] & 0x80) { - this.cursor_++; - } - this.cursor_++; -}; - - -/** - * Skips backwards over a varint in the block - to do this correctly, we have - * to know the value we're skipping backwards over or things are ambiguous. - * @param {number} value The varint value to unskip. - */ -jspb.BinaryDecoder.prototype.unskipVarint = function(value) { - while (value > 128) { - this.cursor_--; - value = value >>> 7; - } - this.cursor_--; -}; - - -/** - * Reads a 32-bit varint from the binary stream. Due to a quirk of the encoding - * format and Javascript's handling of bitwise math, this actually works - * correctly for both signed and unsigned 32-bit varints. - * - * This function is called vastly more frequently than any other in - * BinaryDecoder, so it has been unrolled and tweaked for performance. - * - * If there are more than 32 bits of data in the varint, it _must_ be due to - * sign-extension. If we're in debug mode and the high 32 bits don't match the - * expected sign extension, this method will throw an error. - * - * Decoding varints requires doing some funny base-128 math - for more - * details on the format, see - * https://developers.google.com/protocol-buffers/docs/encoding - * - * @return {number} The decoded unsigned 32-bit varint. - */ -jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() { - var temp; - var bytes = this.bytes_; - - temp = bytes[this.cursor_ + 0]; - var x = (temp & 0x7F); - if (temp < 128) { - this.cursor_ += 1; - goog.asserts.assert(this.cursor_ <= this.end_); - return x; - } - - temp = bytes[this.cursor_ + 1]; - x |= (temp & 0x7F) << 7; - if (temp < 128) { - this.cursor_ += 2; - goog.asserts.assert(this.cursor_ <= this.end_); - return x; - } - - temp = bytes[this.cursor_ + 2]; - x |= (temp & 0x7F) << 14; - if (temp < 128) { - this.cursor_ += 3; - goog.asserts.assert(this.cursor_ <= this.end_); - return x; - } - - temp = bytes[this.cursor_ + 3]; - x |= (temp & 0x7F) << 21; - if (temp < 128) { - this.cursor_ += 4; - goog.asserts.assert(this.cursor_ <= this.end_); - return x; - } - - temp = bytes[this.cursor_ + 4]; - x |= (temp & 0x0F) << 28; - if (temp < 128) { - // We're reading the high bits of an unsigned varint. The byte we just read - // also contains bits 33 through 35, which we're going to discard. - this.cursor_ += 5; - goog.asserts.assert(this.cursor_ <= this.end_); - return x >>> 0; - } - - // If we get here, we need to truncate coming bytes. However we need to make - // sure cursor place is correct. - this.cursor_ += 5; - if (bytes[this.cursor_++] >= 128 && - bytes[this.cursor_++] >= 128 && - bytes[this.cursor_++] >= 128 && - bytes[this.cursor_++] >= 128 && - bytes[this.cursor_++] >= 128) { - // If we get here, the varint is too long. - goog.asserts.assert(false); - } - - goog.asserts.assert(this.cursor_ <= this.end_); - return x; -}; - - -/** - * The readUnsignedVarint32 above deals with signed 32-bit varints correctly, - * so this is just an alias. - * - * @return {number} The decoded signed 32-bit varint. - */ -jspb.BinaryDecoder.prototype.readSignedVarint32 = - jspb.BinaryDecoder.prototype.readUnsignedVarint32; - - -/** - * Reads a 32-bit unsigned variant and returns its value as a string. - * - * @return {string} The decoded unsigned 32-bit varint as a string. - */ -jspb.BinaryDecoder.prototype.readUnsignedVarint32String = function() { - // 32-bit integers fit in JavaScript numbers without loss of precision, so - // string variants of 32-bit varint readers can simply delegate then convert - // to string. - var value = this.readUnsignedVarint32(); - return value.toString(); -}; - - -/** - * Reads a 32-bit signed variant and returns its value as a string. - * - * @return {string} The decoded signed 32-bit varint as a string. - */ -jspb.BinaryDecoder.prototype.readSignedVarint32String = function() { - // 32-bit integers fit in JavaScript numbers without loss of precision, so - // string variants of 32-bit varint readers can simply delegate then convert - // to string. - var value = this.readSignedVarint32(); - return value.toString(); -}; - - -/** - * Reads a signed, zigzag-encoded 32-bit varint from the binary stream. - * - * Zigzag encoding is a modification of varint encoding that reduces the - * storage overhead for small negative integers - for more details on the - * format, see https://developers.google.com/protocol-buffers/docs/encoding - * - * @return {number} The decoded signed, zigzag-encoded 32-bit varint. - */ -jspb.BinaryDecoder.prototype.readZigzagVarint32 = function() { - var result = this.readUnsignedVarint32(); - return (result >>> 1) ^ - (result & 1); -}; - - -/** - * Reads an unsigned 64-bit varint from the binary stream. Note that since - * Javascript represents all numbers as double-precision floats, there will be - * precision lost if the absolute value of the varint is larger than 2^53. - * - * @return {number} The decoded unsigned varint. Precision will be lost if the - * integer exceeds 2^53. - */ -jspb.BinaryDecoder.prototype.readUnsignedVarint64 = function() { - return this.readSplitVarint64(jspb.utils.joinUint64); -}; - - -/** - * Reads an unsigned 64-bit varint from the binary stream and returns the value - * as a decimal string. - * - * @return {string} The decoded unsigned varint as a decimal string. - */ -jspb.BinaryDecoder.prototype.readUnsignedVarint64String = function() { - return this.readSplitVarint64(jspb.utils.joinUnsignedDecimalString); -}; - - -/** - * Reads a signed 64-bit varint from the binary stream. Note that since - * Javascript represents all numbers as double-precision floats, there will be - * precision lost if the absolute value of the varint is larger than 2^53. - * - * @return {number} The decoded signed varint. Precision will be lost if the - * integer exceeds 2^53. - */ -jspb.BinaryDecoder.prototype.readSignedVarint64 = function() { - return this.readSplitVarint64(jspb.utils.joinInt64); -}; - - -/** - * Reads an signed 64-bit varint from the binary stream and returns the value - * as a decimal string. - * - * @return {string} The decoded signed varint as a decimal string. - */ -jspb.BinaryDecoder.prototype.readSignedVarint64String = function() { - return this.readSplitVarint64(jspb.utils.joinSignedDecimalString); -}; - - -/** - * Reads a signed, zigzag-encoded 64-bit varint from the binary stream. Note - * that since Javascript represents all numbers as double-precision floats, - * there will be precision lost if the absolute value of the varint is larger - * than 2^53. - * - * Zigzag encoding is a modification of varint encoding that reduces the - * storage overhead for small negative integers - for more details on the - * format, see https://developers.google.com/protocol-buffers/docs/encoding - * - * @return {number} The decoded zigzag varint. Precision will be lost if the - * integer exceeds 2^53. - */ -jspb.BinaryDecoder.prototype.readZigzagVarint64 = function() { - return this.readSplitVarint64(jspb.utils.joinZigzag64); -}; - - -/** - * Reads a signed, zigzag-encoded 64-bit varint from the binary stream - * losslessly and returns it as an 8-character Unicode string for use as a hash - * table key. - * - * Zigzag encoding is a modification of varint encoding that reduces the - * storage overhead for small negative integers - for more details on the - * format, see https://developers.google.com/protocol-buffers/docs/encoding - * - * @return {string} The decoded zigzag varint in hash64 format. - */ -jspb.BinaryDecoder.prototype.readZigzagVarintHash64 = function() { - return this.readSplitZigzagVarint64(jspb.utils.joinHash64); -}; - - -/** - * Reads a signed, zigzag-encoded 64-bit varint from the binary stream and - * returns its value as a string. - * - * Zigzag encoding is a modification of varint encoding that reduces the - * storage overhead for small negative integers - for more details on the - * format, see https://developers.google.com/protocol-buffers/docs/encoding - * - * @return {string} The decoded signed, zigzag-encoded 64-bit varint as a - * string. - */ -jspb.BinaryDecoder.prototype.readZigzagVarint64String = function() { - return this.readSplitZigzagVarint64(jspb.utils.joinSignedDecimalString); -}; - - -/** - * Reads a raw unsigned 8-bit integer from the binary stream. - * - * @return {number} The unsigned 8-bit integer read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readUint8 = function() { - var a = this.bytes_[this.cursor_ + 0]; - this.cursor_ += 1; - goog.asserts.assert(this.cursor_ <= this.end_); - return a; -}; - - -/** - * Reads a raw unsigned 16-bit integer from the binary stream. - * - * @return {number} The unsigned 16-bit integer read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readUint16 = function() { - var a = this.bytes_[this.cursor_ + 0]; - var b = this.bytes_[this.cursor_ + 1]; - this.cursor_ += 2; - goog.asserts.assert(this.cursor_ <= this.end_); - return (a << 0) | (b << 8); -}; - - -/** - * Reads a raw unsigned 32-bit integer from the binary stream. - * - * @return {number} The unsigned 32-bit integer read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readUint32 = function() { - var a = this.bytes_[this.cursor_ + 0]; - var b = this.bytes_[this.cursor_ + 1]; - var c = this.bytes_[this.cursor_ + 2]; - var d = this.bytes_[this.cursor_ + 3]; - this.cursor_ += 4; - goog.asserts.assert(this.cursor_ <= this.end_); - return ((a << 0) | (b << 8) | (c << 16) | (d << 24)) >>> 0; -}; - - -/** - * Reads a raw unsigned 64-bit integer from the binary stream. Note that since - * Javascript represents all numbers as double-precision floats, there will be - * precision lost if the absolute value of the integer is larger than 2^53. - * - * @return {number} The unsigned 64-bit integer read from the binary stream. - * Precision will be lost if the integer exceeds 2^53. - */ -jspb.BinaryDecoder.prototype.readUint64 = function() { - var bitsLow = this.readUint32(); - var bitsHigh = this.readUint32(); - return jspb.utils.joinUint64(bitsLow, bitsHigh); -}; - - -/** - * Reads a raw unsigned 64-bit integer from the binary stream. Note that since - * Javascript represents all numbers as double-precision floats, there will be - * precision lost if the absolute value of the integer is larger than 2^53. - * - * @return {string} The unsigned 64-bit integer read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readUint64String = function() { - var bitsLow = this.readUint32(); - var bitsHigh = this.readUint32(); - return jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh); -}; - - -/** - * Reads a raw signed 8-bit integer from the binary stream. - * - * @return {number} The signed 8-bit integer read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readInt8 = function() { - var a = this.bytes_[this.cursor_ + 0]; - this.cursor_ += 1; - goog.asserts.assert(this.cursor_ <= this.end_); - return (a << 24) >> 24; -}; - - -/** - * Reads a raw signed 16-bit integer from the binary stream. - * - * @return {number} The signed 16-bit integer read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readInt16 = function() { - var a = this.bytes_[this.cursor_ + 0]; - var b = this.bytes_[this.cursor_ + 1]; - this.cursor_ += 2; - goog.asserts.assert(this.cursor_ <= this.end_); - return (((a << 0) | (b << 8)) << 16) >> 16; -}; - - -/** - * Reads a raw signed 32-bit integer from the binary stream. - * - * @return {number} The signed 32-bit integer read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readInt32 = function() { - var a = this.bytes_[this.cursor_ + 0]; - var b = this.bytes_[this.cursor_ + 1]; - var c = this.bytes_[this.cursor_ + 2]; - var d = this.bytes_[this.cursor_ + 3]; - this.cursor_ += 4; - goog.asserts.assert(this.cursor_ <= this.end_); - return (a << 0) | (b << 8) | (c << 16) | (d << 24); -}; - - -/** - * Reads a raw signed 64-bit integer from the binary stream. Note that since - * Javascript represents all numbers as double-precision floats, there will be - * precision lost if the absolute value of the integer is larger than 2^53. - * - * @return {number} The signed 64-bit integer read from the binary stream. - * Precision will be lost if the integer exceeds 2^53. - */ -jspb.BinaryDecoder.prototype.readInt64 = function() { - var bitsLow = this.readUint32(); - var bitsHigh = this.readUint32(); - return jspb.utils.joinInt64(bitsLow, bitsHigh); -}; - - -/** - * Reads a raw signed 64-bit integer from the binary stream and returns it as a - * string. - * - * @return {string} The signed 64-bit integer read from the binary stream. - * Precision will be lost if the integer exceeds 2^53. - */ -jspb.BinaryDecoder.prototype.readInt64String = function() { - var bitsLow = this.readUint32(); - var bitsHigh = this.readUint32(); - return jspb.utils.joinSignedDecimalString(bitsLow, bitsHigh); -}; - - -/** - * Reads a 32-bit floating-point number from the binary stream, using the - * temporary buffer to realign the data. - * - * @return {number} The float read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readFloat = function() { - var bitsLow = this.readUint32(); - var bitsHigh = 0; - return jspb.utils.joinFloat32(bitsLow, bitsHigh); -}; - - -/** - * Reads a 64-bit floating-point number from the binary stream, using the - * temporary buffer to realign the data. - * - * @return {number} The double read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readDouble = function() { - var bitsLow = this.readUint32(); - var bitsHigh = this.readUint32(); - return jspb.utils.joinFloat64(bitsLow, bitsHigh); -}; - - -/** - * Reads a boolean value from the binary stream. - * @return {boolean} The boolean read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readBool = function() { - return !!this.bytes_[this.cursor_++]; -}; - - -/** - * Reads an enum value from the binary stream, which are always encoded as - * signed varints. - * @return {number} The enum value read from the binary stream. - */ -jspb.BinaryDecoder.prototype.readEnum = function() { - return this.readSignedVarint32(); -}; - - -/** - * Reads and parses a UTF-8 encoded unicode string from the stream. - * The code is inspired by maps.vectortown.parse.StreamedDataViewReader. - * Supports codepoints from U+0000 up to U+10FFFF. - * (http://en.wikipedia.org/wiki/UTF-8). - * @param {number} length The length of the string to read. - * @return {string} The decoded string. - */ -jspb.BinaryDecoder.prototype.readString = function(length) { - var bytes = this.bytes_; - var cursor = this.cursor_; - var end = cursor + length; - var codeUnits = []; - - var result = ''; - while (cursor < end) { - var c = bytes[cursor++]; - if (c < 128) { // Regular 7-bit ASCII. - codeUnits.push(c); - } else if (c < 192) { - // UTF-8 continuation mark. We are out of sync. This - // might happen if we attempted to read a character - // with more than four bytes. - continue; - } else if (c < 224) { // UTF-8 with two bytes. - var c2 = bytes[cursor++]; - codeUnits.push(((c & 31) << 6) | (c2 & 63)); - } else if (c < 240) { // UTF-8 with three bytes. - var c2 = bytes[cursor++]; - var c3 = bytes[cursor++]; - codeUnits.push(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - } else if (c < 248) { // UTF-8 with 4 bytes. - var c2 = bytes[cursor++]; - var c3 = bytes[cursor++]; - var c4 = bytes[cursor++]; - // Characters written on 4 bytes have 21 bits for a codepoint. - // We can't fit that on 16bit characters, so we use surrogates. - var codepoint = ((c & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63); - // Surrogates formula from wikipedia. - // 1. Subtract 0x10000 from codepoint - codepoint -= 0x10000; - // 2. Split this into the high 10-bit value and the low 10-bit value - // 3. Add 0xD800 to the high value to form the high surrogate - // 4. Add 0xDC00 to the low value to form the low surrogate: - var low = (codepoint & 1023) + 0xDC00; - var high = ((codepoint >> 10) & 1023) + 0xD800; - codeUnits.push(high, low); - } - - // Avoid exceeding the maximum stack size when calling `apply`. - if (codeUnits.length >= 8192) { - result += String.fromCharCode.apply(null, codeUnits); - codeUnits.length = 0; - } - } - result += goog.crypt.byteArrayToString(codeUnits); - this.cursor_ = cursor; - return result; -}; - - -/** - * Reads and parses a UTF-8 encoded unicode string (with length prefix) from - * the stream. - * @return {string} The decoded string. - */ -jspb.BinaryDecoder.prototype.readStringWithLength = function() { - var length = this.readUnsignedVarint32(); - return this.readString(length); -}; - - -/** - * Reads a block of raw bytes from the binary stream. - * - * @param {number} length The number of bytes to read. - * @return {!Uint8Array} The decoded block of bytes, or an empty block if the - * length was invalid. - */ -jspb.BinaryDecoder.prototype.readBytes = function(length) { - if (length < 0 || - this.cursor_ + length > this.bytes_.length) { - this.error_ = true; - goog.asserts.fail('Invalid byte length!'); - return new Uint8Array(0); - } - - var result = this.bytes_.subarray(this.cursor_, this.cursor_ + length); - - this.cursor_ += length; - goog.asserts.assert(this.cursor_ <= this.end_); - return result; -}; - - -/** - * Reads a 64-bit varint from the stream and returns it as an 8-character - * Unicode string for use as a hash table key. - * - * @return {string} The hash value. - */ -jspb.BinaryDecoder.prototype.readVarintHash64 = function() { - return this.readSplitVarint64(jspb.utils.joinHash64); -}; - - -/** - * Reads a 64-bit fixed-width value from the stream and returns it as an - * 8-character Unicode string for use as a hash table key. - * - * @return {string} The hash value. - */ -jspb.BinaryDecoder.prototype.readFixedHash64 = function() { - var bytes = this.bytes_; - var cursor = this.cursor_; - - var a = bytes[cursor + 0]; - var b = bytes[cursor + 1]; - var c = bytes[cursor + 2]; - var d = bytes[cursor + 3]; - var e = bytes[cursor + 4]; - var f = bytes[cursor + 5]; - var g = bytes[cursor + 6]; - var h = bytes[cursor + 7]; - - this.cursor_ += 8; - - return String.fromCharCode(a, b, c, d, e, f, g, h); -}; diff --git a/js/binary/decoder_test.js b/js/binary/decoder_test.js deleted file mode 100644 index 0fddc4b34..000000000 --- a/js/binary/decoder_test.js +++ /dev/null @@ -1,481 +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. - -/** - * @fileoverview Test cases for jspb's binary protocol buffer decoder. - * - * There are two particular magic numbers that need to be pointed out - - * 2^64-1025 is the largest number representable as both a double and an - * unsigned 64-bit integer, and 2^63-513 is the largest number representable as - * both a double and a signed 64-bit integer. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryDecoder'); -goog.require('jspb.BinaryEncoder'); -goog.require('jspb.utils'); - - -/** - * Tests encoding and decoding of unsigned types. - * @param {Function} readValue - * @param {Function} writeValue - * @param {number} epsilon - * @param {number} upperLimit - * @param {Function} filter - * @suppress {missingProperties|visibility} - */ -function doTestUnsignedValue(readValue, - writeValue, epsilon, upperLimit, filter) { - var encoder = new jspb.BinaryEncoder(); - - // Encode zero and limits. - writeValue.call(encoder, filter(0)); - writeValue.call(encoder, filter(epsilon)); - writeValue.call(encoder, filter(upperLimit)); - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - writeValue.call(encoder, filter(cursor)); - } - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - // Check zero and limits. - assertEquals(filter(0), readValue.call(decoder)); - assertEquals(filter(epsilon), readValue.call(decoder)); - assertEquals(filter(upperLimit), readValue.call(decoder)); - - // Check positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - if (filter(cursor) != readValue.call(decoder)) throw 'fail!'; - } - - // Encoding values outside the valid range should assert. - assertThrows(function() {writeValue.call(encoder, -1);}); - assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);}); -} - - -/** - * Tests encoding and decoding of signed types. - * @param {Function} readValue - * @param {Function} writeValue - * @param {number} epsilon - * @param {number} lowerLimit - * @param {number} upperLimit - * @param {Function} filter - * @suppress {missingProperties} - */ -function doTestSignedValue(readValue, - writeValue, epsilon, lowerLimit, upperLimit, filter) { - var encoder = new jspb.BinaryEncoder(); - - // Encode zero and limits. - writeValue.call(encoder, filter(lowerLimit)); - writeValue.call(encoder, filter(-epsilon)); - writeValue.call(encoder, filter(0)); - writeValue.call(encoder, filter(epsilon)); - writeValue.call(encoder, filter(upperLimit)); - - var inputValues = []; - - // Encode negative values. - for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) { - var val = filter(cursor); - writeValue.call(encoder, val); - inputValues.push(val); - } - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - var val = filter(cursor); - writeValue.call(encoder, val); - inputValues.push(val); - } - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - // Check zero and limits. - assertEquals(filter(lowerLimit), readValue.call(decoder)); - assertEquals(filter(-epsilon), readValue.call(decoder)); - assertEquals(filter(0), readValue.call(decoder)); - assertEquals(filter(epsilon), readValue.call(decoder)); - assertEquals(filter(upperLimit), readValue.call(decoder)); - - // Verify decoded values. - for (var i = 0; i < inputValues.length; i++) { - assertEquals(inputValues[i], readValue.call(decoder)); - } - - // Encoding values outside the valid range should assert. - var pastLowerLimit = lowerLimit * 1.1; - var pastUpperLimit = upperLimit * 1.1; - if (pastLowerLimit !== -Infinity) { - expect(() => void writeValue.call(encoder, pastLowerLimit)).toThrow(); - } - if (pastUpperLimit !== Infinity) { - expect(() => void writeValue.call(encoder, pastUpperLimit)).toThrow(); - } -} - -describe('binaryDecoderTest', function() { - /** - * Tests the decoder instance cache. - */ - it('testInstanceCache', /** @suppress {visibility} */ function() { - // Empty the instance caches. - jspb.BinaryDecoder.instanceCache_ = []; - - // Allocating and then freeing a decoder should put it in the instance - // cache. - jspb.BinaryDecoder.alloc().free(); - - assertEquals(1, jspb.BinaryDecoder.instanceCache_.length); - - // Allocating and then freeing three decoders should leave us with three in - // the cache. - - var decoder1 = jspb.BinaryDecoder.alloc(); - var decoder2 = jspb.BinaryDecoder.alloc(); - var decoder3 = jspb.BinaryDecoder.alloc(); - decoder1.free(); - decoder2.free(); - decoder3.free(); - - assertEquals(3, jspb.BinaryDecoder.instanceCache_.length); - }); - - - describe('varint64', function() { - var /** !jspb.BinaryEncoder */ encoder; - var /** !jspb.BinaryDecoder */ decoder; - - var hashA = String.fromCharCode(0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00); - var hashB = String.fromCharCode(0x12, 0x34, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00); - var hashC = String.fromCharCode(0x12, 0x34, 0x56, 0x78, - 0x87, 0x65, 0x43, 0x21); - var hashD = String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF); - beforeEach(function() { - encoder = new jspb.BinaryEncoder(); - - encoder.writeVarintHash64(hashA); - encoder.writeVarintHash64(hashB); - encoder.writeVarintHash64(hashC); - encoder.writeVarintHash64(hashD); - - encoder.writeFixedHash64(hashA); - encoder.writeFixedHash64(hashB); - encoder.writeFixedHash64(hashC); - encoder.writeFixedHash64(hashD); - - decoder = jspb.BinaryDecoder.alloc(encoder.end()); - }); - - it('reads 64-bit integers as hash strings', function() { - assertEquals(hashA, decoder.readVarintHash64()); - assertEquals(hashB, decoder.readVarintHash64()); - assertEquals(hashC, decoder.readVarintHash64()); - assertEquals(hashD, decoder.readVarintHash64()); - - assertEquals(hashA, decoder.readFixedHash64()); - assertEquals(hashB, decoder.readFixedHash64()); - assertEquals(hashC, decoder.readFixedHash64()); - assertEquals(hashD, decoder.readFixedHash64()); - }); - - it('reads split 64 bit integers', function() { - function hexJoin(bitsLow, bitsHigh) { - return `0x${(bitsHigh >>> 0).toString(16)}:0x${ - (bitsLow >>> 0).toString(16)}`; - } - function hexJoinHash(hash64) { - jspb.utils.splitHash64(hash64); - return hexJoin(jspb.utils.split64Low, jspb.utils.split64High); - } - - expect(decoder.readSplitVarint64(hexJoin)).toEqual(hexJoinHash(hashA)); - expect(decoder.readSplitVarint64(hexJoin)).toEqual(hexJoinHash(hashB)); - expect(decoder.readSplitVarint64(hexJoin)).toEqual(hexJoinHash(hashC)); - expect(decoder.readSplitVarint64(hexJoin)).toEqual(hexJoinHash(hashD)); - - expect(decoder.readSplitFixed64(hexJoin)).toEqual(hexJoinHash(hashA)); - expect(decoder.readSplitFixed64(hexJoin)).toEqual(hexJoinHash(hashB)); - expect(decoder.readSplitFixed64(hexJoin)).toEqual(hexJoinHash(hashC)); - expect(decoder.readSplitFixed64(hexJoin)).toEqual(hexJoinHash(hashD)); - }); - }); - - describe('sint64', function() { - var /** !jspb.BinaryDecoder */ decoder; - - var hashA = - String.fromCharCode(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - var hashB = - String.fromCharCode(0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - var hashC = - String.fromCharCode(0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21); - var hashD = - String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); - beforeEach(function() { - var encoder = new jspb.BinaryEncoder(); - - encoder.writeZigzagVarintHash64(hashA); - encoder.writeZigzagVarintHash64(hashB); - encoder.writeZigzagVarintHash64(hashC); - encoder.writeZigzagVarintHash64(hashD); - - decoder = jspb.BinaryDecoder.alloc(encoder.end()); - }); - - it('reads 64-bit integers as decimal strings', function() { - const signed = true; - expect(decoder.readZigzagVarint64String()) - .toEqual(jspb.utils.hash64ToDecimalString(hashA, signed)); - expect(decoder.readZigzagVarint64String()) - .toEqual(jspb.utils.hash64ToDecimalString(hashB, signed)); - expect(decoder.readZigzagVarint64String()) - .toEqual(jspb.utils.hash64ToDecimalString(hashC, signed)); - expect(decoder.readZigzagVarint64String()) - .toEqual(jspb.utils.hash64ToDecimalString(hashD, signed)); - }); - - it('reads 64-bit integers as hash strings', function() { - expect(decoder.readZigzagVarintHash64()).toEqual(hashA); - expect(decoder.readZigzagVarintHash64()).toEqual(hashB); - expect(decoder.readZigzagVarintHash64()).toEqual(hashC); - expect(decoder.readZigzagVarintHash64()).toEqual(hashD); - }); - - it('reads split 64 bit zigzag integers', function() { - function hexJoin(bitsLow, bitsHigh) { - return `0x${(bitsHigh >>> 0).toString(16)}:0x${ - (bitsLow >>> 0).toString(16)}`; - } - function hexJoinHash(hash64) { - jspb.utils.splitHash64(hash64); - return hexJoin(jspb.utils.split64Low, jspb.utils.split64High); - } - - expect(decoder.readSplitZigzagVarint64(hexJoin)) - .toEqual(hexJoinHash(hashA)); - expect(decoder.readSplitZigzagVarint64(hexJoin)) - .toEqual(hexJoinHash(hashB)); - expect(decoder.readSplitZigzagVarint64(hexJoin)) - .toEqual(hexJoinHash(hashC)); - expect(decoder.readSplitZigzagVarint64(hexJoin)) - .toEqual(hexJoinHash(hashD)); - }); - - it('does zigzag encoding properly', function() { - // Test cases directly from the protobuf dev guide. - // https://engdoc.corp.google.com/eng/howto/protocolbuffers/developerguide/encoding.shtml?cl=head#types - var testCases = [ - {original: '0', zigzag: '0'}, - {original: '-1', zigzag: '1'}, - {original: '1', zigzag: '2'}, - {original: '-2', zigzag: '3'}, - {original: '2147483647', zigzag: '4294967294'}, - {original: '-2147483648', zigzag: '4294967295'}, - // 64-bit extremes, not in dev guide. - {original: '9223372036854775807', zigzag: '18446744073709551614'}, - {original: '-9223372036854775808', zigzag: '18446744073709551615'}, - // None of the above catch: bitsLow < 0 && bitsHigh > 0 && bitsHigh < - // 0x1FFFFF. The following used to be broken. - {original: '72000000000', zigzag: '144000000000'}, - ]; - var encoder = new jspb.BinaryEncoder(); - testCases.forEach(function(c) { - encoder.writeZigzagVarint64String(c.original); - }); - var buffer = encoder.end(); - var zigzagDecoder = jspb.BinaryDecoder.alloc(buffer); - var varintDecoder = jspb.BinaryDecoder.alloc(buffer); - testCases.forEach(function(c) { - expect(zigzagDecoder.readZigzagVarint64String()).toEqual(c.original); - expect(varintDecoder.readUnsignedVarint64String()).toEqual(c.zigzag); - }); - }); - }); - - /** - * Tests reading and writing large strings - */ - it('testLargeStrings', function() { - var encoder = new jspb.BinaryEncoder(); - - var len = 150000; - var long_string = ''; - for (var i = 0; i < len; i++) { - long_string += 'a'; - } - - encoder.writeString(long_string); - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - assertEquals(long_string, decoder.readString(len)); - }); - - /** - * Test encoding and decoding utf-8. - */ - it('testUtf8', function() { - var encoder = new jspb.BinaryEncoder(); - - var ascii = "ASCII should work in 3, 2, 1..."; - var utf8_two_bytes = "©"; - var utf8_three_bytes = "❄"; - var utf8_four_bytes = "😁"; - - encoder.writeString(ascii); - encoder.writeString(utf8_two_bytes); - encoder.writeString(utf8_three_bytes); - encoder.writeString(utf8_four_bytes); - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - assertEquals(ascii, decoder.readString(ascii.length)); - assertEquals(utf8_two_bytes, decoder.readString(utf8_two_bytes.length)); - assertEquals(utf8_three_bytes, decoder.readString(utf8_three_bytes.length)); - assertEquals(utf8_four_bytes, decoder.readString(utf8_four_bytes.length)); - }); - - /** - * Verifies that misuse of the decoder class triggers assertions. - */ - it('testDecodeErrors', function() { - // Reading a value past the end of the stream should trigger an assertion. - var decoder = jspb.BinaryDecoder.alloc([0, 1, 2]); - assertThrows(function() {decoder.readUint64()}); - - // Overlong varints should trigger assertions. - decoder.setBlock([255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0]); - assertThrows(function() {decoder.readUnsignedVarint64()}); - decoder.reset(); - assertThrows(function() {decoder.readSignedVarint64()}); - decoder.reset(); - assertThrows(function() {decoder.readZigzagVarint64()}); - decoder.reset(); - assertThrows(function() {decoder.readUnsignedVarint32()}); - }); - - - /** - * Tests encoding and decoding of unsigned integers. - */ - it('testUnsignedIntegers', function() { - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint8, - jspb.BinaryEncoder.prototype.writeUint8, - 1, 0xFF, Math.round); - - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint16, - jspb.BinaryEncoder.prototype.writeUint16, - 1, 0xFFFF, Math.round); - - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint32, - jspb.BinaryEncoder.prototype.writeUint32, - 1, 0xFFFFFFFF, Math.round); - - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint64, - jspb.BinaryEncoder.prototype.writeUint64, - 1, Math.pow(2, 64) - 1025, Math.round); - }); - - - /** - * Tests encoding and decoding of signed integers. - */ - it('testSignedIntegers', function() { - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt8, - jspb.BinaryEncoder.prototype.writeInt8, - 1, -0x80, 0x7F, Math.round); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt16, - jspb.BinaryEncoder.prototype.writeInt16, - 1, -0x8000, 0x7FFF, Math.round); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt32, - jspb.BinaryEncoder.prototype.writeInt32, - 1, -0x80000000, 0x7FFFFFFF, Math.round); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt64, - jspb.BinaryEncoder.prototype.writeInt64, - 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); - }); - - - /** - * Tests encoding and decoding of floats. - */ - it('testFloats', function() { - /** - * @param {number} x - * @return {number} - */ - function truncate(x) { - var temp = new Float32Array(1); - temp[0] = x; - return temp[0]; - } - doTestSignedValue( - jspb.BinaryDecoder.prototype.readFloat, - jspb.BinaryEncoder.prototype.writeFloat, - jspb.BinaryConstants.FLOAT32_EPS, - -jspb.BinaryConstants.FLOAT32_MAX, - jspb.BinaryConstants.FLOAT32_MAX, - truncate); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readDouble, - jspb.BinaryEncoder.prototype.writeDouble, - jspb.BinaryConstants.FLOAT64_EPS * 10, - -jspb.BinaryConstants.FLOAT64_MAX, - jspb.BinaryConstants.FLOAT64_MAX, - function(x) { return x; }); - }); -}); diff --git a/js/binary/encoder.js b/js/binary/encoder.js deleted file mode 100644 index 726481b2c..000000000 --- a/js/binary/encoder.js +++ /dev/null @@ -1,510 +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. - -/** - * @fileoverview BinaryEncode defines methods for encoding Javascript values - * into arrays of bytes compatible with the Protocol Buffer wire format. - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.provide('jspb.BinaryEncoder'); - -goog.require('goog.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.utils'); - - - -/** - * BinaryEncoder implements encoders for all the wire types specified in - * https://developers.google.com/protocol-buffers/docs/encoding. - * - * @constructor - * @struct - */ -jspb.BinaryEncoder = function() { - /** @private {!Array} */ - this.buffer_ = []; -}; - - -/** - * @return {number} - */ -jspb.BinaryEncoder.prototype.length = function() { - return this.buffer_.length; -}; - - -/** - * @return {!Array} - */ -jspb.BinaryEncoder.prototype.end = function() { - var buffer = this.buffer_; - this.buffer_ = []; - return buffer; -}; - - -/** - * Encodes a 64-bit integer in 32:32 split representation into its wire-format - * varint representation and stores it in the buffer. - * @param {number} lowBits The low 32 bits of the int. - * @param {number} highBits The high 32 bits of the int. - */ -jspb.BinaryEncoder.prototype.writeSplitVarint64 = function(lowBits, highBits) { - goog.asserts.assert(lowBits == Math.floor(lowBits)); - goog.asserts.assert(highBits == Math.floor(highBits)); - goog.asserts.assert((lowBits >= 0) && - (lowBits < jspb.BinaryConstants.TWO_TO_32)); - goog.asserts.assert((highBits >= 0) && - (highBits < jspb.BinaryConstants.TWO_TO_32)); - - // Break the binary representation into chunks of 7 bits, set the 8th bit - // in each chunk if it's not the final chunk, and append to the result. - while (highBits > 0 || lowBits > 127) { - this.buffer_.push((lowBits & 0x7f) | 0x80); - lowBits = ((lowBits >>> 7) | (highBits << 25)) >>> 0; - highBits = highBits >>> 7; - } - this.buffer_.push(lowBits); -}; - - -/** - * Encodes a 64-bit integer in 32:32 split representation into its wire-format - * fixed representation and stores it in the buffer. - * @param {number} lowBits The low 32 bits of the int. - * @param {number} highBits The high 32 bits of the int. - */ -jspb.BinaryEncoder.prototype.writeSplitFixed64 = function(lowBits, highBits) { - goog.asserts.assert(lowBits == Math.floor(lowBits)); - goog.asserts.assert(highBits == Math.floor(highBits)); - goog.asserts.assert((lowBits >= 0) && - (lowBits < jspb.BinaryConstants.TWO_TO_32)); - goog.asserts.assert((highBits >= 0) && - (highBits < jspb.BinaryConstants.TWO_TO_32)); - this.writeUint32(lowBits); - this.writeUint32(highBits); -}; - - -/** - * Encodes a 32-bit unsigned integer into its wire-format varint representation - * and stores it in the buffer. - * @param {number} value The integer to convert. - */ -jspb.BinaryEncoder.prototype.writeUnsignedVarint32 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= 0) && - (value < jspb.BinaryConstants.TWO_TO_32)); - - while (value > 127) { - this.buffer_.push((value & 0x7f) | 0x80); - value = value >>> 7; - } - - this.buffer_.push(value); -}; - - -/** - * Encodes a 32-bit signed integer into its wire-format varint representation - * and stores it in the buffer. - * @param {number} value The integer to convert. - */ -jspb.BinaryEncoder.prototype.writeSignedVarint32 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && - (value < jspb.BinaryConstants.TWO_TO_31)); - - // Use the unsigned version if the value is not negative. - if (value >= 0) { - this.writeUnsignedVarint32(value); - return; - } - - // Write nine bytes with a _signed_ right shift so we preserve the sign bit. - for (var i = 0; i < 9; i++) { - this.buffer_.push((value & 0x7f) | 0x80); - value = value >> 7; - } - - // The above loop writes out 63 bits, so the last byte is always the sign bit - // which is always set for negative numbers. - this.buffer_.push(1); -}; - - -/** - * Encodes a 64-bit unsigned integer into its wire-format varint representation - * and stores it in the buffer. Integers that are not representable in 64 bits - * will be truncated. - * @param {number} value The integer to convert. - */ -jspb.BinaryEncoder.prototype.writeUnsignedVarint64 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= 0) && - (value < jspb.BinaryConstants.TWO_TO_64)); - jspb.utils.splitInt64(value); - this.writeSplitVarint64(jspb.utils.split64Low, - jspb.utils.split64High); -}; - - -/** - * Encodes a 64-bit signed integer into its wire-format varint representation - * and stores it in the buffer. Integers that are not representable in 64 bits - * will be truncated. - * @param {number} value The integer to convert. - */ -jspb.BinaryEncoder.prototype.writeSignedVarint64 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && - (value < jspb.BinaryConstants.TWO_TO_63)); - jspb.utils.splitInt64(value); - this.writeSplitVarint64(jspb.utils.split64Low, - jspb.utils.split64High); -}; - - -/** - * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint - * representation and stores it in the buffer. - * @param {number} value The integer to convert. - */ -jspb.BinaryEncoder.prototype.writeZigzagVarint32 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && - (value < jspb.BinaryConstants.TWO_TO_31)); - this.writeUnsignedVarint32(((value << 1) ^ (value >> 31)) >>> 0); -}; - - -/** - * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint - * representation and stores it in the buffer. Integers not representable in 64 - * bits will be truncated. - * @param {number} value The integer to convert. - */ -jspb.BinaryEncoder.prototype.writeZigzagVarint64 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && - (value < jspb.BinaryConstants.TWO_TO_63)); - jspb.utils.splitZigzag64(value); - this.writeSplitVarint64(jspb.utils.split64Low, - jspb.utils.split64High); -}; - - -/** - * Encodes a JavaScript decimal string into its wire-format, zigzag-encoded - * varint representation and stores it in the buffer. Integers not representable - * in 64 bits will be truncated. - * @param {string} value The integer to convert. - */ -jspb.BinaryEncoder.prototype.writeZigzagVarint64String = function(value) { - this.writeZigzagVarintHash64(jspb.utils.decimalStringToHash64(value)); -}; - - -/** - * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the - * buffer as a zigzag varint. - * @param {string} hash The hash to write. - */ -jspb.BinaryEncoder.prototype.writeZigzagVarintHash64 = function(hash) { - var self = this; - jspb.utils.splitHash64(hash); - jspb.utils.toZigzag64( - jspb.utils.split64Low, jspb.utils.split64High, function(lo, hi) { - self.writeSplitVarint64(lo >>> 0, hi >>> 0); - }); -}; - - -/** - * Writes an 8-bit unsigned integer to the buffer. Numbers outside the range - * [0,2^8) will be truncated. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeUint8 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= 0) && (value < 256)); - this.buffer_.push((value >>> 0) & 0xFF); -}; - - -/** - * Writes a 16-bit unsigned integer to the buffer. Numbers outside the - * range [0,2^16) will be truncated. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeUint16 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= 0) && (value < 65536)); - this.buffer_.push((value >>> 0) & 0xFF); - this.buffer_.push((value >>> 8) & 0xFF); -}; - - -/** - * Writes a 32-bit unsigned integer to the buffer. Numbers outside the - * range [0,2^32) will be truncated. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeUint32 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= 0) && - (value < jspb.BinaryConstants.TWO_TO_32)); - this.buffer_.push((value >>> 0) & 0xFF); - this.buffer_.push((value >>> 8) & 0xFF); - this.buffer_.push((value >>> 16) & 0xFF); - this.buffer_.push((value >>> 24) & 0xFF); -}; - - -/** - * Writes a 64-bit unsigned integer to the buffer. Numbers outside the - * range [0,2^64) will be truncated. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeUint64 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= 0) && - (value < jspb.BinaryConstants.TWO_TO_64)); - jspb.utils.splitUint64(value); - this.writeUint32(jspb.utils.split64Low); - this.writeUint32(jspb.utils.split64High); -}; - - -/** - * Writes an 8-bit integer to the buffer. Numbers outside the range - * [-2^7,2^7) will be truncated. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeInt8 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -128) && (value < 128)); - this.buffer_.push((value >>> 0) & 0xFF); -}; - - -/** - * Writes a 16-bit integer to the buffer. Numbers outside the range - * [-2^15,2^15) will be truncated. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeInt16 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -32768) && (value < 32768)); - this.buffer_.push((value >>> 0) & 0xFF); - this.buffer_.push((value >>> 8) & 0xFF); -}; - - -/** - * Writes a 32-bit integer to the buffer. Numbers outside the range - * [-2^31,2^31) will be truncated. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeInt32 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && - (value < jspb.BinaryConstants.TWO_TO_31)); - this.buffer_.push((value >>> 0) & 0xFF); - this.buffer_.push((value >>> 8) & 0xFF); - this.buffer_.push((value >>> 16) & 0xFF); - this.buffer_.push((value >>> 24) & 0xFF); -}; - - -/** - * Writes a 64-bit integer to the buffer. Numbers outside the range - * [-2^63,2^63) will be truncated. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeInt64 = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && - (value < jspb.BinaryConstants.TWO_TO_63)); - jspb.utils.splitInt64(value); - this.writeSplitFixed64(jspb.utils.split64Low, jspb.utils.split64High); -}; - - -/** - * Writes a 64-bit integer decimal strings to the buffer. Numbers outside the - * range [-2^63,2^63) will be truncated. - * @param {string} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeInt64String = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((+value >= -jspb.BinaryConstants.TWO_TO_63) && - (+value < jspb.BinaryConstants.TWO_TO_63)); - jspb.utils.splitHash64(jspb.utils.decimalStringToHash64(value)); - this.writeSplitFixed64(jspb.utils.split64Low, jspb.utils.split64High); -}; - - -/** - * Writes a single-precision floating point value to the buffer. Numbers - * requiring more than 32 bits of precision will be truncated. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeFloat = function(value) { - goog.asserts.assert( - value === Infinity || value === -Infinity || isNaN(value) || - ((value >= -jspb.BinaryConstants.FLOAT32_MAX) && - (value <= jspb.BinaryConstants.FLOAT32_MAX))); - jspb.utils.splitFloat32(value); - this.writeUint32(jspb.utils.split64Low); -}; - - -/** - * Writes a double-precision floating point value to the buffer. As this is - * the native format used by JavaScript, no precision will be lost. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeDouble = function(value) { - goog.asserts.assert( - value === Infinity || value === -Infinity || isNaN(value) || - ((value >= -jspb.BinaryConstants.FLOAT64_MAX) && - (value <= jspb.BinaryConstants.FLOAT64_MAX))); - jspb.utils.splitFloat64(value); - this.writeUint32(jspb.utils.split64Low); - this.writeUint32(jspb.utils.split64High); -}; - - -/** - * Writes a boolean value to the buffer as a varint. We allow numbers as input - * because the JSPB code generator uses 0/1 instead of true/false to save space - * in the string representation of the proto. - * @param {boolean|number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeBool = function(value) { - goog.asserts.assert(typeof value === 'boolean' || typeof value === 'number'); - this.buffer_.push(value ? 1 : 0); -}; - - -/** - * Writes an enum value to the buffer as a varint. - * @param {number} value The value to write. - */ -jspb.BinaryEncoder.prototype.writeEnum = function(value) { - goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && - (value < jspb.BinaryConstants.TWO_TO_31)); - this.writeSignedVarint32(value); -}; - - -/** - * Writes an arbitrary byte array to the buffer. - * @param {!Uint8Array} bytes The array of bytes to write. - */ -jspb.BinaryEncoder.prototype.writeBytes = function(bytes) { - this.buffer_.push.apply(this.buffer_, bytes); -}; - - -/** - * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the - * buffer as a varint. - * @param {string} hash The hash to write. - */ -jspb.BinaryEncoder.prototype.writeVarintHash64 = function(hash) { - jspb.utils.splitHash64(hash); - this.writeSplitVarint64(jspb.utils.split64Low, - jspb.utils.split64High); -}; - - -/** - * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the - * buffer as a fixed64. - * @param {string} hash The hash to write. - */ -jspb.BinaryEncoder.prototype.writeFixedHash64 = function(hash) { - jspb.utils.splitHash64(hash); - this.writeUint32(jspb.utils.split64Low); - this.writeUint32(jspb.utils.split64High); -}; - - -/** - * Writes a UTF16 Javascript string to the buffer encoded as UTF8. - * TODO(aappleby): Add support for surrogate pairs, reject unpaired surrogates. - * @param {string} value The string to write. - * @return {number} The number of bytes used to encode the string. - */ -jspb.BinaryEncoder.prototype.writeString = function(value) { - var oldLength = this.buffer_.length; - - for (var i = 0; i < value.length; i++) { - - var c = value.charCodeAt(i); - - if (c < 128) { - this.buffer_.push(c); - } else if (c < 2048) { - this.buffer_.push((c >> 6) | 192); - this.buffer_.push((c & 63) | 128); - } else if (c < 65536) { - // Look for surrogates - if (c >= 0xD800 && c <= 0xDBFF && i + 1 < value.length) { - var second = value.charCodeAt(i + 1); - if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate - // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae - c = (c - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; - - this.buffer_.push((c >> 18) | 240); - this.buffer_.push(((c >> 12) & 63 ) | 128); - this.buffer_.push(((c >> 6) & 63) | 128); - this.buffer_.push((c & 63) | 128); - i++; - } - } - else { - this.buffer_.push((c >> 12) | 224); - this.buffer_.push(((c >> 6) & 63) | 128); - this.buffer_.push((c & 63) | 128); - } - } - } - - var length = this.buffer_.length - oldLength; - return length; -}; diff --git a/js/binary/message_test.js b/js/binary/message_test.js deleted file mode 100644 index 4edc666b8..000000000 --- a/js/binary/message_test.js +++ /dev/null @@ -1,60 +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. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - -goog.setTestOnly(); - -goog.require('goog.testing.asserts'); - -// CommonJS-LoadFromFile: test_pb proto.jspb.test -goog.require('proto.jspb.test.Deeply.Nested.Message'); - -// CommonJS-LoadFromFile: test2_pb proto.jspb.test -goog.require('proto.jspb.test.ForeignNestedFieldMessage'); - -describe('Message test suite', function() { - // Verify that we can successfully use a field referring to a nested message - // from a different .proto file. - it('testForeignNestedMessage', function() { - var msg = new proto.jspb.test.ForeignNestedFieldMessage(); - var nested = new proto.jspb.test.Deeply.Nested.Message(); - nested.setCount(5); - msg.setDeeplyNestedMessage(nested); - assertEquals(5, msg.getDeeplyNestedMessage().getCount()); - - // After a serialization-deserialization round trip we should get back the - // same data we started with. - var serialized = msg.serializeBinary(); - var deserialized = - proto.jspb.test.ForeignNestedFieldMessage.deserializeBinary(serialized); - assertEquals(5, deserialized.getDeeplyNestedMessage().getCount()); - }); -}); diff --git a/js/binary/proto_test.js b/js/binary/proto_test.js deleted file mode 100644 index aee327a8e..000000000 --- a/js/binary/proto_test.js +++ /dev/null @@ -1,665 +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. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - -goog.require('goog.crypt.base64'); -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryWriter'); -goog.require('jspb.Message'); - -// CommonJS-LoadFromFile: ../testbinary_pb proto.jspb.test -goog.require('proto.jspb.test.ExtendsWithMessage'); -goog.require('proto.jspb.test.ForeignEnum'); -goog.require('proto.jspb.test.ForeignMessage'); -goog.require('proto.jspb.test.TestAllTypes'); -goog.require('proto.jspb.test.TestExtendable'); -goog.require('proto.jspb.test.extendOptionalBool'); -goog.require('proto.jspb.test.extendOptionalBytes'); -goog.require('proto.jspb.test.extendOptionalDouble'); -goog.require('proto.jspb.test.extendOptionalFixed32'); -goog.require('proto.jspb.test.extendOptionalFixed64'); -goog.require('proto.jspb.test.extendOptionalFloat'); -goog.require('proto.jspb.test.extendOptionalForeignEnum'); -goog.require('proto.jspb.test.extendOptionalInt32'); -goog.require('proto.jspb.test.extendOptionalInt64'); -goog.require('proto.jspb.test.extendOptionalSfixed32'); -goog.require('proto.jspb.test.extendOptionalSfixed64'); -goog.require('proto.jspb.test.extendOptionalSint32'); -goog.require('proto.jspb.test.extendOptionalSint64'); -goog.require('proto.jspb.test.extendOptionalString'); -goog.require('proto.jspb.test.extendOptionalUint32'); -goog.require('proto.jspb.test.extendOptionalUint64'); -goog.require('proto.jspb.test.extendPackedRepeatedBoolList'); -goog.require('proto.jspb.test.extendPackedRepeatedDoubleList'); -goog.require('proto.jspb.test.extendPackedRepeatedFixed32List'); -goog.require('proto.jspb.test.extendPackedRepeatedFixed64List'); -goog.require('proto.jspb.test.extendPackedRepeatedFloatList'); -goog.require('proto.jspb.test.extendPackedRepeatedForeignEnumList'); -goog.require('proto.jspb.test.extendPackedRepeatedInt32List'); -goog.require('proto.jspb.test.extendPackedRepeatedInt64List'); -goog.require('proto.jspb.test.extendPackedRepeatedSfixed32List'); -goog.require('proto.jspb.test.extendPackedRepeatedSfixed64List'); -goog.require('proto.jspb.test.extendPackedRepeatedSint32List'); -goog.require('proto.jspb.test.extendPackedRepeatedSint64List'); -goog.require('proto.jspb.test.extendPackedRepeatedUint32List'); -goog.require('proto.jspb.test.extendPackedRepeatedUint64List'); -goog.require('proto.jspb.test.extendRepeatedBoolList'); -goog.require('proto.jspb.test.extendRepeatedBytesList'); -goog.require('proto.jspb.test.extendRepeatedDoubleList'); -goog.require('proto.jspb.test.extendRepeatedFixed32List'); -goog.require('proto.jspb.test.extendRepeatedFixed64List'); -goog.require('proto.jspb.test.extendRepeatedFloatList'); -goog.require('proto.jspb.test.extendRepeatedForeignEnumList'); -goog.require('proto.jspb.test.extendRepeatedInt32List'); -goog.require('proto.jspb.test.extendRepeatedInt64List'); -goog.require('proto.jspb.test.extendRepeatedSfixed32List'); -goog.require('proto.jspb.test.extendRepeatedSfixed64List'); -goog.require('proto.jspb.test.extendRepeatedSint32List'); -goog.require('proto.jspb.test.extendRepeatedSint64List'); -goog.require('proto.jspb.test.extendRepeatedStringList'); -goog.require('proto.jspb.test.extendRepeatedUint32List'); -goog.require('proto.jspb.test.extendRepeatedUint64List'); - -// CommonJS-LoadFromFile: ../node_modules/google-protobuf/google/protobuf/any_pb proto.google.protobuf -goog.require('proto.google.protobuf.Any'); - - -var suite = {}; - -var BYTES = new Uint8Array([1, 2, 8, 9]); - -var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES); - - -/** - * Helper: fill all fields on a TestAllTypes message. - * @param {proto.jspb.test.TestAllTypes} msg - */ -function fillAllFields(msg) { - msg.setOptionalInt32(-42); - // can be exactly represented by JS number (64-bit double, i.e., 52-bit - // mantissa). - msg.setOptionalInt64(-0x7fffffff00000000); - msg.setOptionalUint32(0x80000000); - msg.setOptionalUint64(0xf000000000000000); - msg.setOptionalSint32(-100); - msg.setOptionalSint64(-0x8000000000000000); - msg.setOptionalFixed32(1234); - msg.setOptionalFixed64(0x1234567800000000); - msg.setOptionalSfixed32(-1234); - msg.setOptionalSfixed64(-0x1234567800000000); - msg.setOptionalFloat(1.5); - msg.setOptionalDouble(-1.5); - msg.setOptionalBool(true); - msg.setOptionalString('hello world'); - msg.setOptionalBytes(BYTES); - msg.setOptionalGroup(new proto.jspb.test.TestAllTypes.OptionalGroup()); - msg.getOptionalGroup().setA(100); - var submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(16); - msg.setOptionalForeignMessage(submsg); - msg.setOptionalForeignEnum(proto.jspb.test.ForeignEnum.FOREIGN_FOO); - msg.setOneofString('oneof'); - - - msg.setRepeatedInt32List([-42]); - msg.setRepeatedInt64List([-0x7fffffff00000000]); - msg.setRepeatedUint32List([0x80000000]); - msg.setRepeatedUint64List([0xf000000000000000]); - msg.setRepeatedSint32List([-100]); - msg.setRepeatedSint64List([-0x8000000000000000]); - msg.setRepeatedFixed32List([1234]); - msg.setRepeatedFixed64List([0x1234567800000000]); - msg.setRepeatedSfixed32List([-1234]); - msg.setRepeatedSfixed64List([-0x1234567800000000]); - msg.setRepeatedFloatList([1.5]); - msg.setRepeatedDoubleList([-1.5]); - msg.setRepeatedBoolList([true]); - msg.setRepeatedStringList(['hello world']); - msg.setRepeatedBytesList([BYTES, BYTES]); - msg.setRepeatedGroupList([new proto.jspb.test.TestAllTypes.RepeatedGroup()]); - msg.getRepeatedGroupList()[0].setA(100); - submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(1000); - msg.setRepeatedForeignMessageList([submsg]); - msg.setRepeatedForeignEnumList([proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - msg.setPackedRepeatedInt32List([-42]); - msg.setPackedRepeatedInt64List([-0x7fffffff00000000]); - msg.setPackedRepeatedUint32List([0x80000000]); - msg.setPackedRepeatedUint64List([0xf000000000000000]); - msg.setPackedRepeatedSint32List([-100]); - msg.setPackedRepeatedSint64List([-0x8000000000000000]); - msg.setPackedRepeatedFixed32List([1234]); - msg.setPackedRepeatedFixed64List([0x1234567800000000]); - msg.setPackedRepeatedSfixed32List([-1234]); - msg.setPackedRepeatedSfixed64List([-0x1234567800000000]); - msg.setPackedRepeatedFloatList([1.5]); - msg.setPackedRepeatedDoubleList([-1.5]); - msg.setPackedRepeatedBoolList([true]); - -} - - -/** - * Helper: compare a bytes field to an expected value - * @param {Uint8Array|string} arr - * @param {Uint8Array} expected - * @return {boolean} - */ -function bytesCompare(arr, expected) { - if (typeof arr === 'string') { - arr = goog.crypt.base64.decodeStringToUint8Array(arr); - } - if (arr.length != expected.length) { - return false; - } - for (var i = 0; i < arr.length; i++) { - if (arr[i] != expected[i]) { - return false; - } - } - return true; -} - - -/** - * Helper: verify contents of given TestAllTypes message as set by - * fillAllFields(). - * @param {proto.jspb.test.TestAllTypes} original - * @param {proto.jspb.test.TestAllTypes} copy - */ -function checkAllFields(original, copy) { - assertEquals(copy.getOptionalInt32(), -42); - assertEquals(copy.getOptionalInt64(), -0x7fffffff00000000); - assertEquals(copy.getOptionalUint32(), 0x80000000); - assertEquals(copy.getOptionalUint64(), 0xf000000000000000); - assertEquals(copy.getOptionalSint32(), -100); - assertEquals(copy.getOptionalSint64(), -0x8000000000000000); - assertEquals(copy.getOptionalFixed32(), 1234); - assertEquals(copy.getOptionalFixed64(), 0x1234567800000000); - assertEquals(copy.getOptionalSfixed32(), -1234); - assertEquals(copy.getOptionalSfixed64(), -0x1234567800000000); - assertEquals(copy.getOptionalFloat(), 1.5); - assertEquals(copy.getOptionalDouble(), -1.5); - assertEquals(copy.getOptionalBool(), true); - assertEquals(copy.getOptionalString(), 'hello world'); - assertEquals(true, bytesCompare(copy.getOptionalBytes(), BYTES)); - assertEquals(true, bytesCompare(copy.getOptionalBytes_asU8(), BYTES)); - assertEquals( - copy.getOptionalBytes_asB64(), goog.crypt.base64.encodeByteArray(BYTES)); - - assertEquals(copy.getOptionalGroup().getA(), 100); - assertEquals(copy.getOptionalForeignMessage().getC(), 16); - assertEquals(copy.getOptionalForeignEnum(), - proto.jspb.test.ForeignEnum.FOREIGN_FOO); - - - assertEquals(copy.getOneofString(), 'oneof'); - assertEquals(copy.getOneofFieldCase(), - proto.jspb.test.TestAllTypes.OneofFieldCase.ONEOF_STRING); - - assertElementsEquals(copy.getRepeatedInt32List(), [-42]); - assertElementsEquals(copy.getRepeatedInt64List(), [-0x7fffffff00000000]); - assertElementsEquals(copy.getRepeatedUint32List(), [0x80000000]); - assertElementsEquals(copy.getRepeatedUint64List(), [0xf000000000000000]); - assertElementsEquals(copy.getRepeatedSint32List(), [-100]); - assertElementsEquals(copy.getRepeatedSint64List(), [-0x8000000000000000]); - assertElementsEquals(copy.getRepeatedFixed32List(), [1234]); - assertElementsEquals(copy.getRepeatedFixed64List(), [0x1234567800000000]); - assertElementsEquals(copy.getRepeatedSfixed32List(), [-1234]); - assertElementsEquals(copy.getRepeatedSfixed64List(), [-0x1234567800000000]); - assertElementsEquals(copy.getRepeatedFloatList(), [1.5]); - assertElementsEquals(copy.getRepeatedDoubleList(), [-1.5]); - assertElementsEquals(copy.getRepeatedBoolList(), [true]); - assertElementsEquals(copy.getRepeatedStringList(), ['hello world']); - assertEquals(copy.getRepeatedBytesList().length, 2); - assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[0], BYTES)); - assertEquals(true, bytesCompare(copy.getRepeatedBytesList()[0], BYTES)); - assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[1], BYTES)); - assertEquals(copy.getRepeatedBytesList_asB64()[0], BYTES_B64); - assertEquals(copy.getRepeatedBytesList_asB64()[1], BYTES_B64); - assertEquals(copy.getRepeatedGroupList().length, 1); - assertEquals(copy.getRepeatedGroupList()[0].getA(), 100); - assertEquals(copy.getRepeatedForeignMessageList().length, 1); - assertEquals(copy.getRepeatedForeignMessageList()[0].getC(), 1000); - assertElementsEquals(copy.getRepeatedForeignEnumList(), - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - assertElementsEquals(copy.getPackedRepeatedInt32List(), [-42]); - assertElementsEquals(copy.getPackedRepeatedInt64List(), - [-0x7fffffff00000000]); - assertElementsEquals(copy.getPackedRepeatedUint32List(), [0x80000000]); - assertElementsEquals(copy.getPackedRepeatedUint64List(), - [0xf000000000000000]); - assertElementsEquals(copy.getPackedRepeatedSint32List(), [-100]); - assertElementsEquals(copy.getPackedRepeatedSint64List(), - [-0x8000000000000000]); - assertElementsEquals(copy.getPackedRepeatedFixed32List(), [1234]); - assertElementsEquals(copy.getPackedRepeatedFixed64List(), - [0x1234567800000000]); - assertElementsEquals(copy.getPackedRepeatedSfixed32List(), [-1234]); - assertElementsEquals(copy.getPackedRepeatedSfixed64List(), - [-0x1234567800000000]); - assertElementsEquals(copy.getPackedRepeatedFloatList(), [1.5]); - assertElementsEquals(copy.getPackedRepeatedDoubleList(), [-1.5]); - - - // Check last so we get more granular errors first. - assertTrue(jspb.Message.equals(original, copy)); -} - - -/** - * Helper: verify that all expected extensions are present. - * @param {!proto.jspb.test.TestExtendable} msg - */ -function checkExtensions(msg) { - assertEquals(0, msg.getExtension(proto.jspb.test.extendOptionalInt32)); - assertEquals(-0x7fffffff00000000, - msg.getExtension(proto.jspb.test.extendOptionalInt64)); - assertEquals(0x80000000, - msg.getExtension(proto.jspb.test.extendOptionalUint32)); - assertEquals(0xf000000000000000, - msg.getExtension(proto.jspb.test.extendOptionalUint64)); - assertEquals(-100, - msg.getExtension(proto.jspb.test.extendOptionalSint32)); - assertEquals(-0x8000000000000000, - msg.getExtension(proto.jspb.test.extendOptionalSint64)); - assertEquals(1234, - msg.getExtension(proto.jspb.test.extendOptionalFixed32)); - assertEquals(0x1234567800000000, - msg.getExtension(proto.jspb.test.extendOptionalFixed64)); - assertEquals(-1234, - msg.getExtension(proto.jspb.test.extendOptionalSfixed32)); - assertEquals(-0x1234567800000000, - msg.getExtension(proto.jspb.test.extendOptionalSfixed64)); - assertEquals(1.5, - msg.getExtension(proto.jspb.test.extendOptionalFloat)); - assertEquals(-1.5, - msg.getExtension(proto.jspb.test.extendOptionalDouble)); - assertEquals(true, - msg.getExtension(proto.jspb.test.extendOptionalBool)); - assertEquals('hello world', - msg.getExtension(proto.jspb.test.extendOptionalString)); - assertEquals( - true, bytesCompare( - msg.getExtension(proto.jspb.test.extendOptionalBytes), BYTES)); - assertEquals(16, - msg.getExtension( - proto.jspb.test.ExtendsWithMessage.optionalExtension).getFoo()); - - - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedInt32List), - [-42]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedInt64List), - [-0x7fffffff00000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedUint32List), - [0x80000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedUint64List), - [0xf000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSint32List), - [-100]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSint64List), - [-0x8000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedFixed32List), - [1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedFixed64List), - [0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSfixed32List), - [-1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSfixed64List), - [-0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedFloatList), - [1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedDoubleList), - [-1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedBoolList), - [true]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedStringList), - ['hello world']); - assertEquals( - true, - bytesCompare( - msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0], BYTES)); - assertEquals(1000, - msg.getExtension( - proto.jspb.test.ExtendsWithMessage.repeatedExtensionList)[0] - .getFoo()); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedForeignEnumList), - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedInt32List), - [-42]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedInt64List), - [-0x7fffffff00000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedUint32List), - [0x80000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedUint64List), - [0xf000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSint32List), - [-100]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSint64List), - [-0x8000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed32List), - [1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed64List), - [0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed32List), - [-1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed64List), - [-0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedFloatList), - [1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedDoubleList), - [-1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedBoolList), - [true]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList), - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - -} - - -describe('protoBinaryTest', function() { - /** - * Tests a basic serialization-deserializaton round-trip with all supported - * field types (on the TestAllTypes message type). - */ - it('testRoundTrip', function() { - var msg = new proto.jspb.test.TestAllTypes(); - fillAllFields(msg); - var encoded = msg.serializeBinary(); - var decoded = proto.jspb.test.TestAllTypes.deserializeBinary(encoded); - checkAllFields(msg, decoded); - }); - - /** - * Test that base64 string and Uint8Array are interchangeable in bytes fields. - */ - it('testBytesFieldsGettersInterop', function() { - var msg = new proto.jspb.test.TestAllTypes(); - // Set from a base64 string and check all the getters work. - msg.setOptionalBytes(BYTES_B64); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - // Test binary serialize round trip doesn't break it. - msg = proto.jspb.test.TestAllTypes.deserializeBinary(msg.serializeBinary()); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - msg = new proto.jspb.test.TestAllTypes(); - // Set from a Uint8Array and check all the getters work. - msg.setOptionalBytes(BYTES); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - }); - - /** - * Test that bytes setters will receive result of any of the getters. - */ - it('testBytesFieldsSettersInterop', function() { - var msg = new proto.jspb.test.TestAllTypes(); - msg.setOptionalBytes(BYTES); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - msg.setOptionalBytes(msg.getOptionalBytes()); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - msg.setOptionalBytes(msg.getOptionalBytes_asB64()); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - msg.setOptionalBytes(msg.getOptionalBytes_asU8()); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - }); - - /** - * Test that bytes setters will receive result of any of the getters. - */ - it('testRepeatedBytesGetters', function() { - var msg = new proto.jspb.test.TestAllTypes(); - - function assertGetters() { - assertTrue(typeof msg.getRepeatedBytesList_asB64()[0] === 'string'); - assertTrue(typeof msg.getRepeatedBytesList_asB64()[1] === 'string'); - assertTrue(msg.getRepeatedBytesList_asU8()[0] instanceof Uint8Array); - assertTrue(msg.getRepeatedBytesList_asU8()[1] instanceof Uint8Array); - - assertTrue(bytesCompare(msg.getRepeatedBytesList()[0], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList()[1], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[0], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[1], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[0], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[1], BYTES)); - } - - msg.setRepeatedBytesList([BYTES, BYTES]); - assertGetters(); - - msg.setRepeatedBytesList([BYTES_B64, BYTES_B64]); - assertGetters(); - - msg.setRepeatedBytesList([]); - assertEquals(0, msg.getRepeatedBytesList().length); - assertEquals(0, msg.getRepeatedBytesList_asB64().length); - assertEquals(0, msg.getRepeatedBytesList_asU8().length); - }); - - /** - * Helper: fill all extension values. - * @param {proto.jspb.test.TestExtendable} msg - */ - function fillExtensions(msg) { - msg.setExtension(proto.jspb.test.extendOptionalInt32, 0); - msg.setExtension( - proto.jspb.test.extendOptionalInt64, -0x7fffffff00000000); - msg.setExtension( - proto.jspb.test.extendOptionalUint32, 0x80000000); - msg.setExtension( - proto.jspb.test.extendOptionalUint64, 0xf000000000000000); - msg.setExtension( - proto.jspb.test.extendOptionalSint32, -100); - msg.setExtension( - proto.jspb.test.extendOptionalSint64, -0x8000000000000000); - msg.setExtension( - proto.jspb.test.extendOptionalFixed32, 1234); - msg.setExtension( - proto.jspb.test.extendOptionalFixed64, 0x1234567800000000); - msg.setExtension( - proto.jspb.test.extendOptionalSfixed32, -1234); - msg.setExtension( - proto.jspb.test.extendOptionalSfixed64, -0x1234567800000000); - msg.setExtension( - proto.jspb.test.extendOptionalFloat, 1.5); - msg.setExtension( - proto.jspb.test.extendOptionalDouble, -1.5); - msg.setExtension( - proto.jspb.test.extendOptionalBool, true); - msg.setExtension( - proto.jspb.test.extendOptionalString, 'hello world'); - msg.setExtension(proto.jspb.test.extendOptionalBytes, BYTES); - var submsg = new proto.jspb.test.ExtendsWithMessage(); - submsg.setFoo(16); - msg.setExtension( - proto.jspb.test.ExtendsWithMessage.optionalExtension, submsg); - msg.setExtension( - proto.jspb.test.extendOptionalForeignEnum, - proto.jspb.test.ForeignEnum.FOREIGN_FOO); - - - msg.setExtension( - proto.jspb.test.extendRepeatedInt32List, [-42]); - msg.setExtension( - proto.jspb.test.extendRepeatedInt64List, [-0x7fffffff00000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedUint32List, [0x80000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedUint64List, [0xf000000000000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedSint32List, [-100]); - msg.setExtension( - proto.jspb.test.extendRepeatedSint64List, [-0x8000000000000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedFixed32List, [1234]); - msg.setExtension( - proto.jspb.test.extendRepeatedFixed64List, [0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedSfixed32List, [-1234]); - msg.setExtension( - proto.jspb.test.extendRepeatedSfixed64List, [-0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedFloatList, [1.5]); - msg.setExtension( - proto.jspb.test.extendRepeatedDoubleList, [-1.5]); - msg.setExtension( - proto.jspb.test.extendRepeatedBoolList, [true]); - msg.setExtension( - proto.jspb.test.extendRepeatedStringList, ['hello world']); - msg.setExtension(proto.jspb.test.extendRepeatedBytesList, [BYTES]); - submsg = new proto.jspb.test.ExtendsWithMessage(); - submsg.setFoo(1000); - msg.setExtension( - proto.jspb.test.ExtendsWithMessage.repeatedExtensionList, [submsg]); - msg.setExtension(proto.jspb.test.extendRepeatedForeignEnumList, - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - - msg.setExtension( - proto.jspb.test.extendPackedRepeatedInt32List, [-42]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedInt64List, [-0x7fffffff00000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedUint32List, [0x80000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedUint64List, [0xf000000000000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSint32List, [-100]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSint64List, [-0x8000000000000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedFixed32List, [1234]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedFixed64List, [0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSfixed32List, [-1234]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSfixed64List, - [-0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedFloatList, [1.5]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedDoubleList, [-1.5]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedBoolList, [true]); - msg.setExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList, - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - } - - - /** - * Tests extension serialization and deserialization. - */ - it('testExtensions', function() { - var msg = new proto.jspb.test.TestExtendable(); - fillExtensions(msg); - var encoded = msg.serializeBinary(); - var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded); - checkExtensions(decoded); - }); - - /** - * Tests that unknown extensions don't cause deserialization failure. - */ - it('testUnknownExtension', function() { - var msg = new proto.jspb.test.TestExtendable(); - fillExtensions(msg); - var writer = new jspb.BinaryWriter(); - writer.writeBool((1 << 29) - 1, true); - proto.jspb.test.TestExtendable.serializeBinaryToWriter(msg, writer); - var encoded = writer.getResultBuffer(); - var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded); - checkExtensions(decoded); - }); - - it('testAnyWellKnownType', function() { - var any = new proto.google.protobuf.Any(); - var msg = new proto.jspb.test.TestAllTypes(); - - fillAllFields(msg); - - any.pack(msg.serializeBinary(), 'jspb.test.TestAllTypes'); - - assertEquals('type.googleapis.com/jspb.test.TestAllTypes', - any.getTypeUrl()); - - var msg2 = any.unpack( - proto.jspb.test.TestAllTypes.deserializeBinary, - 'jspb.test.TestAllTypes'); - - checkAllFields(msg, msg2); - - }); - -}); diff --git a/js/binary/reader.js b/js/binary/reader.js deleted file mode 100644 index 31bbfda43..000000000 --- a/js/binary/reader.js +++ /dev/null @@ -1,1296 +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. - -/** - * @fileoverview This file contains utilities for converting binary, - * wire-format protocol buffers into Javascript data structures. - * - * jspb's BinaryReader class wraps the BinaryDecoder class to add methods - * that understand the protocol buffer syntax and can do the type checking and - * bookkeeping necessary to parse trees of nested messages. - * - * Major caveat - Users of this library _must_ keep their Javascript proto - * parsing code in sync with the original .proto file - presumably you'll be - * using the typed jspb code generator, but if you bypass that you'll need - * to keep things in sync by hand. - * - * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed - * @author aappleby@google.com (Austin Appleby) - */ - -goog.provide('jspb.BinaryReader'); - -goog.require('goog.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryDecoder'); -goog.require('jspb.utils'); - - - -/** - * BinaryReader implements the decoders for all the wire types specified in - * https://developers.google.com/protocol-buffers/docs/encoding. - * - * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from. - * @param {number=} opt_start The optional offset to start reading at. - * @param {number=} opt_length The optional length of the block to read - - * we'll throw an assertion if we go off the end of the block. - * @constructor - * @struct - */ -jspb.BinaryReader = function(opt_bytes, opt_start, opt_length) { - /** - * Wire-format decoder. - * @private {!jspb.BinaryDecoder} - */ - this.decoder_ = jspb.BinaryDecoder.alloc(opt_bytes, opt_start, opt_length); - - /** - * Cursor immediately before the field tag. - * @private {number} - */ - this.fieldCursor_ = this.decoder_.getCursor(); - - /** - * Field number of the next field in the buffer, filled in by nextField(). - * @private {number} - */ - this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER; - - /** - * Wire type of the next proto field in the buffer, filled in by - * nextField(). - * @private {jspb.BinaryConstants.WireType} - */ - this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID; - - /** - * Set to true if this reader encountered an error due to corrupt data. - * @private {boolean} - */ - this.error_ = false; - - /** - * User-defined reader callbacks. - * @private {?Object} - */ - this.readCallbacks_ = null; -}; - - -/** - * Global pool of BinaryReader instances. - * @private {!Array} - */ -jspb.BinaryReader.instanceCache_ = []; - - -/** - * Pops an instance off the instance cache, or creates one if the cache is - * empty. - * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from. - * @param {number=} opt_start The optional offset to start reading at. - * @param {number=} opt_length The optional length of the block to read - - * we'll throw an assertion if we go off the end of the block. - * @return {!jspb.BinaryReader} - */ -jspb.BinaryReader.alloc = - function(opt_bytes, opt_start, opt_length) { - if (jspb.BinaryReader.instanceCache_.length) { - var newReader = jspb.BinaryReader.instanceCache_.pop(); - if (opt_bytes) { - newReader.decoder_.setBlock(opt_bytes, opt_start, opt_length); - } - return newReader; - } else { - return new jspb.BinaryReader(opt_bytes, opt_start, opt_length); - } -}; - - -/** - * Alias for the above method. - * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from. - * @param {number=} opt_start The optional offset to start reading at. - * @param {number=} opt_length The optional length of the block to read - - * we'll throw an assertion if we go off the end of the block. - * @return {!jspb.BinaryReader} - */ -jspb.BinaryReader.prototype.alloc = jspb.BinaryReader.alloc; - - -/** - * Puts this instance back in the instance cache. - */ -jspb.BinaryReader.prototype.free = function() { - this.decoder_.clear(); - this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER; - this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID; - this.error_ = false; - this.readCallbacks_ = null; - - if (jspb.BinaryReader.instanceCache_.length < 100) { - jspb.BinaryReader.instanceCache_.push(this); - } -}; - - -/** - * Returns the cursor immediately before the current field's tag. - * @return {number} The internal read cursor. - */ -jspb.BinaryReader.prototype.getFieldCursor = function() { - return this.fieldCursor_; -}; - - -/** - * Returns the internal read cursor. - * @return {number} The internal read cursor. - */ -jspb.BinaryReader.prototype.getCursor = function() { - return this.decoder_.getCursor(); -}; - - -/** - * Returns the raw buffer. - * @return {?Uint8Array} The raw buffer. - */ -jspb.BinaryReader.prototype.getBuffer = function() { - return this.decoder_.getBuffer(); -}; - - -/** - * @return {number} The field number of the next field in the buffer, or - * INVALID_FIELD_NUMBER if there is no next field. - */ -jspb.BinaryReader.prototype.getFieldNumber = function() { - return this.nextField_; -}; - - -/** - * @return {jspb.BinaryConstants.WireType} The wire type of the next field - * in the stream, or WireType.INVALID if there is no next field. - */ -jspb.BinaryReader.prototype.getWireType = function() { - return this.nextWireType_; -}; - - -/** - * @return {boolean} Whether the current wire type is a delimited field. Used to - * conditionally parse packed repeated fields. - */ -jspb.BinaryReader.prototype.isDelimited = function() { - return this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED; -}; - - -/** - * @return {boolean} Whether the current wire type is an end-group tag. Used as - * an exit condition in decoder loops in generated code. - */ -jspb.BinaryReader.prototype.isEndGroup = function() { - return this.nextWireType_ == jspb.BinaryConstants.WireType.END_GROUP; -}; - - -/** - * Returns true if this reader hit an error due to corrupt data. - * @return {boolean} - */ -jspb.BinaryReader.prototype.getError = function() { - return this.error_ || this.decoder_.getError(); -}; - - -/** - * Points this reader at a new block of bytes. - * @param {!Uint8Array} bytes The block of bytes we're reading from. - * @param {number} start The offset to start reading at. - * @param {number} length The length of the block to read. - */ -jspb.BinaryReader.prototype.setBlock = function(bytes, start, length) { - this.decoder_.setBlock(bytes, start, length); - this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER; - this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID; -}; - - -/** - * Rewinds the stream cursor to the beginning of the buffer and resets all - * internal state. - */ -jspb.BinaryReader.prototype.reset = function() { - this.decoder_.reset(); - this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER; - this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID; -}; - - -/** - * Advances the stream cursor by the given number of bytes. - * @param {number} count The number of bytes to advance by. - */ -jspb.BinaryReader.prototype.advance = function(count) { - this.decoder_.advance(count); -}; - - -/** - * Reads the next field header in the stream if there is one, returns true if - * we saw a valid field header or false if we've read the whole stream. - * Throws an error if we encountered a deprecated START_GROUP/END_GROUP field. - * @return {boolean} True if the stream contains more fields. - */ -jspb.BinaryReader.prototype.nextField = function() { - // If we're at the end of the block, there are no more fields. - if (this.decoder_.atEnd()) { - return false; - } - - // If we hit an error decoding the previous field, stop now before we - // try to decode anything else - if (this.getError()) { - goog.asserts.fail('Decoder hit an error'); - return false; - } - - // Otherwise just read the header of the next field. - this.fieldCursor_ = this.decoder_.getCursor(); - var header = this.decoder_.readUnsignedVarint32(); - - var nextField = header >>> 3; - var nextWireType = /** @type {jspb.BinaryConstants.WireType} */ - (header & 0x7); - - // If the wire type isn't one of the valid ones, something's broken. - if (nextWireType != jspb.BinaryConstants.WireType.VARINT && - nextWireType != jspb.BinaryConstants.WireType.FIXED32 && - nextWireType != jspb.BinaryConstants.WireType.FIXED64 && - nextWireType != jspb.BinaryConstants.WireType.DELIMITED && - nextWireType != jspb.BinaryConstants.WireType.START_GROUP && - nextWireType != jspb.BinaryConstants.WireType.END_GROUP) { - goog.asserts.fail( - 'Invalid wire type: %s (at position %s)', nextWireType, - this.fieldCursor_); - this.error_ = true; - return false; - } - - this.nextField_ = nextField; - this.nextWireType_ = nextWireType; - - return true; -}; - - -/** - * Winds the reader back to just before this field's header. - */ -jspb.BinaryReader.prototype.unskipHeader = function() { - this.decoder_.unskipVarint((this.nextField_ << 3) | this.nextWireType_); -}; - - -/** - * Skips all contiguous fields whose header matches the one we just read. - */ -jspb.BinaryReader.prototype.skipMatchingFields = function() { - var field = this.nextField_; - this.unskipHeader(); - - while (this.nextField() && (this.getFieldNumber() == field)) { - this.skipField(); - } - - if (!this.decoder_.atEnd()) { - this.unskipHeader(); - } -}; - - -/** - * Skips over the next varint field in the binary stream. - */ -jspb.BinaryReader.prototype.skipVarintField = function() { - if (this.nextWireType_ != jspb.BinaryConstants.WireType.VARINT) { - goog.asserts.fail('Invalid wire type for skipVarintField'); - this.skipField(); - return; - } - - this.decoder_.skipVarint(); -}; - - -/** - * Skips over the next delimited field in the binary stream. - */ -jspb.BinaryReader.prototype.skipDelimitedField = function() { - if (this.nextWireType_ != jspb.BinaryConstants.WireType.DELIMITED) { - goog.asserts.fail('Invalid wire type for skipDelimitedField'); - this.skipField(); - return; - } - - var length = this.decoder_.readUnsignedVarint32(); - this.decoder_.advance(length); -}; - - -/** - * Skips over the next fixed32 field in the binary stream. - */ -jspb.BinaryReader.prototype.skipFixed32Field = function() { - if (this.nextWireType_ != jspb.BinaryConstants.WireType.FIXED32) { - goog.asserts.fail('Invalid wire type for skipFixed32Field'); - this.skipField(); - return; - } - - this.decoder_.advance(4); -}; - - -/** - * Skips over the next fixed64 field in the binary stream. - */ -jspb.BinaryReader.prototype.skipFixed64Field = function() { - if (this.nextWireType_ != jspb.BinaryConstants.WireType.FIXED64) { - goog.asserts.fail('Invalid wire type for skipFixed64Field'); - this.skipField(); - return; - } - - this.decoder_.advance(8); -}; - - -/** - * Skips over the next group field in the binary stream. - */ -jspb.BinaryReader.prototype.skipGroup = function() { - var previousField = this.nextField_; - do { - if (!this.nextField()) { - goog.asserts.fail('Unmatched start-group tag: stream EOF'); - this.error_ = true; - return; - } - if (this.nextWireType_ == - jspb.BinaryConstants.WireType.END_GROUP) { - // Group end: check that it matches top-of-stack. - if (this.nextField_ != previousField) { - goog.asserts.fail('Unmatched end-group tag'); - this.error_ = true; - return; - } - return; - } - this.skipField(); - } while (true); -}; - - -/** - * Skips over the next field in the binary stream - this is useful if we're - * decoding a message that contain unknown fields. - */ -jspb.BinaryReader.prototype.skipField = function() { - switch (this.nextWireType_) { - case jspb.BinaryConstants.WireType.VARINT: - this.skipVarintField(); - break; - case jspb.BinaryConstants.WireType.FIXED64: - this.skipFixed64Field(); - break; - case jspb.BinaryConstants.WireType.DELIMITED: - this.skipDelimitedField(); - break; - case jspb.BinaryConstants.WireType.FIXED32: - this.skipFixed32Field(); - break; - case jspb.BinaryConstants.WireType.START_GROUP: - this.skipGroup(); - break; - default: - goog.asserts.fail('Invalid wire encoding for field.'); - } -}; - - -/** - * Registers a user-defined read callback. - * @param {string} callbackName - * @param {function(!jspb.BinaryReader):*} callback - */ -jspb.BinaryReader.prototype.registerReadCallback = function( - callbackName, callback) { - if (this.readCallbacks_ === null) { - this.readCallbacks_ = {}; - } - goog.asserts.assert(!this.readCallbacks_[callbackName]); - this.readCallbacks_[callbackName] = callback; -}; - - -/** - * Runs a registered read callback. - * @param {string} callbackName The name the callback is registered under. - * @return {*} The value returned by the callback. - */ -jspb.BinaryReader.prototype.runReadCallback = function(callbackName) { - goog.asserts.assert(this.readCallbacks_ !== null); - var callback = this.readCallbacks_[callbackName]; - goog.asserts.assert(callback); - return callback(this); -}; - - -/** - * Reads a field of any valid non-message type from the binary stream. - * @param {jspb.BinaryConstants.FieldType} fieldType - * @return {jspb.AnyFieldType} - */ -jspb.BinaryReader.prototype.readAny = function(fieldType) { - this.nextWireType_ = jspb.BinaryConstants.FieldTypeToWireType(fieldType); - var fieldTypes = jspb.BinaryConstants.FieldType; - switch (fieldType) { - case fieldTypes.DOUBLE: - return this.readDouble(); - case fieldTypes.FLOAT: - return this.readFloat(); - case fieldTypes.INT64: - return this.readInt64(); - case fieldTypes.UINT64: - return this.readUint64(); - case fieldTypes.INT32: - return this.readInt32(); - case fieldTypes.FIXED64: - return this.readFixed64(); - case fieldTypes.FIXED32: - return this.readFixed32(); - case fieldTypes.BOOL: - return this.readBool(); - case fieldTypes.STRING: - return this.readString(); - case fieldTypes.GROUP: - goog.asserts.fail('Group field type not supported in readAny()'); - case fieldTypes.MESSAGE: - goog.asserts.fail('Message field type not supported in readAny()'); - case fieldTypes.BYTES: - return this.readBytes(); - case fieldTypes.UINT32: - return this.readUint32(); - case fieldTypes.ENUM: - return this.readEnum(); - case fieldTypes.SFIXED32: - return this.readSfixed32(); - case fieldTypes.SFIXED64: - return this.readSfixed64(); - case fieldTypes.SINT32: - return this.readSint32(); - case fieldTypes.SINT64: - return this.readSint64(); - case fieldTypes.FHASH64: - return this.readFixedHash64(); - case fieldTypes.VHASH64: - return this.readVarintHash64(); - default: - goog.asserts.fail('Invalid field type in readAny()'); - } - return 0; -}; - - -/** - * Deserialize a proto into the provided message object using the provided - * reader function. This function is templated as we currently have one client - * who is using manual deserialization instead of the code-generated versions. - * @template T - * @param {T} message - * @param {function(T, !jspb.BinaryReader)} reader - */ -jspb.BinaryReader.prototype.readMessage = function(message, reader) { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED); - - // Save the current endpoint of the decoder and move it to the end of the - // embedded message. - var oldEnd = this.decoder_.getEnd(); - var length = this.decoder_.readUnsignedVarint32(); - var newEnd = this.decoder_.getCursor() + length; - this.decoder_.setEnd(newEnd); - - // Deserialize the embedded message. - reader(message, this); - - // Advance the decoder past the embedded message and restore the endpoint. - this.decoder_.setCursor(newEnd); - this.decoder_.setEnd(oldEnd); -}; - - -/** - * Deserialize a proto into the provided message object using the provided - * reader function, assuming that the message is serialized as a group - * with the given tag. - * @template T - * @param {number} field - * @param {T} message - * @param {function(T, !jspb.BinaryReader)} reader - */ -jspb.BinaryReader.prototype.readGroup = - function(field, message, reader) { - // Ensure that the wire type is correct. - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.START_GROUP); - // Ensure that the field number is correct. - goog.asserts.assert(this.nextField_ == field); - - // Deserialize the message. The deserialization will stop at an END_GROUP tag. - reader(message, this); - - if (!this.error_ && - this.nextWireType_ != jspb.BinaryConstants.WireType.END_GROUP) { - goog.asserts.fail('Group submessage did not end with an END_GROUP tag'); - this.error_ = true; - } -}; - - -/** - * Return a decoder that wraps the current delimited field. - * @return {!jspb.BinaryDecoder} - */ -jspb.BinaryReader.prototype.getFieldDecoder = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED); - - var length = this.decoder_.readUnsignedVarint32(); - var start = this.decoder_.getCursor(); - var end = start + length; - - var innerDecoder = - jspb.BinaryDecoder.alloc(this.decoder_.getBuffer(), start, length); - this.decoder_.setCursor(end); - return innerDecoder; -}; - - -/** - * Reads a signed 32-bit integer field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * @return {number} The value of the signed 32-bit integer field. - */ -jspb.BinaryReader.prototype.readInt32 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readSignedVarint32(); -}; - - -/** - * Reads a signed 32-bit integer field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * Returns the value as a string. - * - * @return {string} The value of the signed 32-bit integer field as a decimal - * string. - */ -jspb.BinaryReader.prototype.readInt32String = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readSignedVarint32String(); -}; - - -/** - * Reads a signed 64-bit integer field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * @return {number} The value of the signed 64-bit integer field. - */ -jspb.BinaryReader.prototype.readInt64 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readSignedVarint64(); -}; - - -/** - * Reads a signed 64-bit integer field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * Returns the value as a string. - * - * @return {string} The value of the signed 64-bit integer field as a decimal - * string. - */ -jspb.BinaryReader.prototype.readInt64String = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readSignedVarint64String(); -}; - - -/** - * Reads an unsigned 32-bit integer field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * @return {number} The value of the unsigned 32-bit integer field. - */ -jspb.BinaryReader.prototype.readUint32 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readUnsignedVarint32(); -}; - - -/** - * Reads an unsigned 32-bit integer field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * Returns the value as a string. - * - * @return {string} The value of the unsigned 32-bit integer field as a decimal - * string. - */ -jspb.BinaryReader.prototype.readUint32String = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readUnsignedVarint32String(); -}; - - -/** - * Reads an unsigned 64-bit integer field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * @return {number} The value of the unsigned 64-bit integer field. - */ -jspb.BinaryReader.prototype.readUint64 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readUnsignedVarint64(); -}; - - -/** - * Reads an unsigned 64-bit integer field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * Returns the value as a string. - * - * @return {string} The value of the unsigned 64-bit integer field as a decimal - * string. - */ -jspb.BinaryReader.prototype.readUint64String = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readUnsignedVarint64String(); -}; - - -/** - * Reads a signed zigzag-encoded 32-bit integer field from the binary stream, - * or throws an error if the next field in the stream is not of the correct - * wire type. - * - * @return {number} The value of the signed 32-bit integer field. - */ -jspb.BinaryReader.prototype.readSint32 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readZigzagVarint32(); -}; - - -/** - * Reads a signed zigzag-encoded 64-bit integer field from the binary stream, - * or throws an error if the next field in the stream is not of the correct - * wire type. - * - * @return {number} The value of the signed 64-bit integer field. - */ -jspb.BinaryReader.prototype.readSint64 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readZigzagVarint64(); -}; - - -/** - * Reads a signed zigzag-encoded 64-bit integer field from the binary stream, - * or throws an error if the next field in the stream is not of the correct - * wire type. - * - * @return {string} The value of the signed 64-bit integer field as a decimal string. - */ -jspb.BinaryReader.prototype.readSint64String = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readZigzagVarint64String(); -}; - - -/** - * Reads an unsigned 32-bit fixed-length integer fiield from the binary stream, - * or throws an error if the next field in the stream is not of the correct - * wire type. - * - * @return {number} The value of the double field. - */ -jspb.BinaryReader.prototype.readFixed32 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32); - return this.decoder_.readUint32(); -}; - - -/** - * Reads an unsigned 64-bit fixed-length integer fiield from the binary stream, - * or throws an error if the next field in the stream is not of the correct - * wire type. - * - * @return {number} The value of the float field. - */ -jspb.BinaryReader.prototype.readFixed64 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64); - return this.decoder_.readUint64(); -}; - - -/** - * Reads a signed 64-bit integer field from the binary stream as a string, or - * throws an error if the next field in the stream is not of the correct wire - * type. - * - * Returns the value as a string. - * - * @return {string} The value of the unsigned 64-bit integer field as a decimal - * string. - */ -jspb.BinaryReader.prototype.readFixed64String = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64); - return this.decoder_.readUint64String(); -}; - - -/** - * Reads a signed 32-bit fixed-length integer fiield from the binary stream, or - * throws an error if the next field in the stream is not of the correct wire - * type. - * - * @return {number} The value of the signed 32-bit integer field. - */ -jspb.BinaryReader.prototype.readSfixed32 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32); - return this.decoder_.readInt32(); -}; - - -/** - * Reads a signed 32-bit fixed-length integer fiield from the binary stream, or - * throws an error if the next field in the stream is not of the correct wire - * type. - * - * @return {string} The value of the signed 32-bit integer field as a decimal - * string. - */ -jspb.BinaryReader.prototype.readSfixed32String = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32); - return this.decoder_.readInt32().toString(); -}; - - -/** - * Reads a signed 64-bit fixed-length integer fiield from the binary stream, or - * throws an error if the next field in the stream is not of the correct wire - * type. - * - * @return {number} The value of the sfixed64 field. - */ -jspb.BinaryReader.prototype.readSfixed64 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64); - return this.decoder_.readInt64(); -}; - - -/** - * Reads a signed 64-bit fixed-length integer fiield from the binary stream, or - * throws an error if the next field in the stream is not of the correct wire - * type. - * - * Returns the value as a string. - * - * @return {string} The value of the sfixed64 field as a decimal string. - */ -jspb.BinaryReader.prototype.readSfixed64String = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64); - return this.decoder_.readInt64String(); -}; - - -/** - * Reads a 32-bit floating-point field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * @return {number} The value of the float field. - */ -jspb.BinaryReader.prototype.readFloat = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32); - return this.decoder_.readFloat(); -}; - - -/** - * Reads a 64-bit floating-point field from the binary stream, or throws an - * error if the next field in the stream is not of the correct wire type. - * - * @return {number} The value of the double field. - */ -jspb.BinaryReader.prototype.readDouble = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64); - return this.decoder_.readDouble(); -}; - - -/** - * Reads a boolean field from the binary stream, or throws an error if the next - * field in the stream is not of the correct wire type. - * - * @return {boolean} The value of the boolean field. - */ -jspb.BinaryReader.prototype.readBool = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return !!this.decoder_.readUnsignedVarint32(); -}; - - -/** - * Reads an enum field from the binary stream, or throws an error if the next - * field in the stream is not of the correct wire type. - * - * @return {number} The value of the enum field. - */ -jspb.BinaryReader.prototype.readEnum = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readSignedVarint64(); -}; - - -/** - * Reads a string field from the binary stream, or throws an error if the next - * field in the stream is not of the correct wire type. - * - * @return {string} The value of the string field. - */ -jspb.BinaryReader.prototype.readString = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED); - var length = this.decoder_.readUnsignedVarint32(); - return this.decoder_.readString(length); -}; - - -/** - * Reads a length-prefixed block of bytes from the binary stream, or returns - * null if the next field in the stream has an invalid length value. - * - * @return {!Uint8Array} The block of bytes. - */ -jspb.BinaryReader.prototype.readBytes = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED); - var length = this.decoder_.readUnsignedVarint32(); - return this.decoder_.readBytes(length); -}; - - -/** - * Reads a 64-bit varint or fixed64 field from the stream and returns it as an - * 8-character Unicode string for use as a hash table key, or throws an error - * if the next field in the stream is not of the correct wire type. - * - * @return {string} The hash value. - */ -jspb.BinaryReader.prototype.readVarintHash64 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readVarintHash64(); -}; - - -/** - * Reads an sint64 field from the stream and returns it as an 8-character - * Unicode string for use as a hash table key, or throws an error if the next - * field in the stream is not of the correct wire type. - * - * @return {string} The hash value. - */ -jspb.BinaryReader.prototype.readSintHash64 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readZigzagVarintHash64(); -}; - - -/** - * Reads a 64-bit varint field from the stream and invokes `convert` to produce - * the return value, or throws an error if the next field in the stream is not - * of the correct wire type. - * - * @param {function(number, number): T} convert Conversion function to produce - * the result value, takes parameters (lowBits, highBits). - * @return {T} - * @template T - */ -jspb.BinaryReader.prototype.readSplitVarint64 = function(convert) { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readSplitVarint64(convert); -}; - - -/** - * Reads a 64-bit zig-zag varint field from the stream and invokes `convert` to - * produce the return value, or throws an error if the next field in the stream - * is not of the correct wire type. - * - * @param {function(number, number): T} convert Conversion function to produce - * the result value, takes parameters (lowBits, highBits). - * @return {T} - * @template T - */ -jspb.BinaryReader.prototype.readSplitZigzagVarint64 = function(convert) { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT); - return this.decoder_.readSplitVarint64(function(lowBits, highBits) { - return jspb.utils.fromZigzag64(lowBits, highBits, convert); - }); -}; - - -/** - * Reads a 64-bit varint or fixed64 field from the stream and returns it as a - * 8-character Unicode string for use as a hash table key, or throws an error - * if the next field in the stream is not of the correct wire type. - * - * @return {string} The hash value. - */ -jspb.BinaryReader.prototype.readFixedHash64 = function() { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64); - return this.decoder_.readFixedHash64(); -}; - - -/** - * Reads a 64-bit fixed64 field from the stream and invokes `convert` - * to produce the return value, or throws an error if the next field in the - * stream is not of the correct wire type. - * - * @param {function(number, number): T} convert Conversion function to produce - * the result value, takes parameters (lowBits, highBits). - * @return {T} - * @template T - */ -jspb.BinaryReader.prototype.readSplitFixed64 = function(convert) { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64); - return this.decoder_.readSplitFixed64(convert); -}; - - -/** - * Reads a packed scalar field using the supplied raw reader function. - * @param {function(this:jspb.BinaryDecoder)} decodeMethod - * @return {!Array} - * @private - */ -jspb.BinaryReader.prototype.readPackedField_ = function(decodeMethod) { - goog.asserts.assert( - this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED); - var length = this.decoder_.readUnsignedVarint32(); - var end = this.decoder_.getCursor() + length; - var result = []; - while (this.decoder_.getCursor() < end) { - // TODO(aappleby): .call is slow - result.push(decodeMethod.call(this.decoder_)); - } - return result; -}; - - -/** - * Reads a packed int32 field, which consists of a length header and a list of - * signed varints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedInt32 = function() { - return this.readPackedField_(this.decoder_.readSignedVarint32); -}; - - -/** - * Reads a packed int32 field, which consists of a length header and a list of - * signed varints. Returns a list of strings. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedInt32String = function() { - return this.readPackedField_(this.decoder_.readSignedVarint32String); -}; - - -/** - * Reads a packed int64 field, which consists of a length header and a list of - * signed varints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedInt64 = function() { - return this.readPackedField_(this.decoder_.readSignedVarint64); -}; - - -/** - * Reads a packed int64 field, which consists of a length header and a list of - * signed varints. Returns a list of strings. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedInt64String = function() { - return this.readPackedField_(this.decoder_.readSignedVarint64String); -}; - - -/** - * Reads a packed uint32 field, which consists of a length header and a list of - * unsigned varints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedUint32 = function() { - return this.readPackedField_(this.decoder_.readUnsignedVarint32); -}; - - -/** - * Reads a packed uint32 field, which consists of a length header and a list of - * unsigned varints. Returns a list of strings. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedUint32String = function() { - return this.readPackedField_(this.decoder_.readUnsignedVarint32String); -}; - - -/** - * Reads a packed uint64 field, which consists of a length header and a list of - * unsigned varints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedUint64 = function() { - return this.readPackedField_(this.decoder_.readUnsignedVarint64); -}; - - -/** - * Reads a packed uint64 field, which consists of a length header and a list of - * unsigned varints. Returns a list of strings. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedUint64String = function() { - return this.readPackedField_(this.decoder_.readUnsignedVarint64String); -}; - - -/** - * Reads a packed sint32 field, which consists of a length header and a list of - * zigzag varints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedSint32 = function() { - return this.readPackedField_(this.decoder_.readZigzagVarint32); -}; - - -/** - * Reads a packed sint64 field, which consists of a length header and a list of - * zigzag varints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedSint64 = function() { - return this.readPackedField_(this.decoder_.readZigzagVarint64); -}; - - -/** - * Reads a packed sint64 field, which consists of a length header and a list of - * zigzag varints. Returns a list of strings. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedSint64String = function() { - return this.readPackedField_(this.decoder_.readZigzagVarint64String); -}; - - -/** - * Reads a packed fixed32 field, which consists of a length header and a list - * of unsigned 32-bit ints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedFixed32 = function() { - return this.readPackedField_(this.decoder_.readUint32); -}; - - -/** - * Reads a packed fixed64 field, which consists of a length header and a list - * of unsigned 64-bit ints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedFixed64 = function() { - return this.readPackedField_(this.decoder_.readUint64); -}; - - -/** - * Reads a packed fixed64 field, which consists of a length header and a list - * of unsigned 64-bit ints. Returns a list of strings. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedFixed64String = function() { - return this.readPackedField_(this.decoder_.readUint64String); -}; - - -/** - * Reads a packed sfixed32 field, which consists of a length header and a list - * of 32-bit ints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedSfixed32 = function() { - return this.readPackedField_(this.decoder_.readInt32); -}; - - -/** - * Reads a packed sfixed64 field, which consists of a length header and a list - * of 64-bit ints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedSfixed64 = function() { - return this.readPackedField_(this.decoder_.readInt64); -}; - - -/** - * Reads a packed sfixed64 field, which consists of a length header and a list - * of 64-bit ints. Returns a list of strings. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedSfixed64String = function() { - return this.readPackedField_(this.decoder_.readInt64String); -}; - - -/** - * Reads a packed float field, which consists of a length header and a list of - * floats. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedFloat = function() { - return this.readPackedField_(this.decoder_.readFloat); -}; - - -/** - * Reads a packed double field, which consists of a length header and a list of - * doubles. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedDouble = function() { - return this.readPackedField_(this.decoder_.readDouble); -}; - - -/** - * Reads a packed bool field, which consists of a length header and a list of - * unsigned varints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedBool = function() { - return this.readPackedField_(this.decoder_.readBool); -}; - - -/** - * Reads a packed enum field, which consists of a length header and a list of - * unsigned varints. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedEnum = function() { - return this.readPackedField_(this.decoder_.readEnum); -}; - - -/** - * Reads a packed varint hash64 field, which consists of a length header and a - * list of varint hash64s. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedVarintHash64 = function() { - return this.readPackedField_(this.decoder_.readVarintHash64); -}; - - -/** - * Reads a packed fixed hash64 field, which consists of a length header and a - * list of fixed hash64s. - * @return {!Array} - */ -jspb.BinaryReader.prototype.readPackedFixedHash64 = function() { - return this.readPackedField_(this.decoder_.readFixedHash64); -}; diff --git a/js/binary/reader_test.js b/js/binary/reader_test.js deleted file mode 100644 index 6963f77f4..000000000 --- a/js/binary/reader_test.js +++ /dev/null @@ -1,992 +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. - -/** - * @fileoverview Test cases for jspb's binary protocol buffer reader. - * - * There are two particular magic numbers that need to be pointed out - - * 2^64-1025 is the largest number representable as both a double and an - * unsigned 64-bit integer, and 2^63-513 is the largest number representable as - * both a double and a signed 64-bit integer. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryDecoder'); -goog.require('jspb.BinaryReader'); -goog.require('jspb.BinaryWriter'); -goog.require('jspb.utils'); -goog.requireType('jspb.BinaryMessage'); - - -describe('binaryReaderTest', function() { - /** - * Tests the reader instance cache. - */ - it('testInstanceCaches', /** @suppress {visibility} */ function() { - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - writer.writeMessage(1, dummyMessage, () => {}); - writer.writeMessage(2, dummyMessage, () => {}); - - var buffer = writer.getResultBuffer(); - - // Empty the instance caches. - jspb.BinaryReader.instanceCache_ = []; - - // Allocating and then freeing three decoders should leave us with three in - // the cache. - - var decoder1 = jspb.BinaryDecoder.alloc(); - var decoder2 = jspb.BinaryDecoder.alloc(); - var decoder3 = jspb.BinaryDecoder.alloc(); - decoder1.free(); - decoder2.free(); - decoder3.free(); - - assertEquals(3, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - - // Allocating and then freeing a reader should remove one decoder from its - // cache, but it should stay stuck to the reader afterwards since we can't - // have a reader without a decoder. - jspb.BinaryReader.alloc().free(); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(1, jspb.BinaryReader.instanceCache_.length); - - // Allocating a reader should remove a reader from the cache. - var reader = jspb.BinaryReader.alloc(buffer); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - - // Processing the message reuses the current reader. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - }); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - }); - - assertEquals(false, reader.nextField()); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - - // Freeing the reader should put it back into the cache. - reader.free(); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(1, jspb.BinaryReader.instanceCache_.length); - }); - - - /** - * @param {number} x - * @return {number} - */ - function truncate(x) { - var temp = new Float32Array(1); - temp[0] = x; - return temp[0]; - } - - - /** - * Verifies that misuse of the reader class triggers assertions. - */ - it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() { - // Calling readMessage on a non-delimited field should trigger an - // assertion. - var reader = jspb.BinaryReader.alloc([8, 1]); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - reader.nextField(); - assertThrows(function() { - reader.readMessage(dummyMessage, () => {}); - }); - - // Reading past the end of the stream should trigger an assertion. - reader = jspb.BinaryReader.alloc([9, 1]); - reader.nextField(); - assertThrows(function() { - reader.readFixed64() - }); - - // Reading past the end of a submessage should trigger an assertion. - reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]); - reader.nextField(); - reader.readMessage(dummyMessage, function() { - reader.nextField(); - assertThrows(function() { - reader.readFixed32() - }); - }); - - // Skipping an invalid field should trigger an assertion. - reader = jspb.BinaryReader.alloc([12, 1]); - reader.nextWireType_ = 1000; - assertThrows(function() { - reader.skipField() - }); - - // Reading fields with the wrong wire type should assert. - reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]); - reader.nextField(); - assertThrows(function() { - reader.readInt32() - }); - assertThrows(function() { - reader.readInt32String() - }); - assertThrows(function() { - reader.readInt64() - }); - assertThrows(function() { - reader.readInt64String() - }); - assertThrows(function() { - reader.readUint32() - }); - assertThrows(function() { - reader.readUint32String() - }); - assertThrows(function() { - reader.readUint64() - }); - assertThrows(function() { - reader.readUint64String() - }); - assertThrows(function() { - reader.readSint32() - }); - assertThrows(function() { - reader.readBool() - }); - assertThrows(function() { - reader.readEnum() - }); - - reader = jspb.BinaryReader.alloc([8, 1]); - reader.nextField(); - assertThrows(function() { - reader.readFixed32() - }); - assertThrows(function() { - reader.readFixed64() - }); - assertThrows(function() { - reader.readSfixed32() - }); - assertThrows(function() { - reader.readSfixed64() - }); - assertThrows(function() { - reader.readFloat() - }); - assertThrows(function() { - reader.readDouble() - }); - - assertThrows(function() { - reader.readString() - }); - assertThrows(function() { - reader.readBytes() - }); - }); - - - /** - * Tests encoding and decoding of unsigned field types. - * @param {Function} readField - * @param {Function} writeField - * @param {number} epsilon - * @param {number} upperLimit - * @param {Function} filter - * @private - * @suppress {missingProperties} - */ - var doTestUnsignedField_ = function( - readField, writeField, epsilon, upperLimit, filter) { - assertNotNull(readField); - assertNotNull(writeField); - - var writer = new jspb.BinaryWriter(); - - // Encode zero and limits. - writeField.call(writer, 1, filter(0)); - writeField.call(writer, 2, filter(epsilon)); - writeField.call(writer, 3, filter(upperLimit)); - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - writeField.call(writer, 4, filter(cursor)); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - // Check zero and limits. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(filter(0), readField.call(reader)); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(filter(epsilon), readField.call(reader)); - - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(filter(upperLimit), readField.call(reader)); - - // Check positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - reader.nextField(); - if (4 != reader.getFieldNumber()) throw 'fail!'; - if (filter(cursor) != readField.call(reader)) throw 'fail!'; - } - }; - - - /** - * Tests encoding and decoding of signed field types. - * @param {Function} readField - * @param {Function} writeField - * @param {number} epsilon - * @param {number} lowerLimit - * @param {number} upperLimit - * @param {Function} filter - * @private - * @suppress {missingProperties} - */ - var doTestSignedField_ = function( - readField, writeField, epsilon, lowerLimit, upperLimit, filter) { - var writer = new jspb.BinaryWriter(); - - // Encode zero and limits. - writeField.call(writer, 1, filter(lowerLimit)); - writeField.call(writer, 2, filter(-epsilon)); - writeField.call(writer, 3, filter(0)); - writeField.call(writer, 4, filter(epsilon)); - writeField.call(writer, 5, filter(upperLimit)); - - var inputValues = []; - - // Encode negative values. - for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) { - var val = filter(cursor); - writeField.call(writer, 6, val); - inputValues.push({fieldNumber: 6, value: val}); - } - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - var val = filter(cursor); - writeField.call(writer, 7, val); - inputValues.push({fieldNumber: 7, value: val}); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - // Check zero and limits. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(filter(lowerLimit), readField.call(reader)); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(filter(-epsilon), readField.call(reader)); - - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(filter(0), readField.call(reader)); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(filter(epsilon), readField.call(reader)); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(filter(upperLimit), readField.call(reader)); - - for (var i = 0; i < inputValues.length; i++) { - var expected = inputValues[i]; - reader.nextField(); - assertEquals(expected.fieldNumber, reader.getFieldNumber()); - assertEquals(expected.value, readField.call(reader)); - } - }; - - - /** - * Tests fields that use varint encoding. - */ - it('testVarintFields', function() { - assertNotUndefined(jspb.BinaryReader.prototype.readUint32); - assertNotUndefined(jspb.BinaryWriter.prototype.writeUint32); - assertNotUndefined(jspb.BinaryReader.prototype.readUint64); - assertNotUndefined(jspb.BinaryWriter.prototype.writeUint64); - assertNotUndefined(jspb.BinaryReader.prototype.readBool); - assertNotUndefined(jspb.BinaryWriter.prototype.writeBool); - doTestUnsignedField_( - jspb.BinaryReader.prototype.readUint32, - jspb.BinaryWriter.prototype.writeUint32, 1, Math.pow(2, 32) - 1, - Math.round); - - doTestUnsignedField_( - jspb.BinaryReader.prototype.readUint64, - jspb.BinaryWriter.prototype.writeUint64, 1, Math.pow(2, 64) - 1025, - Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readInt32, - jspb.BinaryWriter.prototype.writeInt32, 1, -Math.pow(2, 31), - Math.pow(2, 31) - 1, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readInt64, - jspb.BinaryWriter.prototype.writeInt64, 1, -Math.pow(2, 63), - Math.pow(2, 63) - 513, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readEnum, - jspb.BinaryWriter.prototype.writeEnum, 1, -Math.pow(2, 31), - Math.pow(2, 31) - 1, Math.round); - - doTestUnsignedField_( - jspb.BinaryReader.prototype.readBool, - jspb.BinaryWriter.prototype.writeBool, 1, 1, function(x) { - return !!x; - }); - }); - - - /** - * Tests reading a field from hexadecimal string (format: '08 BE EF'). - * @param {Function} readField - * @param {number} expected - * @param {string} hexString - */ - function doTestHexStringVarint_(readField, expected, hexString) { - var bytesCount = (hexString.length + 1) / 3; - var bytes = new Uint8Array(bytesCount); - for (var i = 0; i < bytesCount; i++) { - bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16); - } - var reader = jspb.BinaryReader.alloc(bytes); - reader.nextField(); - assertEquals(expected, readField.call(reader)); - } - - - /** - * Tests non-canonical redundant varint decoding. - */ - it('testRedundantVarintFields', function() { - assertNotNull(jspb.BinaryReader.prototype.readUint32); - assertNotNull(jspb.BinaryReader.prototype.readUint64); - assertNotNull(jspb.BinaryReader.prototype.readSint32); - assertNotNull(jspb.BinaryReader.prototype.readSint64); - - // uint32 and sint32 take no more than 5 bytes - // 08 - field prefix (type = 0 means varint) - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readUint32, 12, '08 8C 80 80 80 00'); - - // 11 stands for -6 in zigzag encoding - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readSint32, -6, '08 8B 80 80 80 00'); - - // uint64 and sint64 take no more than 10 bytes - // 08 - field prefix (type = 0 means varint) - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readUint64, 12, - '08 8C 80 80 80 80 80 80 80 80 00'); - - // 11 stands for -6 in zigzag encoding - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readSint64, -6, - '08 8B 80 80 80 80 80 80 80 80 00'); - }); - - /** - * Tests reading 64-bit integers as split values. - */ - it('handles split 64 fields', function() { - var writer = new jspb.BinaryWriter(); - writer.writeInt64String(1, '4294967296'); - writer.writeSfixed64String(2, '4294967298'); - writer.writeInt64String(3, '3'); // 3 is the zig-zag encoding of -2. - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - function rejoin(lowBits, highBits) { - return highBits * 2 ** 32 + (lowBits >>> 0); - } - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(1); - expect(reader.readSplitVarint64(rejoin)).toEqual(0x100000000); - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(2); - expect(reader.readSplitFixed64(rejoin)).toEqual(0x100000002); - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(3); - expect(reader.readSplitZigzagVarint64(rejoin)).toEqual(-2); - }); - - /** - * Tests 64-bit fields that are handled as strings. - */ - it('testStringInt64Fields', function() { - var writer = new jspb.BinaryWriter(); - - var testSignedData = [ - '2730538252207801776', '-2688470994844604560', '3398529779486536359', - '3568577411627971000', '272477188847484900', '-6649058714086158188', - '-7695254765712060806', '-4525541438037104029', '-4993706538836508568', - '4990160321893729138' - ]; - var testUnsignedData = [ - '7822732630241694882', '6753602971916687352', '2399935075244442116', - '8724292567325338867', '16948784802625696584', '4136275908516066934', - '3575388346793700364', '5167142028379259461', '1557573948689737699', - '17100725280812548567' - ]; - - for (var i = 0; i < testSignedData.length; i++) { - writer.writeInt64String(2 * i + 1, testSignedData[i]); - writer.writeUint64String(2 * i + 2, testUnsignedData[i]); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - for (var i = 0; i < testSignedData.length; i++) { - reader.nextField(); - assertEquals(2 * i + 1, reader.getFieldNumber()); - assertEquals(testSignedData[i], reader.readInt64String()); - reader.nextField(); - assertEquals(2 * i + 2, reader.getFieldNumber()); - assertEquals(testUnsignedData[i], reader.readUint64String()); - } - }); - - - /** - * Tests fields that use zigzag encoding. - */ - it('testZigzagFields', function() { - doTestSignedField_( - jspb.BinaryReader.prototype.readSint32, - jspb.BinaryWriter.prototype.writeSint32, 1, -Math.pow(2, 31), - Math.pow(2, 31) - 1, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSint64, - jspb.BinaryWriter.prototype.writeSint64, 1, -Math.pow(2, 63), - Math.pow(2, 63) - 513, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSintHash64, - jspb.BinaryWriter.prototype.writeSintHash64, 1, -Math.pow(2, 63), - Math.pow(2, 63) - 513, jspb.utils.numberToHash64); - }); - - - /** - * Tests fields that use fixed-length encoding. - */ - it('testFixedFields', function() { - doTestUnsignedField_( - jspb.BinaryReader.prototype.readFixed32, - jspb.BinaryWriter.prototype.writeFixed32, 1, Math.pow(2, 32) - 1, - Math.round); - - doTestUnsignedField_( - jspb.BinaryReader.prototype.readFixed64, - jspb.BinaryWriter.prototype.writeFixed64, 1, Math.pow(2, 64) - 1025, - Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSfixed32, - jspb.BinaryWriter.prototype.writeSfixed32, 1, -Math.pow(2, 31), - Math.pow(2, 31) - 1, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSfixed64, - jspb.BinaryWriter.prototype.writeSfixed64, 1, -Math.pow(2, 63), - Math.pow(2, 63) - 513, Math.round); - }); - - - /** - * Tests floating point fields. - */ - it('testFloatFields', function() { - doTestSignedField_( - jspb.BinaryReader.prototype.readFloat, - jspb.BinaryWriter.prototype.writeFloat, - jspb.BinaryConstants.FLOAT32_MIN, -jspb.BinaryConstants.FLOAT32_MAX, - jspb.BinaryConstants.FLOAT32_MAX, truncate); - - doTestSignedField_( - jspb.BinaryReader.prototype.readDouble, - jspb.BinaryWriter.prototype.writeDouble, - jspb.BinaryConstants.FLOAT64_EPS * 10, - -jspb.BinaryConstants.FLOAT64_MIN, jspb.BinaryConstants.FLOAT64_MIN, - function(x) { - return x; - }); - }); - - - /** - * Tests length-delimited string fields. - */ - it('testStringFields', function() { - var s1 = 'The quick brown fox jumps over the lazy dog.'; - var s2 = '人人生而自由,在尊嚴和權利上一律平等。'; - - var writer = new jspb.BinaryWriter(); - - writer.writeString(1, s1); - writer.writeString(2, s2); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(s1, reader.readString()); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(s2, reader.readString()); - }); - - - /** - * Tests length-delimited byte fields. - */ - it('testByteFields', function() { - var message = []; - var lowerLimit = 1; - var upperLimit = 256; - var scale = 1.1; - - var writer = new jspb.BinaryWriter(); - - for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) { - var len = Math.round(cursor); - var bytes = []; - for (var i = 0; i < len; i++) bytes.push(i % 256); - - writer.writeBytes(len, bytes); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) { - var len = Math.round(cursor); - if (len != reader.getFieldNumber()) throw 'fail!'; - - var bytes = reader.readBytes(); - if (len != bytes.length) throw 'fail!'; - for (var i = 0; i < bytes.length; i++) { - if (i % 256 != bytes[i]) throw 'fail!'; - } - } - }); - - - /** - * Tests nested messages. - */ - it('testNesting', function() { - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - - writer.writeInt32(1, 100); - - // Add one message with 3 int fields. - writer.writeMessage(2, dummyMessage, function() { - writer.writeInt32(3, 300); - writer.writeInt32(4, 400); - writer.writeInt32(5, 500); - }); - - // Add one empty message. - writer.writeMessage(6, dummyMessage, () => {}); - - writer.writeInt32(7, 700); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - // Validate outermost message. - - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(100, reader.readInt32()); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - // Validate embedded message 1. - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(300, reader.readInt32()); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(400, reader.readInt32()); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(500, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }); - - reader.nextField(); - assertEquals(6, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - // Validate embedded message 2. - - assertEquals(false, reader.nextField()); - }); - - reader.nextField(); - assertEquals(7, reader.getFieldNumber()); - assertEquals(700, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }); - - /** - * Tests skipping fields of each type by interleaving them with sentinel - * values and skipping everything that's not a sentinel. - */ - it('testSkipField', function() { - var writer = new jspb.BinaryWriter(); - - var sentinel = 123456789; - - // Write varint fields of different sizes. - writer.writeInt32(1, sentinel); - writer.writeInt32(1, 1); - writer.writeInt32(1, 1000); - writer.writeInt32(1, 1000000); - writer.writeInt32(1, 1000000000); - - // Write fixed 64-bit encoded fields. - writer.writeInt32(2, sentinel); - writer.writeDouble(2, 1); - writer.writeFixed64(2, 1); - writer.writeSfixed64(2, 1); - - // Write fixed 32-bit encoded fields. - writer.writeInt32(3, sentinel); - writer.writeFloat(3, 1); - writer.writeFixed32(3, 1); - writer.writeSfixed32(3, 1); - - // Write delimited fields. - writer.writeInt32(4, sentinel); - writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - writer.writeString(4, 'The quick brown fox jumps over the lazy dog'); - - // Write a group with a nested group inside. - writer.writeInt32(5, sentinel); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - writer.writeGroup(5, dummyMessage, function() { - // Previously the skipGroup implementation was wrong, which only consume - // the decoder by nextField. This case is for making the previous - // implementation failed in skipGroup by an early end group tag. - // The reason is 44 = 5 * 8 + 4, this will be translated in to a field - // with number 5 and with type 4 (end group) - writer.writeInt64(44, 44); - // This will make previous implementation failed by invalid tag (7). - writer.writeInt64(42, 47); - writer.writeInt64(42, 42); - // This is for making the previous implementation failed by an invalid - // varint. The bytes have at least 9 consecutive minus byte, which will - // fail in this.nextField for previous implementation. - writer.writeBytes(43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); - writer.writeGroup(6, dummyMessage, function() { - writer.writeInt64(84, 42); - writer.writeInt64(84, 44); - writer.writeBytes( - 43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); - }); - }); - - // Write final sentinel. - writer.writeInt32(6, sentinel); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - function skip(field, count) { - for (var i = 0; i < count; i++) { - reader.nextField(); - if (field != reader.getFieldNumber()) throw 'fail!'; - reader.skipField(); - } - } - - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(1, 4); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(2, 3); - - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(3, 3); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(4, 2); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(5, 1); - - reader.nextField(); - assertEquals(6, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - }); - - - /** - * Tests packed fields. - */ - it('testPackedFields', function() { - var writer = new jspb.BinaryWriter(); - - var sentinel = 123456789; - - var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]; - var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; - var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; - var boolData = [true, false, true, true, false, false, true, false]; - - for (var i = 0; i < floatData.length; i++) { - floatData[i] = truncate(floatData[i]); - } - - writer.writeInt32(1, sentinel); - - writer.writePackedInt32(2, signedData); - writer.writePackedInt64(2, signedData); - writer.writePackedUint32(2, unsignedData); - writer.writePackedUint64(2, unsignedData); - writer.writePackedSint32(2, signedData); - writer.writePackedSint64(2, signedData); - writer.writePackedFixed32(2, unsignedData); - writer.writePackedFixed64(2, unsignedData); - writer.writePackedSfixed32(2, signedData); - writer.writePackedSfixed64(2, signedData); - writer.writePackedFloat(2, floatData); - writer.writePackedDouble(2, doubleData); - writer.writePackedBool(2, boolData); - writer.writePackedEnum(2, unsignedData); - - writer.writeInt32(3, sentinel); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - reader.nextField(); - assertEquals(sentinel, reader.readInt32()); - - reader.nextField(); - assertElementsEquals(reader.readPackedInt32(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedInt64(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedUint32(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedUint64(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSint32(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSint64(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedFixed32(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedFixed64(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSfixed32(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSfixed64(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedFloat(), floatData); - - reader.nextField(); - assertElementsEquals(reader.readPackedDouble(), doubleData); - - reader.nextField(); - assertElementsEquals(reader.readPackedBool(), boolData); - - reader.nextField(); - assertElementsEquals(reader.readPackedEnum(), unsignedData); - - reader.nextField(); - assertEquals(sentinel, reader.readInt32()); - }); - - - /** - * Byte blobs inside nested messages should always have their byte offset set - * relative to the start of the outermost blob, not the start of their parent - * blob. - */ - it('testNestedBlobs', function() { - // Create a proto consisting of two nested messages, with the inner one - // containing a blob of bytes. - - var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED; - var blob = [1, 2, 3, 4, 5]; - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - - writer.writeMessage(1, dummyMessage, function() { - writer.writeMessage(1, dummyMessage, function() { - writer.writeBytes(1, blob); - }); - }); - - // Peel off the outer two message layers. Each layer should have two bytes - // of overhead, one for the field tag and one for the length of the inner - // blob. - - var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer()); - assertEquals(fieldTag, decoder1.readUnsignedVarint32()); - assertEquals(blob.length + 4, decoder1.readUnsignedVarint32()); - - var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4)); - assertEquals(fieldTag, decoder2.readUnsignedVarint32()); - assertEquals(blob.length + 2, decoder2.readUnsignedVarint32()); - - assertEquals(fieldTag, decoder2.readUnsignedVarint32()); - assertEquals(blob.length, decoder2.readUnsignedVarint32()); - var bytes = decoder2.readBytes(blob.length); - - assertElementsEquals(bytes, blob); - }); - - - /** - * Tests read callbacks. - */ - it('testReadCallbacks', function() { - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - - // Add an int, a submessage, and another int. - writer.writeInt32(1, 100); - - writer.writeMessage(2, dummyMessage, function() { - writer.writeInt32(3, 300); - writer.writeInt32(4, 400); - writer.writeInt32(5, 500); - }); - - writer.writeInt32(7, 700); - - // Create the reader and register a custom read callback. - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - /** - * @param {!jspb.BinaryReader} reader - * @return {*} - */ - function readCallback(reader) { - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(300, reader.readInt32()); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(400, reader.readInt32()); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(500, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }; - - reader.registerReadCallback('readCallback', readCallback); - - // Read the container message. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(100, reader.readInt32()); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - // Decode the embedded message using the registered callback. - reader.runReadCallback('readCallback'); - }); - - reader.nextField(); - assertEquals(7, reader.getFieldNumber()); - assertEquals(700, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }); -}); diff --git a/js/binary/utils.js b/js/binary/utils.js deleted file mode 100644 index d28102724..000000000 --- a/js/binary/utils.js +++ /dev/null @@ -1,1071 +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. - -/** - * @fileoverview This file contains helper code used by jspb.BinaryReader - * and BinaryWriter. - * - * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed - * @author aappleby@google.com (Austin Appleby) - */ - -goog.provide('jspb.utils'); - -goog.require('goog.asserts'); -goog.require('goog.crypt'); -goog.require('goog.crypt.base64'); -goog.require('goog.string'); -goog.require('jspb.BinaryConstants'); - - -/** - * Javascript can't natively handle 64-bit data types, so to manipulate them we - * have to split them into two 32-bit halves and do the math manually. - * - * Instead of instantiating and passing small structures around to do this, we - * instead just use two global temporary values. This one stores the low 32 - * bits of a split value - for example, if the original value was a 64-bit - * integer, this temporary value will contain the low 32 bits of that integer. - * If the original value was a double, this temporary value will contain the - * low 32 bits of the binary representation of that double, etcetera. - * @type {number} - */ -jspb.utils.split64Low = 0; - - -/** - * And correspondingly, this temporary variable will contain the high 32 bits - * of whatever value was split. - * @type {number} - */ -jspb.utils.split64High = 0; - - -/** - * Splits an unsigned Javascript integer into two 32-bit halves and stores it - * in the temp values above. - * @param {number} value The number to split. - */ -jspb.utils.splitUint64 = function(value) { - // Extract low 32 bits and high 32 bits as unsigned integers. - var lowBits = value >>> 0; - var highBits = Math.floor((value - lowBits) / - jspb.BinaryConstants.TWO_TO_32) >>> 0; - - jspb.utils.split64Low = lowBits; - jspb.utils.split64High = highBits; -}; - - -/** - * Splits a signed Javascript integer into two 32-bit halves and stores it in - * the temp values above. - * @param {number} value The number to split. - */ -jspb.utils.splitInt64 = function(value) { - // Convert to sign-magnitude representation. - var sign = (value < 0); - value = Math.abs(value); - - // Extract low 32 bits and high 32 bits as unsigned integers. - var lowBits = value >>> 0; - var highBits = Math.floor((value - lowBits) / - jspb.BinaryConstants.TWO_TO_32); - highBits = highBits >>> 0; - - // Perform two's complement conversion if the sign bit was set. - if (sign) { - highBits = ~highBits >>> 0; - lowBits = ~lowBits >>> 0; - lowBits += 1; - if (lowBits > 0xFFFFFFFF) { - lowBits = 0; - highBits++; - if (highBits > 0xFFFFFFFF) highBits = 0; - } - } - - jspb.utils.split64Low = lowBits; - jspb.utils.split64High = highBits; -}; - - -/** - * Converts a signed Javascript integer into zigzag format, splits it into two - * 32-bit halves, and stores it in the temp values above. - * @param {number} value The number to split. - */ -jspb.utils.splitZigzag64 = function(value) { - // Convert to sign-magnitude and scale by 2 before we split the value. - var sign = (value < 0); - value = Math.abs(value) * 2; - - jspb.utils.splitUint64(value); - var lowBits = jspb.utils.split64Low; - var highBits = jspb.utils.split64High; - - // If the value is negative, subtract 1 from the split representation so we - // don't lose the sign bit due to precision issues. - if (sign) { - if (lowBits == 0) { - if (highBits == 0) { - lowBits = 0xFFFFFFFF; - highBits = 0xFFFFFFFF; - } else { - highBits--; - lowBits = 0xFFFFFFFF; - } - } else { - lowBits--; - } - } - - jspb.utils.split64Low = lowBits; - jspb.utils.split64High = highBits; -}; - - -/** - * Converts a floating-point number into 32-bit IEEE representation and stores - * it in the temp values above. - * @param {number} value - */ -jspb.utils.splitFloat32 = function(value) { - var sign = (value < 0) ? 1 : 0; - value = sign ? -value : value; - var exp; - var mant; - - // Handle zeros. - if (value === 0) { - if ((1 / value) > 0) { - // Positive zero. - jspb.utils.split64High = 0; - jspb.utils.split64Low = 0x00000000; - } else { - // Negative zero. - jspb.utils.split64High = 0; - jspb.utils.split64Low = 0x80000000; - } - return; - } - - // Handle nans. - if (isNaN(value)) { - jspb.utils.split64High = 0; - jspb.utils.split64Low = 0x7FFFFFFF; - return; - } - - // Handle infinities. - if (value > jspb.BinaryConstants.FLOAT32_MAX) { - jspb.utils.split64High = 0; - jspb.utils.split64Low = ((sign << 31) | (0x7F800000)) >>> 0; - return; - } - - // Handle denormals. - if (value < jspb.BinaryConstants.FLOAT32_MIN) { - // Number is a denormal. - mant = Math.round(value / Math.pow(2, -149)); - jspb.utils.split64High = 0; - jspb.utils.split64Low = ((sign << 31) | mant) >>> 0; - return; - } - - exp = Math.floor(Math.log(value) / Math.LN2); - mant = value * Math.pow(2, -exp); - mant = Math.round(mant * jspb.BinaryConstants.TWO_TO_23); - if (mant >= 0x1000000) { - ++exp; - } - mant = mant & 0x7FFFFF; - - jspb.utils.split64High = 0; - jspb.utils.split64Low = ((sign << 31) | ((exp + 127) << 23) | mant) >>> 0; -}; - - -/** - * Converts a floating-point number into 64-bit IEEE representation and stores - * it in the temp values above. - * @param {number} value - */ -jspb.utils.splitFloat64 = function(value) { - var sign = (value < 0) ? 1 : 0; - value = sign ? -value : value; - - // Handle zeros. - if (value === 0) { - if ((1 / value) > 0) { - // Positive zero. - jspb.utils.split64High = 0x00000000; - jspb.utils.split64Low = 0x00000000; - } else { - // Negative zero. - jspb.utils.split64High = 0x80000000; - jspb.utils.split64Low = 0x00000000; - } - return; - } - - // Handle nans. - if (isNaN(value)) { - jspb.utils.split64High = 0x7FFFFFFF; - jspb.utils.split64Low = 0xFFFFFFFF; - return; - } - - // Handle infinities. - if (value > jspb.BinaryConstants.FLOAT64_MAX) { - jspb.utils.split64High = ((sign << 31) | (0x7FF00000)) >>> 0; - jspb.utils.split64Low = 0; - return; - } - - // Handle denormals. - if (value < jspb.BinaryConstants.FLOAT64_MIN) { - // Number is a denormal. - var mant = value / Math.pow(2, -1074); - var mantHigh = (mant / jspb.BinaryConstants.TWO_TO_32); - jspb.utils.split64High = ((sign << 31) | mantHigh) >>> 0; - jspb.utils.split64Low = (mant >>> 0); - return; - } - - // Compute the least significant exponent needed to represent the magnitude of - // the value by repeadly dividing/multiplying by 2 until the magnitude - // crosses 2. While tempting to use log math to find the exponent, at the - // boundaries of precision, the result can be off by one. - var maxDoubleExponent = 1023; - var minDoubleExponent = -1022; - var x = value; - var exp = 0; - if (x >= 2) { - while (x >= 2 && exp < maxDoubleExponent) { - exp++; - x = x / 2; - } - } else { - while (x < 1 && exp > minDoubleExponent) { - x = x * 2; - exp--; - } - } - var mant = value * Math.pow(2, -exp); - - var mantHigh = (mant * jspb.BinaryConstants.TWO_TO_20) & 0xFFFFF; - var mantLow = (mant * jspb.BinaryConstants.TWO_TO_52) >>> 0; - - jspb.utils.split64High = - ((sign << 31) | ((exp + 1023) << 20) | mantHigh) >>> 0; - jspb.utils.split64Low = mantLow; -}; - - -/** - * Converts an 8-character hash string into two 32-bit numbers and stores them - * in the temp values above. - * @param {string} hash - */ -jspb.utils.splitHash64 = function(hash) { - var a = hash.charCodeAt(0); - var b = hash.charCodeAt(1); - var c = hash.charCodeAt(2); - var d = hash.charCodeAt(3); - var e = hash.charCodeAt(4); - var f = hash.charCodeAt(5); - var g = hash.charCodeAt(6); - var h = hash.charCodeAt(7); - - jspb.utils.split64Low = (a + (b << 8) + (c << 16) + (d << 24)) >>> 0; - jspb.utils.split64High = (e + (f << 8) + (g << 16) + (h << 24)) >>> 0; -}; - - -/** - * Joins two 32-bit values into a 64-bit unsigned integer. Precision will be - * lost if the result is greater than 2^52. - * @param {number} bitsLow - * @param {number} bitsHigh - * @return {number} - */ -jspb.utils.joinUint64 = function(bitsLow, bitsHigh) { - return bitsHigh * jspb.BinaryConstants.TWO_TO_32 + (bitsLow >>> 0); -}; - - -/** - * Joins two 32-bit values into a 64-bit signed integer. Precision will be lost - * if the result is greater than 2^52. - * @param {number} bitsLow - * @param {number} bitsHigh - * @return {number} - */ -jspb.utils.joinInt64 = function(bitsLow, bitsHigh) { - // If the high bit is set, do a manual two's complement conversion. - var sign = (bitsHigh & 0x80000000); - if (sign) { - bitsLow = (~bitsLow + 1) >>> 0; - bitsHigh = ~bitsHigh >>> 0; - if (bitsLow == 0) { - bitsHigh = (bitsHigh + 1) >>> 0; - } - } - - var result = jspb.utils.joinUint64(bitsLow, bitsHigh); - return sign ? -result : result; -}; - -/** - * Converts split 64-bit values from standard two's complement encoding to - * zig-zag encoding. Invokes the provided function to produce final result. - * - * @param {number} bitsLow - * @param {number} bitsHigh - * @param {function(number, number): T} convert Conversion function to produce - * the result value, takes parameters (lowBits, highBits). - * @return {T} - * @template T - */ -jspb.utils.toZigzag64 = function(bitsLow, bitsHigh, convert) { - // See - // https://engdoc.corp.google.com/eng/howto/protocolbuffers/developerguide/encoding.shtml?cl=head#types - // 64-bit math is: (n << 1) ^ (n >> 63) - // - // To do this in 32 bits, we can get a 32-bit sign-flipping mask from the - // high word. - // Then we can operate on each word individually, with the addition of the - // "carry" to get the most significant bit from the low word into the high - // word. - var signFlipMask = bitsHigh >> 31; - bitsHigh = (bitsHigh << 1 | bitsLow >>> 31) ^ signFlipMask; - bitsLow = (bitsLow << 1) ^ signFlipMask; - return convert(bitsLow, bitsHigh); -}; - - -/** - * Joins two 32-bit values into a 64-bit unsigned integer and applies zigzag - * decoding. Precision will be lost if the result is greater than 2^52. - * @param {number} bitsLow - * @param {number} bitsHigh - * @return {number} - */ -jspb.utils.joinZigzag64 = function(bitsLow, bitsHigh) { - return jspb.utils.fromZigzag64(bitsLow, bitsHigh, jspb.utils.joinInt64); -}; - - -/** - * Converts split 64-bit values from zigzag encoding to standard two's - * complement encoding. Invokes the provided function to produce final result. - * - * @param {number} bitsLow - * @param {number} bitsHigh - * @param {function(number, number): T} convert Conversion function to produce - * the result value, takes parameters (lowBits, highBits). - * @return {T} - * @template T - */ -jspb.utils.fromZigzag64 = function(bitsLow, bitsHigh, convert) { - // 64 bit math is: - // signmask = (zigzag & 1) ? -1 : 0; - // twosComplement = (zigzag >> 1) ^ signmask; - // - // To work with 32 bit, we can operate on both but "carry" the lowest bit - // from the high word by shifting it up 31 bits to be the most significant bit - // of the low word. - var signFlipMask = -(bitsLow & 1); - bitsLow = ((bitsLow >>> 1) | (bitsHigh << 31)) ^ signFlipMask; - bitsHigh = (bitsHigh >>> 1) ^ signFlipMask; - return convert(bitsLow, bitsHigh); -}; - - -/** - * Joins two 32-bit values into a 32-bit IEEE floating point number and - * converts it back into a Javascript number. - * @param {number} bitsLow The low 32 bits of the binary number; - * @param {number} bitsHigh The high 32 bits of the binary number. - * @return {number} - */ -jspb.utils.joinFloat32 = function(bitsLow, bitsHigh) { - var sign = ((bitsLow >> 31) * 2 + 1); - var exp = (bitsLow >>> 23) & 0xFF; - var mant = bitsLow & 0x7FFFFF; - - if (exp == 0xFF) { - if (mant) { - return NaN; - } else { - return sign * Infinity; - } - } - - if (exp == 0) { - // Denormal. - return sign * Math.pow(2, -149) * mant; - } else { - return sign * Math.pow(2, exp - 150) * - (mant + Math.pow(2, 23)); - } -}; - - -/** - * Joins two 32-bit values into a 64-bit IEEE floating point number and - * converts it back into a Javascript number. - * @param {number} bitsLow The low 32 bits of the binary number; - * @param {number} bitsHigh The high 32 bits of the binary number. - * @return {number} - */ -jspb.utils.joinFloat64 = function(bitsLow, bitsHigh) { - var sign = ((bitsHigh >> 31) * 2 + 1); - var exp = (bitsHigh >>> 20) & 0x7FF; - var mant = jspb.BinaryConstants.TWO_TO_32 * (bitsHigh & 0xFFFFF) + bitsLow; - - if (exp == 0x7FF) { - if (mant) { - return NaN; - } else { - return sign * Infinity; - } - } - - if (exp == 0) { - // Denormal. - return sign * Math.pow(2, -1074) * mant; - } else { - return sign * Math.pow(2, exp - 1075) * - (mant + jspb.BinaryConstants.TWO_TO_52); - } -}; - - -/** - * Joins two 32-bit values into an 8-character hash string. - * @param {number} bitsLow - * @param {number} bitsHigh - * @return {string} - */ -jspb.utils.joinHash64 = function(bitsLow, bitsHigh) { - var a = (bitsLow >>> 0) & 0xFF; - var b = (bitsLow >>> 8) & 0xFF; - var c = (bitsLow >>> 16) & 0xFF; - var d = (bitsLow >>> 24) & 0xFF; - var e = (bitsHigh >>> 0) & 0xFF; - var f = (bitsHigh >>> 8) & 0xFF; - var g = (bitsHigh >>> 16) & 0xFF; - var h = (bitsHigh >>> 24) & 0xFF; - - return String.fromCharCode(a, b, c, d, e, f, g, h); -}; - -/** - * Individual digits for number->string conversion. - * @const {!Array} - */ -jspb.utils.DIGITS = [ - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' -]; - -/** @const @private {number} '0' */ -jspb.utils.ZERO_CHAR_CODE_ = 48; - -/** @const @private {number} 'a' */ -jspb.utils.A_CHAR_CODE_ = 97; - -/** - * Losslessly converts a 64-bit unsigned integer in 32:32 split representation - * into a decimal string. - * @param {number} bitsLow The low 32 bits of the binary number; - * @param {number} bitsHigh The high 32 bits of the binary number. - * @return {string} The binary number represented as a string. - */ -jspb.utils.joinUnsignedDecimalString = function(bitsLow, bitsHigh) { - // Skip the expensive conversion if the number is small enough to use the - // built-in conversions. - if (bitsHigh <= 0x1FFFFF) { - return '' + jspb.utils.joinUint64(bitsLow, bitsHigh); - } - - // What this code is doing is essentially converting the input number from - // base-2 to base-1e7, which allows us to represent the 64-bit range with - // only 3 (very large) digits. Those digits are then trivial to convert to - // a base-10 string. - - // The magic numbers used here are - - // 2^24 = 16777216 = (1,6777216) in base-1e7. - // 2^48 = 281474976710656 = (2,8147497,6710656) in base-1e7. - - // Split 32:32 representation into 16:24:24 representation so our - // intermediate digits don't overflow. - var low = bitsLow & 0xFFFFFF; - var mid = (((bitsLow >>> 24) | (bitsHigh << 8)) >>> 0) & 0xFFFFFF; - var high = (bitsHigh >> 16) & 0xFFFF; - - // Assemble our three base-1e7 digits, ignoring carries. The maximum - // value in a digit at this step is representable as a 48-bit integer, which - // can be stored in a 64-bit floating point number. - var digitA = low + (mid * 6777216) + (high * 6710656); - var digitB = mid + (high * 8147497); - var digitC = (high * 2); - - // Apply carries from A to B and from B to C. - var base = 10000000; - if (digitA >= base) { - digitB += Math.floor(digitA / base); - digitA %= base; - } - - if (digitB >= base) { - digitC += Math.floor(digitB / base); - digitB %= base; - } - - // Convert base-1e7 digits to base-10, with optional leading zeroes. - function decimalFrom1e7(digit1e7, needLeadingZeros) { - var partial = digit1e7 ? String(digit1e7) : ''; - if (needLeadingZeros) { - return '0000000'.slice(partial.length) + partial; - } - return partial; - } - - return decimalFrom1e7(digitC, /*needLeadingZeros=*/ 0) + - decimalFrom1e7(digitB, /*needLeadingZeros=*/ digitC) + - // If the final 1e7 digit didn't need leading zeros, we would have - // returned via the trivial code path at the top. - decimalFrom1e7(digitA, /*needLeadingZeros=*/ 1); -}; - - -/** - * Losslessly converts a 64-bit signed integer in 32:32 split representation - * into a decimal string. - * @param {number} bitsLow The low 32 bits of the binary number; - * @param {number} bitsHigh The high 32 bits of the binary number. - * @return {string} The binary number represented as a string. - */ -jspb.utils.joinSignedDecimalString = function(bitsLow, bitsHigh) { - // If we're treating the input as a signed value and the high bit is set, do - // a manual two's complement conversion before the decimal conversion. - var negative = (bitsHigh & 0x80000000); - if (negative) { - bitsLow = (~bitsLow + 1) >>> 0; - var carry = (bitsLow == 0) ? 1 : 0; - bitsHigh = (~bitsHigh + carry) >>> 0; - } - - var result = jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh); - return negative ? '-' + result : result; -}; - - -/** - * Convert an 8-character hash string representing either a signed or unsigned - * 64-bit integer into its decimal representation without losing accuracy. - * @param {string} hash The hash string to convert. - * @param {boolean} signed True if we should treat the hash string as encoding - * a signed integer. - * @return {string} - */ -jspb.utils.hash64ToDecimalString = function(hash, signed) { - jspb.utils.splitHash64(hash); - var bitsLow = jspb.utils.split64Low; - var bitsHigh = jspb.utils.split64High; - return signed ? - jspb.utils.joinSignedDecimalString(bitsLow, bitsHigh) : - jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh); -}; - - -/** - * Converts an array of 8-character hash strings into their decimal - * representations. - * @param {!Array} hashes The array of hash strings to convert. - * @param {boolean} signed True if we should treat the hash string as encoding - * a signed integer. - * @return {!Array} - */ -jspb.utils.hash64ArrayToDecimalStrings = function(hashes, signed) { - var result = new Array(hashes.length); - for (var i = 0; i < hashes.length; i++) { - result[i] = jspb.utils.hash64ToDecimalString(hashes[i], signed); - } - return result; -}; - - -/** - * Converts a signed or unsigned decimal string into its hash string - * representation. - * @param {string} dec - * @return {string} - */ -jspb.utils.decimalStringToHash64 = function(dec) { - goog.asserts.assert(dec.length > 0); - - // Check for minus sign. - var minus = false; - if (dec[0] === '-') { - minus = true; - dec = dec.slice(1); - } - - // Store result as a byte array. - var resultBytes = [0, 0, 0, 0, 0, 0, 0, 0]; - - // Set result to m*result + c. - function muladd(m, c) { - for (var i = 0; i < 8 && (m !== 1 || c > 0); i++) { - var r = m * resultBytes[i] + c; - resultBytes[i] = r & 0xFF; - c = r >>> 8; - } - } - - // Negate the result bits. - function neg() { - for (var i = 0; i < 8; i++) { - resultBytes[i] = (~resultBytes[i]) & 0xFF; - } - } - - // For each decimal digit, set result to 10*result + digit. - for (var i = 0; i < dec.length; i++) { - muladd(10, dec.charCodeAt(i) - jspb.utils.ZERO_CHAR_CODE_); - } - - // If there's a minus sign, convert into two's complement. - if (minus) { - neg(); - muladd(1, 1); - } - - return goog.crypt.byteArrayToString(resultBytes); -}; - - -/** - * Converts a signed or unsigned decimal string into two 32-bit halves, and - * stores them in the temp variables listed above. - * @param {string} value The decimal string to convert. - */ -jspb.utils.splitDecimalString = function(value) { - jspb.utils.splitHash64(jspb.utils.decimalStringToHash64(value)); -}; - -/** - * @param {number} nibble A 4-bit integer. - * @return {string} - * @private - */ -jspb.utils.toHexDigit_ = function(nibble) { - return String.fromCharCode( - nibble < 10 ? jspb.utils.ZERO_CHAR_CODE_ + nibble : - jspb.utils.A_CHAR_CODE_ - 10 + nibble); -}; - -/** - * @param {number} hexCharCode - * @return {number} - * @private - */ -jspb.utils.fromHexCharCode_ = function(hexCharCode) { - if (hexCharCode >= jspb.utils.A_CHAR_CODE_) { - return hexCharCode - jspb.utils.A_CHAR_CODE_ + 10; - } - return hexCharCode - jspb.utils.ZERO_CHAR_CODE_; -}; - -/** - * Converts an 8-character hash string into its hexadecimal representation. - * @param {string} hash - * @return {string} - */ -jspb.utils.hash64ToHexString = function(hash) { - var temp = new Array(18); - temp[0] = '0'; - temp[1] = 'x'; - - for (var i = 0; i < 8; i++) { - var c = hash.charCodeAt(7 - i); - temp[i * 2 + 2] = jspb.utils.toHexDigit_(c >> 4); - temp[i * 2 + 3] = jspb.utils.toHexDigit_(c & 0xF); - } - - var result = temp.join(''); - return result; -}; - - -/** - * Converts a '0x<16 digits>' hex string into its hash string representation. - * @param {string} hex - * @return {string} - */ -jspb.utils.hexStringToHash64 = function(hex) { - hex = hex.toLowerCase(); - goog.asserts.assert(hex.length == 18); - goog.asserts.assert(hex[0] == '0'); - goog.asserts.assert(hex[1] == 'x'); - - var result = ''; - for (var i = 0; i < 8; i++) { - var hi = jspb.utils.fromHexCharCode_(hex.charCodeAt(i * 2 + 2)); - var lo = jspb.utils.fromHexCharCode_(hex.charCodeAt(i * 2 + 3)); - result = String.fromCharCode(hi * 16 + lo) + result; - } - - return result; -}; - - -/** - * Convert an 8-character hash string representing either a signed or unsigned - * 64-bit integer into a Javascript number. Will lose accuracy if the result is - * larger than 2^52. - * @param {string} hash The hash string to convert. - * @param {boolean} signed True if the has should be interpreted as a signed - * number. - * @return {number} - */ -jspb.utils.hash64ToNumber = function(hash, signed) { - jspb.utils.splitHash64(hash); - var bitsLow = jspb.utils.split64Low; - var bitsHigh = jspb.utils.split64High; - return signed ? jspb.utils.joinInt64(bitsLow, bitsHigh) : - jspb.utils.joinUint64(bitsLow, bitsHigh); -}; - - -/** - * Convert a Javascript number into an 8-character hash string. Will lose - * precision if the value is non-integral or greater than 2^64. - * @param {number} value The integer to convert. - * @return {string} - */ -jspb.utils.numberToHash64 = function(value) { - jspb.utils.splitInt64(value); - return jspb.utils.joinHash64(jspb.utils.split64Low, - jspb.utils.split64High); -}; - - -/** - * Counts the number of contiguous varints in a buffer. - * @param {!Uint8Array} buffer The buffer to scan. - * @param {number} start The starting point in the buffer to scan. - * @param {number} end The end point in the buffer to scan. - * @return {number} The number of varints in the buffer. - */ -jspb.utils.countVarints = function(buffer, start, end) { - // Count how many high bits of each byte were set in the buffer. - var count = 0; - for (var i = start; i < end; i++) { - count += buffer[i] >> 7; - } - - // The number of varints in the buffer equals the size of the buffer minus - // the number of non-terminal bytes in the buffer (those with the high bit - // set). - return (end - start) - count; -}; - - -/** - * Counts the number of contiguous varint fields with the given field number in - * the buffer. - * @param {!Uint8Array} buffer The buffer to scan. - * @param {number} start The starting point in the buffer to scan. - * @param {number} end The end point in the buffer to scan. - * @param {number} field The field number to count. - * @return {number} The number of matching fields in the buffer. - */ -jspb.utils.countVarintFields = function(buffer, start, end, field) { - var count = 0; - var cursor = start; - var tag = field * 8 + jspb.BinaryConstants.WireType.VARINT; - - if (tag < 128) { - // Single-byte field tag, we can use a slightly quicker count. - while (cursor < end) { - // Skip the field tag, or exit if we find a non-matching tag. - if (buffer[cursor++] != tag) return count; - - // Field tag matches, we've found a valid field. - count++; - - // Skip the varint. - while (1) { - var x = buffer[cursor++]; - if ((x & 0x80) == 0) break; - } - } - } else { - while (cursor < end) { - // Skip the field tag, or exit if we find a non-matching tag. - var temp = tag; - while (temp > 128) { - if (buffer[cursor] != ((temp & 0x7F) | 0x80)) return count; - cursor++; - temp >>= 7; - } - if (buffer[cursor++] != temp) return count; - - // Field tag matches, we've found a valid field. - count++; - - // Skip the varint. - while (1) { - var x = buffer[cursor++]; - if ((x & 0x80) == 0) break; - } - } - } - return count; -}; - - -/** - * Counts the number of contiguous fixed32 fields with the given tag in the - * buffer. - * @param {!Uint8Array} buffer The buffer to scan. - * @param {number} start The starting point in the buffer to scan. - * @param {number} end The end point in the buffer to scan. - * @param {number} tag The tag value to count. - * @param {number} stride The number of bytes to skip per field. - * @return {number} The number of fields with a matching tag in the buffer. - * @private - */ -jspb.utils.countFixedFields_ = - function(buffer, start, end, tag, stride) { - var count = 0; - var cursor = start; - - if (tag < 128) { - // Single-byte field tag, we can use a slightly quicker count. - while (cursor < end) { - // Skip the field tag, or exit if we find a non-matching tag. - if (buffer[cursor++] != tag) return count; - - // Field tag matches, we've found a valid field. - count++; - - // Skip the value. - cursor += stride; - } - } else { - while (cursor < end) { - // Skip the field tag, or exit if we find a non-matching tag. - var temp = tag; - while (temp > 128) { - if (buffer[cursor++] != ((temp & 0x7F) | 0x80)) return count; - temp >>= 7; - } - if (buffer[cursor++] != temp) return count; - - // Field tag matches, we've found a valid field. - count++; - - // Skip the value. - cursor += stride; - } - } - return count; -}; - - -/** - * Counts the number of contiguous fixed32 fields with the given field number - * in the buffer. - * @param {!Uint8Array} buffer The buffer to scan. - * @param {number} start The starting point in the buffer to scan. - * @param {number} end The end point in the buffer to scan. - * @param {number} field The field number to count. - * @return {number} The number of matching fields in the buffer. - */ -jspb.utils.countFixed32Fields = function(buffer, start, end, field) { - var tag = field * 8 + jspb.BinaryConstants.WireType.FIXED32; - return jspb.utils.countFixedFields_(buffer, start, end, tag, 4); -}; - - -/** - * Counts the number of contiguous fixed64 fields with the given field number - * in the buffer. - * @param {!Uint8Array} buffer The buffer to scan. - * @param {number} start The starting point in the buffer to scan. - * @param {number} end The end point in the buffer to scan. - * @param {number} field The field number to count - * @return {number} The number of matching fields in the buffer. - */ -jspb.utils.countFixed64Fields = function(buffer, start, end, field) { - var tag = field * 8 + jspb.BinaryConstants.WireType.FIXED64; - return jspb.utils.countFixedFields_(buffer, start, end, tag, 8); -}; - - -/** - * Counts the number of contiguous delimited fields with the given field number - * in the buffer. - * @param {!Uint8Array} buffer The buffer to scan. - * @param {number} start The starting point in the buffer to scan. - * @param {number} end The end point in the buffer to scan. - * @param {number} field The field number to count. - * @return {number} The number of matching fields in the buffer. - */ -jspb.utils.countDelimitedFields = function(buffer, start, end, field) { - var count = 0; - var cursor = start; - var tag = field * 8 + jspb.BinaryConstants.WireType.DELIMITED; - - while (cursor < end) { - // Skip the field tag, or exit if we find a non-matching tag. - var temp = tag; - while (temp > 128) { - if (buffer[cursor++] != ((temp & 0x7F) | 0x80)) return count; - temp >>= 7; - } - if (buffer[cursor++] != temp) return count; - - // Field tag matches, we've found a valid field. - count++; - - // Decode the length prefix. - var length = 0; - var shift = 1; - while (1) { - temp = buffer[cursor++]; - length += (temp & 0x7f) * shift; - shift *= 128; - if ((temp & 0x80) == 0) break; - } - - // Advance the cursor past the blob. - cursor += length; - } - return count; -}; - - -/** - * String-ify bytes for text format. Should be optimized away in non-debug. - * The returned string uses \xXX escapes for all values and is itself quoted. - * [1, 31] serializes to '"\x01\x1f"'. - * @param {jspb.ByteSource} byteSource The bytes to serialize. - * @return {string} Stringified bytes for text format. - */ -jspb.utils.debugBytesToTextFormat = function(byteSource) { - var s = '"'; - if (byteSource) { - var bytes = jspb.utils.byteSourceToUint8Array(byteSource); - for (var i = 0; i < bytes.length; i++) { - s += '\\x'; - if (bytes[i] < 16) s += '0'; - s += bytes[i].toString(16); - } - } - return s + '"'; -}; - - -/** - * String-ify a scalar for text format. Should be optimized away in non-debug. - * @param {string|number|boolean} scalar The scalar to stringify. - * @return {string} Stringified scalar for text format. - */ -jspb.utils.debugScalarToTextFormat = function(scalar) { - if (typeof scalar === 'string') { - return goog.string.quote(scalar); - } else { - return scalar.toString(); - } -}; - - -/** - * Utility function: convert a string with codepoints 0--255 inclusive to a - * Uint8Array. If any codepoints greater than 255 exist in the string, throws an - * exception. - * @param {string} str - * @return {!Uint8Array} - */ -jspb.utils.stringToByteArray = function(str) { - var arr = new Uint8Array(str.length); - for (var i = 0; i < str.length; i++) { - var codepoint = str.charCodeAt(i); - if (codepoint > 255) { - throw new Error('Conversion error: string contains codepoint ' + - 'outside of byte range'); - } - arr[i] = codepoint; - } - return arr; -}; - - -/** - * Converts any type defined in jspb.ByteSource into a Uint8Array. - * @param {!jspb.ByteSource} data - * @return {!Uint8Array} - * @suppress {invalidCasts} - */ -jspb.utils.byteSourceToUint8Array = function(data) { - if (data.constructor === Uint8Array) { - return /** @type {!Uint8Array} */(data); - } - - if (data.constructor === ArrayBuffer) { - data = /** @type {!ArrayBuffer} */(data); - return /** @type {!Uint8Array} */(new Uint8Array(data)); - } - - if (typeof Buffer != 'undefined' && data.constructor === Buffer) { - return /** @type {!Uint8Array} */ ( - new Uint8Array(/** @type {?} */ (data))); - } - - if (data.constructor === Array) { - data = /** @type {!Array} */(data); - return /** @type {!Uint8Array} */(new Uint8Array(data)); - } - - if (data.constructor === String) { - data = /** @type {string} */(data); - return goog.crypt.base64.decodeStringToUint8Array(data); - } - - goog.asserts.fail('Type not convertible to Uint8Array.'); - return /** @type {!Uint8Array} */(new Uint8Array(0)); -}; diff --git a/js/binary/utils_test.js b/js/binary/utils_test.js deleted file mode 100644 index 70585db46..000000000 --- a/js/binary/utils_test.js +++ /dev/null @@ -1,744 +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. - -/** - * @fileoverview Test cases for jspb's helper functions. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.crypt'); -goog.require('goog.crypt.base64'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryWriter'); -goog.require('jspb.utils'); - - -/** - * @param {number} x - * @return {number} - */ -function truncate(x) { - var temp = new Float32Array(1); - temp[0] = x; - return temp[0]; -} - - -/** - * Converts an 64-bit integer in split representation to a 64-bit hash string - * (8 bits encoded per character). - * @param {number} bitsLow The low 32 bits of the split 64-bit integer. - * @param {number} bitsHigh The high 32 bits of the split 64-bit integer. - * @return {string} The encoded hash string, 8 bits per character. - */ -function toHashString(bitsLow, bitsHigh) { - return String.fromCharCode((bitsLow >>> 0) & 0xFF, - (bitsLow >>> 8) & 0xFF, - (bitsLow >>> 16) & 0xFF, - (bitsLow >>> 24) & 0xFF, - (bitsHigh >>> 0) & 0xFF, - (bitsHigh >>> 8) & 0xFF, - (bitsHigh >>> 16) & 0xFF, - (bitsHigh >>> 24) & 0xFF); -} - - -describe('binaryUtilsTest', function() { - /** - * Tests lossless binary-to-decimal conversion. - */ - it('testDecimalConversion', function() { - // Check some magic numbers. - var result = - jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304); - expect(result).toEqual('10000000000000000001'); - - result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b); - expect(result).toEqual('123456789123456789'); - - result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c); - expect(result).toEqual('12345678901234567890'); - - result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8); - expect(result).toEqual('9876543210987654321'); - - // Check limits. - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000); - expect(result).toEqual('0'); - - result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF); - expect(result).toEqual('18446744073709551615'); - - // Check each bit of the low dword. - for (var i = 0; i < 32; i++) { - var low = (1 << i) >>> 0; - result = jspb.utils.joinUnsignedDecimalString(low, 0); - expect(result).toEqual('' + Math.pow(2, i)); - } - - // Check the first 20 bits of the high dword. - for (var i = 0; i < 20; i++) { - var high = (1 << i) >>> 0; - result = jspb.utils.joinUnsignedDecimalString(0, high); - expect(result).toEqual('' + Math.pow(2, 32 + i)); - } - - // V8's internal double-to-string conversion is inaccurate for values above - // 2^52, even if they're representable integers - check the rest of the bits - // manually against the correct string representations of 2^N. - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000); - expect(result).toEqual('4503599627370496'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000); - expect(result).toEqual('9007199254740992'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000); - expect(result).toEqual('18014398509481984'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000); - expect(result).toEqual('36028797018963968'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000); - expect(result).toEqual('72057594037927936'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000); - expect(result).toEqual('144115188075855872'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000); - expect(result).toEqual('288230376151711744'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000); - expect(result).toEqual('576460752303423488'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000); - expect(result).toEqual('1152921504606846976'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000); - expect(result).toEqual('2305843009213693952'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000); - expect(result).toEqual('4611686018427387904'); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000); - expect(result).toEqual('9223372036854775808'); - }); - - - /** - * Going from hash strings to decimal strings should also be lossless. - */ - it('testHashToDecimalConversion', function() { - var result; - var convert = jspb.utils.hash64ToDecimalString; - - result = convert(toHashString(0x00000000, 0x00000000), false); - expect(result).toEqual('0'); - - result = convert(toHashString(0x00000000, 0x00000000), true); - expect(result).toEqual('0'); - - result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false); - expect(result).toEqual('18446744073709551615'); - - result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true); - expect(result).toEqual('-1'); - - result = convert(toHashString(0x00000000, 0x80000000), false); - expect(result).toEqual('9223372036854775808'); - - result = convert(toHashString(0x00000000, 0x80000000), true); - expect(result).toEqual('-9223372036854775808'); - - result = convert(toHashString(0xacd05f15, 0x01b69b4b), false); - expect(result).toEqual('123456789123456789'); - - result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true); - expect(result).toEqual('-123456789123456789'); - - // And converting arrays of hashes should work the same way. - result = jspb.utils.hash64ArrayToDecimalStrings([ - toHashString(0xFFFFFFFF, 0xFFFFFFFF), - toHashString(0x00000000, 0x80000000), - toHashString(0xacd05f15, 0x01b69b4b)], false); - expect(result.length).toEqual(3); - expect(result[0]).toEqual('18446744073709551615'); - expect(result[1]).toEqual('9223372036854775808'); - expect(result[2]).toEqual('123456789123456789'); - }); - - /* - * Going from decimal strings to hash strings should be lossless. - */ - it('testDecimalToHashConversion', function() { - var result; - var convert = jspb.utils.decimalStringToHash64; - - result = convert('0'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); - - result = convert('-1'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])); - - result = convert('18446744073709551615'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])); - - result = convert('9223372036854775808'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80])); - - result = convert('-9223372036854775808'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80])); - - result = convert('123456789123456789'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01])); - - result = convert('-123456789123456789'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE])); - }); - - /** - * Going from hash strings to hex strings should be lossless. - */ - it('testHashToHexConversion', function() { - var result; - var convert = jspb.utils.hash64ToHexString; - - result = convert(toHashString(0x00000000, 0x00000000)); - expect(result).toEqual('0x0000000000000000'); - - result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF)); - expect(result).toEqual('0xffffffffffffffff'); - - result = convert(toHashString(0x12345678, 0x9ABCDEF0)); - expect(result).toEqual('0x9abcdef012345678'); - }); - - - /** - * Going from hex strings to hash strings should be lossless. - */ - it('testHexToHashConversion', function() { - var result; - var convert = jspb.utils.hexStringToHash64; - - result = convert('0x0000000000000000'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); - - result = convert('0xffffffffffffffff'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])); - - // Hex string is big-endian, hash string is little-endian. - result = convert('0x123456789ABCDEF0'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12])); - - // Capitalization should not matter. - result = convert('0x0000abcdefABCDEF'); - expect(result).toEqual(goog.crypt.byteArrayToString( - [0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00])); - }); - - - /** - * Going from numbers to hash strings should be lossless for up to 53 bits of - * precision. - */ - it('testNumberToHashConversion', function() { - var result; - var convert = jspb.utils.numberToHash64; - - result = convert(0x0000000000000); - expect(jspb.utils.hash64ToHexString(result)).toEqual('0x0000000000000000'); - - result = convert(0xFFFFFFFFFFFFF); - expect(jspb.utils.hash64ToHexString(result)).toEqual('0x000fffffffffffff'); - - result = convert(0x123456789ABCD); - expect(jspb.utils.hash64ToHexString(result)).toEqual('0x000123456789abcd'); - - result = convert(0xDCBA987654321); - expect(jspb.utils.hash64ToHexString(result)).toEqual('0x000dcba987654321'); - - // 53 bits of precision should not be truncated. - result = convert(0x10000000000001); - expect(jspb.utils.hash64ToHexString(result)).toEqual('0x0010000000000001'); - - // 54 bits of precision should be truncated. - result = convert(0x20000000000001); - expect(jspb.utils.hash64ToHexString(result)) - .not.toEqual('0x0020000000000001'); - }); - - - /** - * Sanity check the behavior of Javascript's strings when doing funny things - * with unicode characters. - */ - it('sanityCheckUnicodeStrings', function() { - var strings = new Array(65536); - - // All possible unsigned 16-bit values should be storable in a string, they - // shouldn't do weird things with the length of the string, and they should - // come back out of the string unchanged. - for (var i = 0; i < 65536; i++) { - strings[i] = 'a' + String.fromCharCode(i) + 'a'; - expect(strings[i].length).toEqual(3); - expect(strings[i].charCodeAt(1)).toEqual(i); - } - - // Each unicode character should compare equal to itself and not equal to a - // different unicode character. - for (var i = 0; i < 65536; i++) { - expect(strings[i] == strings[i]).toEqual(true); - expect(strings[i] == strings[(i + 1) % 65536]).toEqual(false); - } - }); - - - /** - * Tests conversion from 32-bit floating point numbers to split64 numbers. - */ - it('testFloat32ToSplit64', function() { - var f32_eps = jspb.BinaryConstants.FLOAT32_EPS; - var f32_min = jspb.BinaryConstants.FLOAT32_MIN; - var f32_max = jspb.BinaryConstants.FLOAT32_MAX; - var f32_max_safe_int = jspb.utils.joinFloat32(0x4b7fffff, 0); - var f32_pi = Math.fround(Math.PI); - - // NaN. - jspb.utils.splitFloat32(NaN); - expect(isNaN(jspb.utils.joinFloat32( - jspb.utils.split64Low, jspb.utils.split64High))) - .toEqual(true); - - /** - * @param {number} x - * @param {number=} opt_bits - */ - function test(x, opt_bits) { - jspb.utils.splitFloat32(x); - if (opt_bits !== undefined) { - if (opt_bits != jspb.utils.split64Low) throw 'fail!'; - } - expect(truncate(x)) - .toEqual(jspb.utils.joinFloat32( - jspb.utils.split64Low, jspb.utils.split64High)); - } - - // Positive and negative infinity. - test(Infinity, 0x7f800000); - test(-Infinity, 0xff800000); - - // Positive and negative zero. - test(0, 0x00000000); - test(-0, 0x80000000); - - // Positive and negative epsilon. - test(f32_eps, 0x00000001); - test(-f32_eps, 0x80000001); - - // Positive and negative min. - test(f32_min, 0x00800000); - test(-f32_min, 0x80800000); - - // Positive and negative max. - test(f32_max, 0x7F7FFFFF); - test(-f32_max, 0xFF7FFFFF); - - // Positive and negative max_safe_int. - test(f32_max_safe_int, 0x4B7FFFFF); - test(-f32_max_safe_int, 0xCB7FFFFF); - - // Pi. - test(f32_pi, 0x40490fdb); - - // corner cases - test(0.9999999762949594, 0x3f800000); - test(7.99999999999999, 0x41000000); - test(Math.sin(30 * Math.PI / 180), 0x3f000000); // sin(30 degrees) - - // Various positive values. - var cursor = f32_eps * 10; - while (cursor != Infinity) { - test(cursor); - cursor *= 1.1; - } - - // Various negative values. - cursor = -f32_eps * 10; - while (cursor != -Infinity) { - test(cursor); - cursor *= 1.1; - } - }); - - - /** - * Tests conversion from 64-bit floating point numbers to split64 numbers. - */ - it('testFloat64ToSplit64', function() { - var f64_eps = jspb.BinaryConstants.FLOAT64_EPS; - var f64_min = jspb.BinaryConstants.FLOAT64_MIN; - var f64_max = jspb.BinaryConstants.FLOAT64_MAX; - - // NaN. - jspb.utils.splitFloat64(NaN); - expect(isNaN(jspb.utils.joinFloat64( - jspb.utils.split64Low, jspb.utils.split64High))) - .toEqual(true); - - /** - * @param {number} x - * @param {number=} opt_highBits - * @param {number=} opt_lowBits - */ - function test(x, opt_highBits, opt_lowBits) { - jspb.utils.splitFloat64(x); - if (opt_highBits !== undefined) { - var split64High = jspb.utils.split64High; - expect(opt_highBits.toString(16)).toEqual(split64High.toString(16)); - } - if (opt_lowBits !== undefined) { - var split64Low = jspb.utils.split64Low; - expect(opt_lowBits.toString(16)).toEqual(split64Low.toString(16)); - } - expect( - jspb.utils.joinFloat64(jspb.utils.split64Low, jspb.utils.split64High)) - .toEqual(x); - } - - // Positive and negative infinity. - test(Infinity, 0x7ff00000, 0x00000000); - test(-Infinity, 0xfff00000, 0x00000000); - - // Positive and negative zero. - test(0, 0x00000000, 0x00000000); - test(-0, 0x80000000, 0x00000000); - - test(1, 0x3FF00000, 0x00000000); - test(2, 0x40000000, 0x00000000); - - // Positive and negative epsilon. - test(f64_eps, 0x00000000, 0x00000001); - test(-f64_eps, 0x80000000, 0x00000001); - - // Positive and negative min. - test(f64_min, 0x00100000, 0x00000000); - test(-f64_min, 0x80100000, 0x00000000); - - // Positive and negative max. - test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF); - test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF); - - test(Number.MAX_SAFE_INTEGER, 0x433FFFFF, 0xFFFFFFFF); - test(Number.MIN_SAFE_INTEGER, 0xC33FFFFF, 0xFFFFFFFF); - - // Test various edge cases with mantissa of all 1, all 0, or just the - // highest or lowest significant bit. - test(4503599627370497, 0x43300000, 0x00000001); - test(6755399441055744, 0x43380000, 0x00000000); - test(1.348269851146737e+308, 0x7FE80000, 0x00000000); - test(1.9999999999999998, 0x3FFFFFFF, 0xFFFFFFFF); - test(2.225073858507201e-308, 0x000FFFFF, 0xFFFFFFFF); - test(Math.PI, 0x400921fb, 0x54442d18); - test(jspb.BinaryConstants.FLOAT32_MIN, 0x38100000, 0x00000000); - - // Various positive values. - var cursor = f64_eps * 10; - while (cursor != Infinity) { - test(cursor); - cursor *= 1.1; - } - - // Various negative values. - cursor = -f64_eps * 10; - while (cursor != -Infinity) { - test(cursor); - cursor *= 1.1; - } - }); - - /** - * Tests zigzag conversions. - */ - it('can encode and decode zigzag 64', function() { - function stringToHiLoPair(str) { - jspb.utils.splitDecimalString(str); - return { - lo: jspb.utils.split64Low >>> 0, - hi: jspb.utils.split64High >>> 0 - }; - } - function makeHiLoPair(lo, hi) { - return {lo: lo >>> 0, hi: hi >>> 0}; - } - // Test cases directly from the protobuf dev guide. - // https://engdoc.corp.google.com/eng/howto/protocolbuffers/developerguide/encoding.shtml?cl=head#types - var testCases = [ - {original: stringToHiLoPair('0'), zigzag: stringToHiLoPair('0')}, - {original: stringToHiLoPair('-1'), zigzag: stringToHiLoPair('1')}, - {original: stringToHiLoPair('1'), zigzag: stringToHiLoPair('2')}, - {original: stringToHiLoPair('-2'), zigzag: stringToHiLoPair('3')}, - { - original: stringToHiLoPair('2147483647'), - zigzag: stringToHiLoPair('4294967294') - }, - { - original: stringToHiLoPair('-2147483648'), - zigzag: stringToHiLoPair('4294967295') - }, - // 64-bit extremes - { - original: stringToHiLoPair('9223372036854775807'), - zigzag: stringToHiLoPair('18446744073709551614') - }, - { - original: stringToHiLoPair('-9223372036854775808'), - zigzag: stringToHiLoPair('18446744073709551615') - }, - ]; - for (const c of testCases) { - expect(jspb.utils.toZigzag64(c.original.lo, c.original.hi, makeHiLoPair)) - .toEqual(c.zigzag); - expect(jspb.utils.fromZigzag64(c.zigzag.lo, c.zigzag.hi, makeHiLoPair)) - .toEqual(c.original); - } - }); - - - /** - * Tests counting packed varints. - */ - it('testCountVarints', function() { - var values = []; - for (var i = 1; i < 1000000000; i *= 1.1) { - values.push(Math.floor(i)); - } - - var writer = new jspb.BinaryWriter(); - writer.writePackedUint64(1, values); - - var buffer = new Uint8Array(writer.getResultBuffer()); - - // We should have two more varints than we started with - one for the field - // tag, one for the packed length. - expect(jspb.utils.countVarints(buffer, 0, buffer.length)) - .toEqual(values.length + 2); - }); - - - /** - * Tests counting matching varint fields. - */ - it('testCountVarintFields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeUint64(1, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - expect(jspb.utils.countVarintFields(buffer, 0, buffer.length, 1)) - .toEqual(count); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeUint64(123456789, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - expect(jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789)) - .toEqual(count); - }); - - - /** - * Tests counting matching fixed32 fields. - */ - it('testCountFixed32Fields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeFixed32(1, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - expect(jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1)) - .toEqual(count); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeFixed32(123456789, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - expect(jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789)) - .toEqual(count); - }); - - - /** - * Tests counting matching fixed64 fields. - */ - it('testCountFixed64Fields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeDouble(1, i); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - expect(jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1)) - .toEqual(count); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeDouble(123456789, i); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - expect(jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789)) - .toEqual(count); - }); - - - /** - * Tests counting matching delimited fields. - */ - it('testCountDelimitedFields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000; i *= 1.1) { - writer.writeBytes(1, [Math.floor(i)]); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - expect(jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1)) - .toEqual(count); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000; i *= 1.1) { - writer.writeBytes(123456789, [Math.floor(i)]); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - expect(jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789)) - .toEqual(count); - }); - - - /** - * Tests byte format for debug strings. - */ - it('testDebugBytesToTextFormat', function() { - expect(jspb.utils.debugBytesToTextFormat(null)).toEqual('""'); - expect(jspb.utils.debugBytesToTextFormat([ - 0, 16, 255 - ])).toEqual('"\\x00\\x10\\xff"'); - }); - - - /** - * Tests converting byte blob sources into byte blobs. - */ - it('testByteSourceToUint8Array', function() { - var convert = jspb.utils.byteSourceToUint8Array; - - var sourceData = []; - for (var i = 0; i < 256; i++) { - sourceData.push(i); - } - - var sourceBytes = new Uint8Array(sourceData); - var sourceBuffer = sourceBytes.buffer; - var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData); - var sourceString = goog.crypt.byteArrayToString(sourceData); - - function check(result) { - expect(result.constructor).toEqual(Uint8Array); - expect(result.length).toEqual(sourceData.length); - for (var i = 0; i < result.length; i++) { - expect(result[i]).toEqual(sourceData[i]); - } - } - - // Converting Uint8Arrays into Uint8Arrays should be a no-op. - expect(convert(sourceBytes)).toEqual(sourceBytes); - - // Converting Array into Uint8Arrays should work. - check(convert(sourceData)); - - // Converting ArrayBuffers into Uint8Arrays should work. - check(convert(sourceBuffer)); - - // Converting base64-encoded strings into Uint8Arrays should work. - check(convert(sourceBase64)); - }); -}); diff --git a/js/binary/writer.js b/js/binary/writer.js deleted file mode 100644 index 1e2beee3e..000000000 --- a/js/binary/writer.js +++ /dev/null @@ -1,1833 +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. - -/** - * @fileoverview This file contains utilities for encoding Javascript objects - * into binary, wire-format protocol buffers (in the form of Uint8Arrays) that - * a server can consume directly. - * - * jspb's BinaryWriter class defines methods for efficiently encoding - * Javascript objects into binary, wire-format protocol buffers and supports - * all the fundamental field types used in protocol buffers. - * - * Major caveat 1 - Users of this library _must_ keep their Javascript proto - * parsing code in sync with the original .proto file - presumably you'll be - * using the typed jspb code generator, but if you bypass that you'll need - * to keep things in sync by hand. - * - * Major caveat 2 - Javascript is unable to accurately represent integers - * larger than 2^53 due to its use of a double-precision floating point format - * for all numbers. BinaryWriter does not make any special effort to preserve - * precision for values above this limit - if you need to pass 64-bit integers - * (hash codes, for example) between the client and server without precision - * loss, do _not_ use this library. - * - * Major caveat 3 - This class uses typed arrays and must not be used on older - * browsers that do not support them. - * - * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed - * @author aappleby@google.com (Austin Appleby) - */ - -goog.provide('jspb.BinaryWriter'); - -goog.require('goog.asserts'); -goog.require('goog.crypt.base64'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryEncoder'); -goog.require('jspb.arith.Int64'); -goog.require('jspb.arith.UInt64'); -goog.require('jspb.utils'); - - - -/** - * BinaryWriter implements encoders for all the wire types specified in - * https://developers.google.com/protocol-buffers/docs/encoding. - * - * @constructor - * @struct - */ -jspb.BinaryWriter = function() { - /** - * Blocks of serialized data that will be concatenated once all messages have - * been written. - * @private {!Array>} - */ - this.blocks_ = []; - - /** - * Total number of bytes in the blocks_ array. Does _not_ include bytes in - * the encoder below. - * @private {number} - */ - this.totalLength_ = 0; - - /** - * Binary encoder holding pieces of a message that we're still serializing. - * When we get to a stopping point (either the start of a new submessage, or - * when we need to append a raw Uint8Array), the encoder's buffer will be - * added to the block array above and the encoder will be reset. - * @private {!jspb.BinaryEncoder} - */ - this.encoder_ = new jspb.BinaryEncoder(); - - /** - * A stack of bookmarks containing the parent blocks for each message started - * via beginSubMessage(), needed as bookkeeping for endSubMessage(). - * TODO(aappleby): Deprecated, users should be calling writeMessage(). - * @private {!Array>} - */ - this.bookmarks_ = []; -}; - - -/** - * Append a typed array of bytes onto the buffer. - * - * @param {!Uint8Array} arr The byte array to append. - * @private - */ -jspb.BinaryWriter.prototype.appendUint8Array_ = function(arr) { - var temp = this.encoder_.end(); - this.blocks_.push(temp); - this.blocks_.push(arr); - this.totalLength_ += temp.length + arr.length; -}; - - -/** - * Begins a new message by writing the field header and returning a bookmark - * which we will use to patch in the message length to in endDelimited_ below. - * @param {number} field - * @return {!Array} - * @private - */ -jspb.BinaryWriter.prototype.beginDelimited_ = function(field) { - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - var bookmark = this.encoder_.end(); - this.blocks_.push(bookmark); - this.totalLength_ += bookmark.length; - bookmark.push(this.totalLength_); - return bookmark; -}; - - -/** - * Ends a message by encoding the _change_ in length of the buffer to the - * parent block and adds the number of bytes needed to encode that length to - * the total byte length. - * @param {!Array} bookmark - * @private - */ -jspb.BinaryWriter.prototype.endDelimited_ = function(bookmark) { - var oldLength = bookmark.pop(); - var messageLength = this.totalLength_ + this.encoder_.length() - oldLength; - goog.asserts.assert(messageLength >= 0); - - while (messageLength > 127) { - bookmark.push((messageLength & 0x7f) | 0x80); - messageLength = messageLength >>> 7; - this.totalLength_++; - } - - bookmark.push(messageLength); - this.totalLength_++; -}; - - -/** - * Writes a pre-serialized message to the buffer. - * @param {!Uint8Array} bytes The array of bytes to write. - * @param {number} start The start of the range to write. - * @param {number} end The end of the range to write. - */ -jspb.BinaryWriter.prototype.writeSerializedMessage = function( - bytes, start, end) { - this.appendUint8Array_(bytes.subarray(start, end)); -}; - - -/** - * Writes a pre-serialized message to the buffer if the message and endpoints - * are non-null. - * @param {?Uint8Array} bytes The array of bytes to write. - * @param {?number} start The start of the range to write. - * @param {?number} end The end of the range to write. - */ -jspb.BinaryWriter.prototype.maybeWriteSerializedMessage = function( - bytes, start, end) { - if (bytes != null && start != null && end != null) { - this.writeSerializedMessage(bytes, start, end); - } -}; - - -/** - * Resets the writer, throwing away any accumulated buffers. - */ -jspb.BinaryWriter.prototype.reset = function() { - this.blocks_ = []; - this.encoder_.end(); - this.totalLength_ = 0; - this.bookmarks_ = []; -}; - - -/** - * Converts the encoded data into a Uint8Array. - * @return {!Uint8Array} - */ -jspb.BinaryWriter.prototype.getResultBuffer = function() { - goog.asserts.assert(this.bookmarks_.length == 0); - - var flat = new Uint8Array(this.totalLength_ + this.encoder_.length()); - - var blocks = this.blocks_; - var blockCount = blocks.length; - var offset = 0; - - for (var i = 0; i < blockCount; i++) { - var block = blocks[i]; - flat.set(block, offset); - offset += block.length; - } - - var tail = this.encoder_.end(); - flat.set(tail, offset); - offset += tail.length; - - // Post condition: `flattened` must have had every byte written. - goog.asserts.assert(offset == flat.length); - - // Replace our block list with the flattened block, which lets GC reclaim - // the temp blocks sooner. - this.blocks_ = [flat]; - - return flat; -}; - - -/** - * Converts the encoded data into a base64-encoded string. - * @param {!goog.crypt.base64.Alphabet=} alphabet Which flavor of base64 to use. - * @return {string} - */ -jspb.BinaryWriter.prototype.getResultBase64String = function(alphabet) { - return goog.crypt.base64.encodeByteArray(this.getResultBuffer(), alphabet); -}; - - -/** - * Begins a new sub-message. The client must call endSubMessage() when they're - * done. - * TODO(aappleby): Deprecated. Move callers to writeMessage(). - * @param {number} field The field number of the sub-message. - */ -jspb.BinaryWriter.prototype.beginSubMessage = function(field) { - this.bookmarks_.push(this.beginDelimited_(field)); -}; - - -/** - * Finishes a sub-message and packs it into the parent messages' buffer. - * TODO(aappleby): Deprecated. Move callers to writeMessage(). - */ -jspb.BinaryWriter.prototype.endSubMessage = function() { - goog.asserts.assert(this.bookmarks_.length >= 0); - this.endDelimited_(this.bookmarks_.pop()); -}; - - -/** - * Encodes a (field number, wire type) tuple into a wire-format field header - * and stores it in the buffer as a varint. - * @param {number} field The field number. - * @param {number} wireType The wire-type of the field, as specified in the - * protocol buffer documentation. - * @private - */ -jspb.BinaryWriter.prototype.writeFieldHeader_ = - function(field, wireType) { - goog.asserts.assert(field >= 1 && field == Math.floor(field)); - var x = field * 8 + wireType; - this.encoder_.writeUnsignedVarint32(x); -}; - - -/** - * Writes a field of any valid scalar type to the binary stream. - * @param {jspb.BinaryConstants.FieldType} fieldType - * @param {number} field - * @param {jspb.AnyFieldType} value - */ -jspb.BinaryWriter.prototype.writeAny = function(fieldType, field, value) { - var fieldTypes = jspb.BinaryConstants.FieldType; - switch (fieldType) { - case fieldTypes.DOUBLE: - this.writeDouble(field, /** @type {number} */(value)); - return; - case fieldTypes.FLOAT: - this.writeFloat(field, /** @type {number} */(value)); - return; - case fieldTypes.INT64: - this.writeInt64(field, /** @type {number} */(value)); - return; - case fieldTypes.UINT64: - this.writeUint64(field, /** @type {number} */(value)); - return; - case fieldTypes.INT32: - this.writeInt32(field, /** @type {number} */(value)); - return; - case fieldTypes.FIXED64: - this.writeFixed64(field, /** @type {number} */(value)); - return; - case fieldTypes.FIXED32: - this.writeFixed32(field, /** @type {number} */(value)); - return; - case fieldTypes.BOOL: - this.writeBool(field, /** @type {boolean} */(value)); - return; - case fieldTypes.STRING: - this.writeString(field, /** @type {string} */(value)); - return; - case fieldTypes.GROUP: - goog.asserts.fail('Group field type not supported in writeAny()'); - return; - case fieldTypes.MESSAGE: - goog.asserts.fail('Message field type not supported in writeAny()'); - return; - case fieldTypes.BYTES: - this.writeBytes(field, /** @type {?Uint8Array} */(value)); - return; - case fieldTypes.UINT32: - this.writeUint32(field, /** @type {number} */(value)); - return; - case fieldTypes.ENUM: - this.writeEnum(field, /** @type {number} */(value)); - return; - case fieldTypes.SFIXED32: - this.writeSfixed32(field, /** @type {number} */(value)); - return; - case fieldTypes.SFIXED64: - this.writeSfixed64(field, /** @type {number} */(value)); - return; - case fieldTypes.SINT32: - this.writeSint32(field, /** @type {number} */(value)); - return; - case fieldTypes.SINT64: - this.writeSint64(field, /** @type {number} */(value)); - return; - case fieldTypes.FHASH64: - this.writeFixedHash64(field, /** @type {string} */(value)); - return; - case fieldTypes.VHASH64: - this.writeVarintHash64(field, /** @type {string} */(value)); - return; - default: - goog.asserts.fail('Invalid field type in writeAny()'); - return; - } -}; - - -/** - * Writes a varint field to the buffer without range checking. - * @param {number} field The field number. - * @param {number?} value The value to write. - * @private - */ -jspb.BinaryWriter.prototype.writeUnsignedVarint32_ = function(field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeUnsignedVarint32(value); -}; - - -/** - * Writes a varint field to the buffer without range checking. - * @param {number} field The field number. - * @param {number?} value The value to write. - * @private - */ -jspb.BinaryWriter.prototype.writeSignedVarint32_ = function(field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeSignedVarint32(value); -}; - - -/** - * Writes a varint field to the buffer without range checking. - * @param {number} field The field number. - * @param {number?} value The value to write. - * @private - */ -jspb.BinaryWriter.prototype.writeUnsignedVarint64_ = function(field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeUnsignedVarint64(value); -}; - - -/** - * Writes a varint field to the buffer without range checking. - * @param {number} field The field number. - * @param {number?} value The value to write. - * @private - */ -jspb.BinaryWriter.prototype.writeSignedVarint64_ = function(field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeSignedVarint64(value); -}; - - -/** - * Writes a zigzag varint field to the buffer without range checking. - * @param {number} field The field number. - * @param {number?} value The value to write. - * @private - */ -jspb.BinaryWriter.prototype.writeZigzagVarint32_ = function(field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeZigzagVarint32(value); -}; - - -/** - * Writes a zigzag varint field to the buffer without range checking. - * @param {number} field The field number. - * @param {number?} value The value to write. - * @private - */ -jspb.BinaryWriter.prototype.writeZigzagVarint64_ = function(field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeZigzagVarint64(value); -}; - - -/** - * Writes a zigzag varint field to the buffer without range checking. - * @param {number} field The field number. - * @param {string?} value The value to write. - * @private - */ -jspb.BinaryWriter.prototype.writeZigzagVarint64String_ = function( - field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeZigzagVarint64String(value); -}; - - -/** - * Writes a zigzag varint field to the buffer without range checking. - * @param {number} field The field number. - * @param {string?} value The value to write. - * @private - */ -jspb.BinaryWriter.prototype.writeZigzagVarintHash64_ = function(field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeZigzagVarintHash64(value); -}; - - -/** - * Writes an int32 field to the buffer. Numbers outside the range [-2^31,2^31) - * will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeInt32 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && - (value < jspb.BinaryConstants.TWO_TO_31)); - this.writeSignedVarint32_(field, value); -}; - - -/** - * Writes an int32 field represented as a string to the buffer. Numbers outside - * the range [-2^31,2^31) will be truncated. - * @param {number} field The field number. - * @param {string?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeInt32String = function(field, value) { - if (value == null) return; - var intValue = /** {number} */ parseInt(value, 10); - goog.asserts.assert((intValue >= -jspb.BinaryConstants.TWO_TO_31) && - (intValue < jspb.BinaryConstants.TWO_TO_31)); - this.writeSignedVarint32_(field, intValue); -}; - - -/** - * Writes an int64 field to the buffer. Numbers outside the range [-2^63,2^63) - * will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeInt64 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && - (value < jspb.BinaryConstants.TWO_TO_63)); - this.writeSignedVarint64_(field, value); -}; - - -/** - * Writes a int64 field (with value as a string) to the buffer. - * @param {number} field The field number. - * @param {string?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeInt64String = function(field, value) { - if (value == null) return; - var num = jspb.arith.Int64.fromString(value); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeSplitVarint64(num.lo, num.hi); -}; - - -/** - * Writes a uint32 field to the buffer. Numbers outside the range [0,2^32) - * will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeUint32 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= 0) && - (value < jspb.BinaryConstants.TWO_TO_32)); - this.writeUnsignedVarint32_(field, value); -}; - - -/** - * Writes a uint32 field represented as a string to the buffer. Numbers outside - * the range [0,2^32) will be truncated. - * @param {number} field The field number. - * @param {string?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeUint32String = function(field, value) { - if (value == null) return; - var intValue = /** {number} */ parseInt(value, 10); - goog.asserts.assert((intValue >= 0) && - (intValue < jspb.BinaryConstants.TWO_TO_32)); - this.writeUnsignedVarint32_(field, intValue); -}; - - -/** - * Writes a uint64 field to the buffer. Numbers outside the range [0,2^64) - * will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeUint64 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= 0) && - (value < jspb.BinaryConstants.TWO_TO_64)); - this.writeUnsignedVarint64_(field, value); -}; - - -/** - * Writes a uint64 field (with value as a string) to the buffer. - * @param {number} field The field number. - * @param {string?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeUint64String = function(field, value) { - if (value == null) return; - var num = jspb.arith.UInt64.fromString(value); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeSplitVarint64(num.lo, num.hi); -}; - - -/** - * Writes an sint32 field to the buffer. Numbers outside the range [-2^31,2^31) - * will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeSint32 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && - (value < jspb.BinaryConstants.TWO_TO_31)); - this.writeZigzagVarint32_(field, value); -}; - - -/** - * Writes an sint64 field to the buffer. Numbers outside the range [-2^63,2^63) - * will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeSint64 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && - (value < jspb.BinaryConstants.TWO_TO_63)); - this.writeZigzagVarint64_(field, value); -}; - - -/** - * Writes an sint64 field to the buffer from a hash64 encoded value. Numbers - * outside the range [-2^63,2^63) will be truncated. - * @param {number} field The field number. - * @param {string?} value The hash64 string to write. - */ -jspb.BinaryWriter.prototype.writeSintHash64 = function(field, value) { - if (value == null) return; - this.writeZigzagVarintHash64_(field, value); -}; - - -/** - * Writes an sint64 field to the buffer. Numbers outside the range [-2^63,2^63) - * will be truncated. - * @param {number} field The field number. - * @param {string?} value The decimal string to write. - */ -jspb.BinaryWriter.prototype.writeSint64String = function(field, value) { - if (value == null) return; - this.writeZigzagVarint64String_(field, value); -}; - - -/** - * Writes a fixed32 field to the buffer. Numbers outside the range [0,2^32) - * will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeFixed32 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= 0) && - (value < jspb.BinaryConstants.TWO_TO_32)); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32); - this.encoder_.writeUint32(value); -}; - - -/** - * Writes a fixed64 field to the buffer. Numbers outside the range [0,2^64) - * will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeFixed64 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= 0) && - (value < jspb.BinaryConstants.TWO_TO_64)); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); - this.encoder_.writeUint64(value); -}; - - -/** - * Writes a fixed64 field (with value as a string) to the buffer. - * @param {number} field The field number. - * @param {string?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeFixed64String = function(field, value) { - if (value == null) return; - var num = jspb.arith.UInt64.fromString(value); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); - this.encoder_.writeSplitFixed64(num.lo, num.hi); -}; - - -/** - * Writes a sfixed32 field to the buffer. Numbers outside the range - * [-2^31,2^31) will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeSfixed32 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && - (value < jspb.BinaryConstants.TWO_TO_31)); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32); - this.encoder_.writeInt32(value); -}; - - -/** - * Writes a sfixed64 field to the buffer. Numbers outside the range - * [-2^63,2^63) will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeSfixed64 = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && - (value < jspb.BinaryConstants.TWO_TO_63)); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); - this.encoder_.writeInt64(value); -}; - - -/** - * Writes a sfixed64 string field to the buffer. Numbers outside the range - * [-2^63,2^63) will be truncated. - * @param {number} field The field number. - * @param {string?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeSfixed64String = function(field, value) { - if (value == null) return; - var num = jspb.arith.Int64.fromString(value); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); - this.encoder_.writeSplitFixed64(num.lo, num.hi); -}; - - -/** - * Writes a single-precision floating point field to the buffer. Numbers - * requiring more than 32 bits of precision will be truncated. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeFloat = function(field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32); - this.encoder_.writeFloat(value); -}; - - -/** - * Writes a double-precision floating point field to the buffer. As this is the - * native format used by JavaScript, no precision will be lost. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeDouble = function(field, value) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); - this.encoder_.writeDouble(value); -}; - - -/** - * Writes a boolean field to the buffer. We allow numbers as input - * because the JSPB code generator uses 0/1 instead of true/false to save space - * in the string representation of the proto. - * @param {number} field The field number. - * @param {boolean?|number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeBool = function(field, value) { - if (value == null) return; - goog.asserts.assert(typeof value === 'boolean' || typeof value === 'number'); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeBool(value); -}; - - -/** - * Writes an enum field to the buffer. - * @param {number} field The field number. - * @param {number?} value The value to write. - */ -jspb.BinaryWriter.prototype.writeEnum = function(field, value) { - if (value == null) return; - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && - (value < jspb.BinaryConstants.TWO_TO_31)); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeSignedVarint32(value); -}; - - -/** - * Writes a string field to the buffer. - * @param {number} field The field number. - * @param {string?} value The string to write. - */ -jspb.BinaryWriter.prototype.writeString = function(field, value) { - if (value == null) return; - var bookmark = this.beginDelimited_(field); - this.encoder_.writeString(value); - this.endDelimited_(bookmark); -}; - - -/** - * Writes an arbitrary byte field to the buffer. Note - to match the behavior - * of the C++ implementation, empty byte arrays _are_ serialized. - * @param {number} field The field number. - * @param {?jspb.ByteSource} value The array of bytes to write. - */ -jspb.BinaryWriter.prototype.writeBytes = function(field, value) { - if (value == null) return; - var bytes = jspb.utils.byteSourceToUint8Array(value); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(bytes.length); - this.appendUint8Array_(bytes); -}; - - -/** - * Writes a message to the buffer. - * @param {number} field The field number. - * @param {?MessageType} value The message to write. - * @param {function(MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback - * Will be invoked with the value to write and the writer to write it with. - * @template MessageType - * Use go/closure-ttl to declare a non-nullable version of MessageType. Replace - * the null in blah|null with none. This is necessary because the compiler will - * infer MessageType to be nullable if the value parameter is nullable. - * @template MessageTypeNonNull := - * cond(isUnknown(MessageType), unknown(), - * mapunion(MessageType, (X) => - * cond(eq(X, 'null'), none(), X))) - * =: - */ -jspb.BinaryWriter.prototype.writeMessage = function( - field, value, writerCallback) { - if (value == null) return; - var bookmark = this.beginDelimited_(field); - writerCallback(value, this); - this.endDelimited_(bookmark); -}; - - -/** - * Writes a message set extension to the buffer. - * @param {number} field The field number for the extension. - * @param {?MessageType} value The extension message object to write. Note that - * message set can only have extensions with type of optional message. - * @param {function(!MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback - * Will be invoked with the value to write and the writer to write it with. - * @template MessageType - * Use go/closure-ttl to declare a non-nullable version of MessageType. Replace - * the null in blah|null with none. This is necessary because the compiler will - * infer MessageType to be nullable if the value parameter is nullable. - * @template MessageTypeNonNull := - * cond(isUnknown(MessageType), unknown(), - * mapunion(MessageType, (X) => - * cond(eq(X, 'null'), none(), X))) - * =: - */ -jspb.BinaryWriter.prototype.writeMessageSet = function( - field, value, writerCallback) { - if (value == null) return; - // The wire format for a message set is defined by - // google3/net/proto/message_set.proto - this.writeFieldHeader_(1, jspb.BinaryConstants.WireType.START_GROUP); - this.writeFieldHeader_(2, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeSignedVarint32(field); - var bookmark = this.beginDelimited_(3); - writerCallback(value, this); - this.endDelimited_(bookmark); - this.writeFieldHeader_(1, jspb.BinaryConstants.WireType.END_GROUP); -}; - - -/** - * Writes a group message to the buffer. - * - * @param {number} field The field number. - * @param {?MessageType} value The message to write, wrapped with START_GROUP / - * END_GROUP tags. Will be a no-op if 'value' is null. - * @param {function(MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback - * Will be invoked with the value to write and the writer to write it with. - * @template MessageType - * Use go/closure-ttl to declare a non-nullable version of MessageType. Replace - * the null in blah|null with none. This is necessary because the compiler will - * infer MessageType to be nullable if the value parameter is nullable. - * @template MessageTypeNonNull := - * cond(isUnknown(MessageType), unknown(), - * mapunion(MessageType, (X) => - * cond(eq(X, 'null'), none(), X))) - * =: - */ -jspb.BinaryWriter.prototype.writeGroup = function( - field, value, writerCallback) { - if (value == null) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP); - writerCallback(value, this); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP); -}; - - -/** - * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to - * the buffer. - * @param {number} field The field number. - * @param {string?} value The hash string. - */ -jspb.BinaryWriter.prototype.writeFixedHash64 = function(field, value) { - if (value == null) return; - goog.asserts.assert(value.length == 8); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); - this.encoder_.writeFixedHash64(value); -}; - - -/** - * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to - * the buffer. - * @param {number} field The field number. - * @param {string?} value The hash string. - */ -jspb.BinaryWriter.prototype.writeVarintHash64 = function(field, value) { - if (value == null) return; - goog.asserts.assert(value.length == 8); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeVarintHash64(value); -}; - - -/** - * Writes a 64-bit field to the buffer as a fixed64. - * @param {number} field The field number. - * @param {number} lowBits The low 32 bits. - * @param {number} highBits The high 32 bits. - */ -jspb.BinaryWriter.prototype.writeSplitFixed64 = function( - field, lowBits, highBits) { - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); - this.encoder_.writeSplitFixed64(lowBits, highBits); -}; - - -/** - * Writes a 64-bit field to the buffer as a varint. - * @param {number} field The field number. - * @param {number} lowBits The low 32 bits. - * @param {number} highBits The high 32 bits. - */ -jspb.BinaryWriter.prototype.writeSplitVarint64 = function( - field, lowBits, highBits) { - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - this.encoder_.writeSplitVarint64(lowBits, highBits); -}; - - -/** - * Writes a 64-bit field to the buffer as a zigzag encoded varint. - * @param {number} field The field number. - * @param {number} lowBits The low 32 bits. - * @param {number} highBits The high 32 bits. - */ -jspb.BinaryWriter.prototype.writeSplitZigzagVarint64 = function( - field, lowBits, highBits) { - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); - var encoder = this.encoder_; - jspb.utils.toZigzag64(lowBits, highBits, function(lowBits, highBits) { - encoder.writeSplitVarint64(lowBits >>> 0, highBits >>> 0); - }); -}; - - -/** - * Writes an array of numbers to the buffer as a repeated 32-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedInt32 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeSignedVarint32_(field, value[i]); - } -}; - - -/** - * Writes an array of numbers formatted as strings to the buffer as a repeated - * 32-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedInt32String = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeInt32String(field, value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a repeated 64-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedInt64 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeSignedVarint64_(field, value[i]); - } -}; - - -/** - * Writes an array of 64-bit values to the buffer as a fixed64. - * @param {number} field The field number. - * @param {?Array} value The value. - * @param {function(T): number} lo Function to get low bits. - * @param {function(T): number} hi Function to get high bits. - * @template T - */ -jspb.BinaryWriter.prototype.writeRepeatedSplitFixed64 = function( - field, value, lo, hi) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeSplitFixed64(field, lo(value[i]), hi(value[i])); - } -}; - - -/** - * Writes an array of 64-bit values to the buffer as a varint. - * @param {number} field The field number. - * @param {?Array} value The value. - * @param {function(T): number} lo Function to get low bits. - * @param {function(T): number} hi Function to get high bits. - * @template T - */ -jspb.BinaryWriter.prototype.writeRepeatedSplitVarint64 = function( - field, value, lo, hi) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeSplitVarint64(field, lo(value[i]), hi(value[i])); - } -}; - - -/** - * Writes an array of 64-bit values to the buffer as a zigzag varint. - * @param {number} field The field number. - * @param {?Array} value The value. - * @param {function(T): number} lo Function to get low bits. - * @param {function(T): number} hi Function to get high bits. - * @template T - */ -jspb.BinaryWriter.prototype.writeRepeatedSplitZigzagVarint64 = function( - field, value, lo, hi) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeSplitZigzagVarint64(field, lo(value[i]), hi(value[i])); - } -}; - - -/** - * Writes an array of numbers formatted as strings to the buffer as a repeated - * 64-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedInt64String = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeInt64String(field, value[i]); - } -}; - - -/** - * Writes an array numbers to the buffer as a repeated unsigned 32-bit int - * field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedUint32 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeUnsignedVarint32_(field, value[i]); - } -}; - - -/** - * Writes an array of numbers formatted as strings to the buffer as a repeated - * unsigned 32-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedUint32String = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeUint32String(field, value[i]); - } -}; - - -/** - * Writes an array numbers to the buffer as a repeated unsigned 64-bit int - * field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedUint64 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeUnsignedVarint64_(field, value[i]); - } -}; - - -/** - * Writes an array of numbers formatted as strings to the buffer as a repeated - * unsigned 64-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedUint64String = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeUint64String(field, value[i]); - } -}; - - -/** - * Writes an array numbers to the buffer as a repeated signed 32-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedSint32 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeZigzagVarint32_(field, value[i]); - } -}; - - -/** - * Writes an array numbers to the buffer as a repeated signed 64-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedSint64 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeZigzagVarint64_(field, value[i]); - } -}; - - -/** - * Writes an array numbers to the buffer as a repeated signed 64-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedSint64String = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeZigzagVarint64String_(field, value[i]); - } -}; - - -/** - * Writes an array of hash64 strings to the buffer as a repeated signed 64-bit - * int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedSintHash64 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeZigzagVarintHash64_(field, value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a repeated fixed32 field. This - * works for both signed and unsigned fixed32s. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedFixed32 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeFixed32(field, value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a repeated fixed64 field. This - * works for both signed and unsigned fixed64s. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedFixed64 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeFixed64(field, value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a repeated fixed64 field. This - * works for both signed and unsigned fixed64s. - * @param {number} field The field number. - * @param {?Array} value The array of decimal strings to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedFixed64String = function( - field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeFixed64String(field, value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a repeated sfixed32 field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedSfixed32 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeSfixed32(field, value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a repeated sfixed64 field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedSfixed64 = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeSfixed64(field, value[i]); - } -}; - - -/** - * Writes an array of decimal strings to the buffer as a repeated sfixed64 - * field. - * @param {number} field The field number. - * @param {?Array} value The array of decimal strings to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedSfixed64String = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeSfixed64String(field, value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a repeated float field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedFloat = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeFloat(field, value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a repeated double field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedDouble = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeDouble(field, value[i]); - } -}; - - -/** - * Writes an array of booleans to the buffer as a repeated bool field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedBool = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeBool(field, value[i]); - } -}; - - -/** - * Writes an array of enums to the buffer as a repeated enum field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedEnum = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeEnum(field, value[i]); - } -}; - - -/** - * Writes an array of strings to the buffer as a repeated string field. - * @param {number} field The field number. - * @param {?Array} value The array of strings to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedString = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeString(field, value[i]); - } -}; - - -/** - * Writes an array of arbitrary byte fields to the buffer. - * @param {number} field The field number. - * @param {?Array} value The arrays of arrays of bytes to - * write. - */ -jspb.BinaryWriter.prototype.writeRepeatedBytes = function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeBytes(field, value[i]); - } -}; - - -/** - * Writes an array of messages to the buffer. - * @template MessageType - * @param {number} field The field number. - * @param {?Array} value The array of messages to - * write. - * @param {function(MessageType, !jspb.BinaryWriter)} writerCallback - * Will be invoked with the value to write and the writer to write it with. - */ -jspb.BinaryWriter.prototype.writeRepeatedMessage = function( - field, value, writerCallback) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - var bookmark = this.beginDelimited_(field); - writerCallback(value[i], this); - this.endDelimited_(bookmark); - } -}; - - -/** - * Writes an array of group messages to the buffer. - * @template MessageType - * @param {number} field The field number. - * @param {?Array} value The array of messages to - * write. - * @param {function(MessageType, !jspb.BinaryWriter)} writerCallback - * Will be invoked with the value to write and the writer to write it with. - */ -jspb.BinaryWriter.prototype.writeRepeatedGroup = function( - field, value, writerCallback) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP); - writerCallback(value[i], this); - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP); - } -}; - - -/** - * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to - * the buffer. - * @param {number} field The field number. - * @param {?Array} value The array of hashes to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedFixedHash64 = - function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeFixedHash64(field, value[i]); - } -}; - - -/** - * Writes a repeated 64-bit hash string field (8 characters @ 8 bits of data - * each) to the buffer. - * @param {number} field The field number. - * @param {?Array} value The array of hashes to write. - */ -jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 = - function(field, value) { - if (value == null) return; - for (var i = 0; i < value.length; i++) { - this.writeVarintHash64(field, value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a packed 32-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedInt32 = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeSignedVarint32(value[i]); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of numbers represented as strings to the buffer as a packed - * 32-bit int field. - * @param {number} field - * @param {?Array} value - */ -jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeSignedVarint32(parseInt(value[i], 10)); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of numbers to the buffer as a packed 64-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedInt64 = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeSignedVarint64(value[i]); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of 64-bit values to the buffer as a fixed64. - * @param {number} field The field number. - * @param {?Array} value The value. - * @param {function(T): number} lo Function to get low bits. - * @param {function(T): number} hi Function to get high bits. - * @template T - */ -jspb.BinaryWriter.prototype.writePackedSplitFixed64 = function( - field, value, lo, hi) { - if (value == null) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeSplitFixed64(lo(value[i]), hi(value[i])); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of 64-bit values to the buffer as a varint. - * @param {number} field The field number. - * @param {?Array} value The value. - * @param {function(T): number} lo Function to get low bits. - * @param {function(T): number} hi Function to get high bits. - * @template T - */ -jspb.BinaryWriter.prototype.writePackedSplitVarint64 = function( - field, value, lo, hi) { - if (value == null) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeSplitVarint64(lo(value[i]), hi(value[i])); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of 64-bit values to the buffer as a zigzag varint. - * @param {number} field The field number. - * @param {?Array} value The value. - * @param {function(T): number} lo Function to get low bits. - * @param {function(T): number} hi Function to get high bits. - * @template T - */ -jspb.BinaryWriter.prototype.writePackedSplitZigzagVarint64 = function( - field, value, lo, hi) { - if (value == null) return; - var bookmark = this.beginDelimited_(field); - var encoder = this.encoder_; - for (var i = 0; i < value.length; i++) { - jspb.utils.toZigzag64( - lo(value[i]), hi(value[i]), function(bitsLow, bitsHigh) { - encoder.writeSplitVarint64(bitsLow >>> 0, bitsHigh >>> 0); - }); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of numbers represented as strings to the buffer as a packed - * 64-bit int field. - * @param {number} field - * @param {?Array} value - */ -jspb.BinaryWriter.prototype.writePackedInt64String = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - var num = jspb.arith.Int64.fromString(value[i]); - this.encoder_.writeSplitVarint64(num.lo, num.hi); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array numbers to the buffer as a packed unsigned 32-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedUint32 = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeUnsignedVarint32(value[i]); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of numbers represented as strings to the buffer as a packed - * unsigned 32-bit int field. - * @param {number} field - * @param {?Array} value - */ -jspb.BinaryWriter.prototype.writePackedUint32String = - function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeUnsignedVarint32(parseInt(value[i], 10)); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array numbers to the buffer as a packed unsigned 64-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedUint64 = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeUnsignedVarint64(value[i]); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of numbers represented as strings to the buffer as a packed - * unsigned 64-bit int field. - * @param {number} field - * @param {?Array} value - */ -jspb.BinaryWriter.prototype.writePackedUint64String = - function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - var num = jspb.arith.UInt64.fromString(value[i]); - this.encoder_.writeSplitVarint64(num.lo, num.hi); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array numbers to the buffer as a packed signed 32-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedSint32 = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeZigzagVarint32(value[i]); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of numbers to the buffer as a packed signed 64-bit int field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedSint64 = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeZigzagVarint64(value[i]); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of decimal strings to the buffer as a packed signed 64-bit - * int field. - * @param {number} field The field number. - * @param {?Array} value The array of decimal strings to write. - */ -jspb.BinaryWriter.prototype.writePackedSint64String = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeZigzagVarintHash64( - jspb.utils.decimalStringToHash64(value[i])); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of hash 64 strings to the buffer as a packed signed 64-bit - * int field. - * @param {number} field The field number. - * @param {?Array} value The array of decimal strings to write. - */ -jspb.BinaryWriter.prototype.writePackedSintHash64 = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeZigzagVarintHash64(value[i]); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes an array of numbers to the buffer as a packed fixed32 field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedFixed32 = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length * 4); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeUint32(value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a packed fixed64 field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedFixed64 = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length * 8); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeUint64(value[i]); - } -}; - - -/** - * Writes an array of numbers represented as strings to the buffer as a packed - * fixed64 field. - * @param {number} field The field number. - * @param {?Array} value The array of strings to write. - */ -jspb.BinaryWriter.prototype.writePackedFixed64String = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length * 8); - for (var i = 0; i < value.length; i++) { - var num = jspb.arith.UInt64.fromString(value[i]); - this.encoder_.writeSplitFixed64(num.lo, num.hi); - } -}; - - -/** - * Writes an array of numbers to the buffer as a packed sfixed32 field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedSfixed32 = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length * 4); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeInt32(value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a packed sfixed64 field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedSfixed64 = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length * 8); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeInt64(value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a packed sfixed64 field. - * @param {number} field The field number. - * @param {?Array} value The array of decimal strings to write. - */ -jspb.BinaryWriter.prototype.writePackedSfixed64String = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length * 8); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeInt64String(value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a packed float field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedFloat = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length * 4); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeFloat(value[i]); - } -}; - - -/** - * Writes an array of numbers to the buffer as a packed double field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedDouble = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length * 8); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeDouble(value[i]); - } -}; - - -/** - * Writes an array of booleans to the buffer as a packed bool field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedBool = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeBool(value[i]); - } -}; - - -/** - * Writes an array of enums to the buffer as a packed enum field. - * @param {number} field The field number. - * @param {?Array} value The array of ints to write. - */ -jspb.BinaryWriter.prototype.writePackedEnum = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeEnum(value[i]); - } - this.endDelimited_(bookmark); -}; - - -/** - * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to - * the buffer. - * @param {number} field The field number. - * @param {?Array} value The array of hashes to write. - */ -jspb.BinaryWriter.prototype.writePackedFixedHash64 = function(field, value) { - if (value == null || !value.length) return; - this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); - this.encoder_.writeUnsignedVarint32(value.length * 8); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeFixedHash64(value[i]); - } -}; - - -/** - * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to - * the buffer. - * @param {number} field The field number. - * @param {?Array} value The array of hashes to write. - */ -jspb.BinaryWriter.prototype.writePackedVarintHash64 = function(field, value) { - if (value == null || !value.length) return; - var bookmark = this.beginDelimited_(field); - for (var i = 0; i < value.length; i++) { - this.encoder_.writeVarintHash64(value[i]); - } - this.endDelimited_(bookmark); -}; diff --git a/js/binary/writer_test.js b/js/binary/writer_test.js deleted file mode 100644 index 543cff66c..000000000 --- a/js/binary/writer_test.js +++ /dev/null @@ -1,412 +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. - -/** - * @fileoverview Test cases for jspb's binary protocol buffer writer. In - * practice BinaryWriter is used to drive the Decoder and Reader test cases, - * so only writer-specific tests are here. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.crypt'); -goog.require('goog.testing.asserts'); -goog.require('jspb.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. - */ -function assertFails(func) { - assertThrows(func); -} - - -describe('binaryWriterTest', function() { - /** - * Verifies that misuse of the writer class triggers assertions. - */ - it('testWriteErrors', function() { - // Submessages with invalid field indices should assert. - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - - assertFails(function() { - writer.writeMessage(-1, dummyMessage, () => {}); - }); - - // Writing invalid field indices should assert. - writer = new jspb.BinaryWriter(); - assertFails(function() { - writer.writeUint64(-1, 1); - }); - - // Writing out-of-range field values should assert. - writer = new jspb.BinaryWriter(); - - assertFails(function() { - writer.writeInt32(1, -Infinity); - }); - assertFails(function() { - writer.writeInt32(1, Infinity); - }); - - assertFails(function() { - writer.writeInt64(1, -Infinity); - }); - assertFails(function() { - writer.writeInt64(1, Infinity); - }); - - assertFails(function() { - writer.writeUint32(1, -1); - }); - assertFails(function() { - writer.writeUint32(1, Infinity); - }); - - assertFails(function() { - writer.writeUint64(1, -1); - }); - assertFails(function() { - writer.writeUint64(1, Infinity); - }); - - assertFails(function() { - writer.writeSint32(1, -Infinity); - }); - assertFails(function() { - writer.writeSint32(1, Infinity); - }); - - assertFails(function() { - writer.writeSint64(1, -Infinity); - }); - assertFails(function() { - writer.writeSint64(1, Infinity); - }); - - assertFails(function() { - writer.writeFixed32(1, -1); - }); - assertFails(function() { - writer.writeFixed32(1, Infinity); - }); - - assertFails(function() { - writer.writeFixed64(1, -1); - }); - assertFails(function() { - writer.writeFixed64(1, Infinity); - }); - - assertFails(function() { - writer.writeSfixed32(1, -Infinity); - }); - assertFails(function() { - writer.writeSfixed32(1, Infinity); - }); - - assertFails(function() { - writer.writeSfixed64(1, -Infinity); - }); - assertFails(function() { - writer.writeSfixed64(1, Infinity); - }); - }); - - - /** - * Basic test of retrieving the result as a Uint8Array buffer - */ - it('testGetResultBuffer', function() { - var expected = '0864120b48656c6c6f20776f726c641a0301020320c801'; - - var writer = new jspb.BinaryWriter(); - writer.writeUint32(1, 100); - writer.writeString(2, 'Hello world'); - writer.writeBytes(3, new Uint8Array([1, 2, 3])); - writer.writeUint32(4, 200); - - var buffer = writer.getResultBuffer(); - assertEquals(expected, goog.crypt.byteArrayToHex(buffer)); - }); - - - /** - * Tests websafe encodings for base64 strings. - */ - it('testWebSafeOption', function() { - var writer = new jspb.BinaryWriter(); - writer.writeBytes(1, new Uint8Array([127])); - assertEquals('CgF/', writer.getResultBase64String()); - assertEquals( - 'CgF/', - writer.getResultBase64String(goog.crypt.base64.Alphabet.DEFAULT)); - assertEquals( - 'CgF_', - writer.getResultBase64String( - goog.crypt.base64.Alphabet.WEBSAFE_NO_PADDING)); - }); - - it('writes split 64 fields', function() { - var writer = new jspb.BinaryWriter(); - writer.writeSplitVarint64(1, 0x1, 0x2); - writer.writeSplitVarint64(1, 0xFFFFFFFF, 0xFFFFFFFF); - writer.writeSplitFixed64(2, 0x1, 0x2); - writer.writeSplitFixed64(2, 0xFFFFFFF0, 0xFFFFFFFF); - function lo(i) { - return i + 1; - } - function hi(i) { - return i + 2; - } - writer.writeRepeatedSplitVarint64(3, [0, 1, 2], lo, hi); - writer.writeRepeatedSplitFixed64(4, [0, 1, 2], lo, hi); - writer.writePackedSplitVarint64(5, [0, 1, 2], lo, hi); - writer.writePackedSplitFixed64(6, [0, 1, 2], lo, hi); - - function bitsAsArray(lowBits, highBits) { - return [lowBits >>> 0, highBits >>> 0]; - } - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(1); - expect(reader.readSplitVarint64(bitsAsArray)).toEqual([0x1, 0x2]); - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(1); - expect(reader.readSplitVarint64(bitsAsArray)).toEqual([ - 0xFFFFFFFF, 0xFFFFFFFF - ]); - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(2); - expect(reader.readSplitFixed64(bitsAsArray)).toEqual([0x1, 0x2]); - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(2); - expect(reader.readSplitFixed64(bitsAsArray)).toEqual([ - 0xFFFFFFF0, 0xFFFFFFFF - ]); - - for (let i = 0; i < 3; i++) { - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(3); - expect(reader.readSplitVarint64(bitsAsArray)).toEqual([i + 1, i + 2]); - } - - for (let i = 0; i < 3; i++) { - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(4); - expect(reader.readSplitFixed64(bitsAsArray)).toEqual([i + 1, i + 2]); - } - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(5); - expect(reader.readPackedInt64String()).toEqual([ - String(2 * 2 ** 32 + 1), - String(3 * 2 ** 32 + 2), - String(4 * 2 ** 32 + 3), - ]); - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(6); - expect(reader.readPackedFixed64String()).toEqual([ - String(2 * 2 ** 32 + 1), - String(3 * 2 ** 32 + 2), - String(4 * 2 ** 32 + 3), - ]); - }); - - it('writes zigzag 64 fields', function() { - // Test cases directly from the protobuf dev guide. - // https://engdoc.corp.google.com/eng/howto/protocolbuffers/developerguide/encoding.shtml?cl=head#types - var testCases = [ - {original: '0', zigzag: '0'}, - {original: '-1', zigzag: '1'}, - {original: '1', zigzag: '2'}, - {original: '-2', zigzag: '3'}, - {original: '2147483647', zigzag: '4294967294'}, - {original: '-2147483648', zigzag: '4294967295'}, - // 64-bit extremes, not in dev guide. - {original: '9223372036854775807', zigzag: '18446744073709551614'}, - {original: '-9223372036854775808', zigzag: '18446744073709551615'}, - ]; - function decimalToLowBits(v) { - jspb.utils.splitDecimalString(v); - return jspb.utils.split64Low >>> 0; - } - function decimalToHighBits(v) { - jspb.utils.splitDecimalString(v); - return jspb.utils.split64High >>> 0; - } - - var writer = new jspb.BinaryWriter(); - testCases.forEach(function(c) { - writer.writeSint64String(1, c.original); - writer.writeSintHash64(1, jspb.utils.decimalStringToHash64(c.original)); - jspb.utils.splitDecimalString(c.original); - writer.writeSplitZigzagVarint64( - 1, jspb.utils.split64Low, jspb.utils.split64High); - }); - - writer.writeRepeatedSint64String(2, testCases.map(function(c) { - return c.original; - })); - - writer.writeRepeatedSintHash64(3, testCases.map(function(c) { - return jspb.utils.decimalStringToHash64(c.original); - })); - - writer.writeRepeatedSplitZigzagVarint64( - 4, testCases.map(function(c) { - return c.original; - }), - decimalToLowBits, decimalToHighBits); - - writer.writePackedSint64String(5, testCases.map(function(c) { - return c.original; - })); - - writer.writePackedSintHash64(6, testCases.map(function(c) { - return jspb.utils.decimalStringToHash64(c.original); - })); - - writer.writePackedSplitZigzagVarint64( - 7, testCases.map(function(c) { - return c.original; - }), - decimalToLowBits, decimalToHighBits); - - // Verify by reading the stream as normal int64 fields and checking with - // the canonical zigzag encoding of each value. - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - testCases.forEach(function(c) { - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(1); - expect(reader.readUint64String()).toEqual(c.zigzag); - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(1); - expect(reader.readUint64String()).toEqual(c.zigzag); - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(1); - expect(reader.readUint64String()).toEqual(c.zigzag); - }); - - testCases.forEach(function(c) { - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(2); - expect(reader.readUint64String()).toEqual(c.zigzag); - }); - - testCases.forEach(function(c) { - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(3); - expect(reader.readUint64String()).toEqual(c.zigzag); - }); - - testCases.forEach(function(c) { - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(4); - expect(reader.readUint64String()).toEqual(c.zigzag); - }); - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(5); - expect(reader.readPackedUint64String()).toEqual(testCases.map(function(c) { - return c.zigzag; - })); - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(6); - expect(reader.readPackedUint64String()).toEqual(testCases.map(function(c) { - return c.zigzag; - })); - - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(7); - expect(reader.readPackedUint64String()).toEqual(testCases.map(function(c) { - return c.zigzag; - })); - }); - - it('writes float32 fields', function() { - var testCases = [ - 0, 1, -1, jspb.BinaryConstants.FLOAT32_MIN, - -jspb.BinaryConstants.FLOAT32_MIN, jspb.BinaryConstants.FLOAT32_MAX, - -jspb.BinaryConstants.FLOAT32_MAX, 3.1415927410125732, Infinity, - -Infinity, NaN - ]; - var writer = new jspb.BinaryWriter(); - testCases.forEach(function(f) { - writer.writeFloat(1, f); - }); - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - testCases.forEach(function(f) { - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(1); - if (isNaN(f)) { - expect(isNaN(reader.readFloat())).toEqual(true); - } else { - expect(reader.readFloat()).toEqual(f); - } - }); - }); - - it('writes double fields', function() { - var testCases = [ - 0, 1, -1, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER, - Number.MAX_VALUE, Number.MIN_VALUE, jspb.BinaryConstants.FLOAT32_MIN, - -jspb.BinaryConstants.FLOAT32_MIN, jspb.BinaryConstants.FLOAT32_MAX, - -jspb.BinaryConstants.FLOAT32_MAX, Math.PI, Infinity, -Infinity, NaN - ]; - var writer = new jspb.BinaryWriter(); - testCases.forEach(function(f) { - writer.writeDouble(1, f); - }); - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - testCases.forEach(function(f) { - reader.nextField(); - expect(reader.getFieldNumber()).toEqual(1); - if (isNaN(f)) { - expect(isNaN(reader.readDouble())).toEqual(true); - } else { - expect(reader.readDouble()).toEqual(f); - } - }); - }); -}); diff --git a/js/commonjs/export.js b/js/commonjs/export.js deleted file mode 100644 index 29a871359..000000000 --- a/js/commonjs/export.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @fileoverview Export symbols needed by generated code in CommonJS style. - * - * This effectively is our canonical list of what we publicly export from - * the google-protobuf.js file that we build at distribution time. - */ - -goog.provide('jspb.Export'); - -goog.require('goog.object'); -goog.require('jspb.BinaryReader'); -goog.require('jspb.BinaryWriter'); -goog.require('jspb.ExtensionFieldBinaryInfo'); -goog.require('jspb.ExtensionFieldInfo'); -goog.require('jspb.Message'); -goog.require('jspb.Map'); - -if (typeof exports === 'object') { - exports.Map = jspb.Map; - exports.Message = jspb.Message; - exports.BinaryReader = jspb.BinaryReader; - exports.BinaryWriter = jspb.BinaryWriter; - exports.ExtensionFieldInfo = jspb.ExtensionFieldInfo; - exports.ExtensionFieldBinaryInfo = jspb.ExtensionFieldBinaryInfo; - - // These are used by generated code but should not be used directly by - // clients. - exports.exportSymbol = goog.exportSymbol; - exports.inherits = goog.inherits; - exports.object = {extend: goog.object.extend}; - exports.typeOf = goog.typeOf; -} \ No newline at end of file diff --git a/js/commonjs/export_asserts.js b/js/commonjs/export_asserts.js deleted file mode 100644 index fa6e7958d..000000000 --- a/js/commonjs/export_asserts.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @fileoverview Exports symbols needed only by tests. - * - * This file exports several Closure Library symbols that are only - * used by tests. It is used to generate a file - * closure_asserts_commonjs.js that is only used at testing time. - */ - -goog.provide('jspb.ExportAsserts'); - -goog.require('goog.testing.asserts'); - -var global = Function('return this')(); - -// All of the closure "assert" functions are exported at the global level. -// -// The Google Closure assert functions start with assert, eg. -// assertThrows -// assertNotThrows -// assertTrue -// ... -// -// The one exception is the "fail" function. -function shouldExport(str) { - return str.lastIndexOf('assert') === 0 || str == 'fail'; -} - -for (var key in global) { - if ((typeof key == "string") && global.hasOwnProperty(key) && - shouldExport(key)) { - exports[key] = global[key]; - } -} - -// The COMPILED variable is set by Closure compiler to "true" when it compiles -// JavaScript, so in practice this is equivalent to "exports.COMPILED = true". -// This will disable some debugging functionality in debug.js. We could -// investigate whether this can/should be enabled in CommonJS builds. -exports.COMPILED = COMPILED diff --git a/js/commonjs/export_testdeps.js b/js/commonjs/export_testdeps.js deleted file mode 100644 index 51d868e14..000000000 --- a/js/commonjs/export_testdeps.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @fileoverview Export symbols needed by tests in CommonJS style. - * - * This file is like export.js, but for symbols that are only used by tests. - * However we exclude assert functions here, because they are exported into - * the global namespace, so those are handled as a special case in - * export_asserts.js. - */ - -goog.provide('jspb.ExportTestDeps'); - -goog.require('goog.crypt.base64'); -goog.require('goog.testing.PropertyReplacer'); -goog.require('jspb.arith.Int64'); -goog.require('jspb.arith.UInt64'); -goog.require('jspb.BinaryEncoder'); -goog.require('jspb.BinaryDecoder'); -goog.require('jspb.BinaryWriter'); -goog.require('jspb.utils'); - -exports.goog = goog; -exports.jspb = jspb; diff --git a/js/commonjs/import_test.js b/js/commonjs/import_test.js deleted file mode 100644 index ffa34fea6..000000000 --- a/js/commonjs/import_test.js +++ /dev/null @@ -1,52 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2016 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - - - -var googleProtobuf = require('google-protobuf'); -var asserts = require('closure_asserts_commonjs'); -var global = Function('return this')(); - -// Bring asserts into the global namespace. -googleProtobuf.object.extend(global, asserts); -googleProtobuf.exportSymbol('jspb.Message', googleProtobuf.Message, global); - -var test7_pb = require('./test7/test7_pb'); -googleProtobuf.exportSymbol('proto.jspb.test.framing.FramingMessage', test7_pb.FramingMessage, global); - -describe('Import test suite', function() { - it('testImportedMessage', function() { - var framing1 = new proto.jspb.test.framing.FramingMessage([]); - var framing2 = new proto.jspb.test.framing.FramingMessage([]); - assertObjectEquals(framing1.toObject(), framing2.toObject()); - }); -}); diff --git a/js/commonjs/jasmine.json b/js/commonjs/jasmine.json deleted file mode 100644 index 666b8edbf..000000000 --- a/js/commonjs/jasmine.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "spec_dir": "", - "spec_files": [ - "*_test.js", - "binary/proto_test.js" - ], - "helpers": [ - ] -} diff --git a/js/commonjs/rewrite_tests_for_commonjs.js b/js/commonjs/rewrite_tests_for_commonjs.js deleted file mode 100644 index 82eef18ed..000000000 --- a/js/commonjs/rewrite_tests_for_commonjs.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @fileoverview Utility to translate test files to CommonJS imports. - * - * This is a somewhat hacky tool designed to do one very specific thing. - * All of the test files in *_test.js are written with Closure-style - * imports (goog.require()). This works great for running the tests - * against Closure-style generated code, but we also want to run the - * tests against CommonJS-style generated code without having to fork - * the tests. - * - * Closure-style imports import each individual type by name. This is - * very different than CommonJS imports which are by file. So we put - * special comments in these tests like: - * - * // CommonJS-LoadFromFile: test_pb - * goog.require('proto.jspb.test.CloneExtension'); - * goog.require('proto.jspb.test.Complex'); - * goog.require('proto.jspb.test.DefaultValues'); - * - * This script parses that special comment and uses it to generate proper - * CommonJS require() statements so that the tests can run and pass using - * CommonJS imports. The script will change the above statements into: - * - * var test_pb = require('test_pb'); - * googleProtobuf.exportSymbol('proto.jspb.test.CloneExtension', test_pb.CloneExtension, global); - * googleProtobuf.exportSymbol('proto.jspb.test.Complex', test_pb.Complex, global); - * googleProtobuf.exportSymbol('proto.jspb.test.DefaultValues', test_pb.DefaultValues, global); - * - * (The "exportSymbol" function will define the given names in the global - * namespace, taking care not to overwrite any previous value for - * "proto.jspb.test"). - */ - -var lineReader = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}); - -function tryStripPrefix(str, prefix) { - if (str.lastIndexOf(prefix) !== 0) { - throw "String: " + str + " didn't start with: " + prefix; - } - return str.substr(prefix.length); -} - -function camelCase(str) { - var ret = ''; - var ucaseNext = false; - for (var i = 0; i < str.length; i++) { - if (str[i] == '-') { - ucaseNext = true; - } else if (ucaseNext) { - ret += str[i].toUpperCase(); - ucaseNext = false; - } else { - ret += str[i]; - } - } - return ret; -} - -var module = null; -var pkg = null; - -// Header: goes in every file at the top. -console.log("var global = Function('return this')();"); -console.log("var googleProtobuf = require('google-protobuf');"); -console.log("var testdeps = require('testdeps_commonjs');"); -console.log("global.goog = testdeps.goog;"); -console.log("global.jspb = testdeps.jspb;"); -console.log("var asserts = require('closure_asserts_commonjs');"); -console.log(""); -console.log("// Bring asserts into the global namespace."); -console.log("googleProtobuf.object.extend(global, asserts);"); - -lineReader.on('line', function(line) { - var isRequire = line.match(/goog\.require\('([^']*)'\)/); - var isLoadFromFile = line.match(/CommonJS-LoadFromFile: (\S*) (.*)/); - var isSetTestOnly = line.match(/goog.setTestOnly()/); - 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);'); - } - } else if (isLoadFromFile) { - var module_path = isLoadFromFile[1].split('/'); - module = camelCase(module_path[module_path.length - 1]); - pkg = isLoadFromFile[2]; - - if (module != "googleProtobuf") { // We unconditionally require this in the header. - console.log("var " + module + " = require('./" + isLoadFromFile[1] + "');"); - } - } else if (!isSetTestOnly) { // Remove goog.setTestOnly() lines. - console.log(line); - } -}); diff --git a/js/commonjs/strict_test.js b/js/commonjs/strict_test.js deleted file mode 100644 index 46458c10b..000000000 --- a/js/commonjs/strict_test.js +++ /dev/null @@ -1,67 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2016 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - - - -var googleProtobuf = require('google-protobuf'); -var asserts = require('closure_asserts_commonjs'); -var global = Function('return this')(); - -// Bring asserts into the global namespace. -googleProtobuf.object.extend(global, asserts); - -var test9_pb = require('./test9_pb'); -var test10_pb = require('./test10_pb'); - -describe('Strict test suite', function() { - it('testImportedMessage', function() { - var simple1 = new test9_pb.jspb.exttest.strict.nine.Simple9() - var simple2 = new test9_pb.jspb.exttest.strict.nine.Simple9() - assertObjectEquals(simple1.toObject(), simple2.toObject()); - }); - - it('testGlobalScopePollution', function() { - assertObjectEquals(global.jspb.exttest, undefined); - }); - - describe('with imports', function() { - it('testImportedMessage', function() { - var simple1 = new test10_pb.jspb.exttest.strict.ten.Simple10() - var simple2 = new test10_pb.jspb.exttest.strict.ten.Simple10() - assertObjectEquals(simple1.toObject(), simple2.toObject()); - }); - - it('testGlobalScopePollution', function() { - assertObjectEquals(global.jspb.exttest, undefined); - }); - }); -}); diff --git a/js/commonjs/test6/test6.proto b/js/commonjs/test6/test6.proto deleted file mode 100644 index a060925f2..000000000 --- a/js/commonjs/test6/test6.proto +++ /dev/null @@ -1,40 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2016 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test.importing; - -message ImportedMessage { - string string_value = 1; -} diff --git a/js/commonjs/test7/test7.proto b/js/commonjs/test7/test7.proto deleted file mode 100644 index f5574a3dd..000000000 --- a/js/commonjs/test7/test7.proto +++ /dev/null @@ -1,42 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2016 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test.framing; - -import "test6/test6.proto"; - -message FramingMessage { - jspb.test.importing.ImportedMessage imported_message = 1; -} diff --git a/js/compatibility_tests/v3.0.0/binary/arith_test.js b/js/compatibility_tests/v3.0.0/binary/arith_test.js deleted file mode 100644 index 89796bf79..000000000 --- a/js/compatibility_tests/v3.0.0/binary/arith_test.js +++ /dev/null @@ -1,355 +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. - -/** - * @fileoverview Test cases for Int64-manipulation functions. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author cfallin@google.com (Chris Fallin) - */ - -goog.require('goog.testing.asserts'); -goog.require('jspb.arith.Int64'); -goog.require('jspb.arith.UInt64'); - - -describe('binaryArithTest', function() { - /** - * Tests comparison operations. - */ - it('testCompare', function() { - var a = new jspb.arith.UInt64(1234, 5678); - var b = new jspb.arith.UInt64(1234, 5678); - assertEquals(a.cmp(b), 0); - assertEquals(b.cmp(a), 0); - b.lo -= 1; - assertEquals(a.cmp(b), 1); - assertEquals(b.cmp(a), -1); - b.lo += 2; - assertEquals(a.cmp(b), -1); - assertEquals(b.cmp(a), 1); - b.lo = a.lo; - b.hi = a.hi - 1; - assertEquals(a.cmp(b), 1); - assertEquals(b.cmp(a), -1); - - assertEquals(a.zero(), false); - assertEquals(a.msb(), false); - assertEquals(a.lsb(), false); - a.hi = 0; - a.lo = 0; - assertEquals(a.zero(), true); - a.hi = 0x80000000; - assertEquals(a.zero(), false); - assertEquals(a.msb(), true); - a.lo = 0x00000001; - assertEquals(a.lsb(), true); - }); - - - /** - * Tests shifts. - */ - it('testShifts', function() { - var a = new jspb.arith.UInt64(1, 0); - assertEquals(a.lo, 1); - assertEquals(a.hi, 0); - var orig = a; - a = a.leftShift(); - assertEquals(orig.lo, 1); // original unmodified. - assertEquals(orig.hi, 0); - assertEquals(a.lo, 2); - assertEquals(a.hi, 0); - a = a.leftShift(); - assertEquals(a.lo, 4); - assertEquals(a.hi, 0); - for (var i = 0; i < 29; i++) { - a = a.leftShift(); - } - assertEquals(a.lo, 0x80000000); - assertEquals(a.hi, 0); - a = a.leftShift(); - assertEquals(a.lo, 0); - assertEquals(a.hi, 1); - a = a.leftShift(); - assertEquals(a.lo, 0); - assertEquals(a.hi, 2); - a = a.rightShift(); - a = a.rightShift(); - assertEquals(a.lo, 0x80000000); - assertEquals(a.hi, 0); - a = a.rightShift(); - assertEquals(a.lo, 0x40000000); - assertEquals(a.hi, 0); - }); - - - /** - * Tests additions. - */ - it('testAdd', function() { - var a = new jspb.arith.UInt64(/* lo = */ 0x89abcdef, - /* hi = */ 0x01234567); - var b = new jspb.arith.UInt64(/* lo = */ 0xff52ab91, - /* hi = */ 0x92fa2123); - // Addition with carry. - var c = a.add(b); - assertEquals(a.lo, 0x89abcdef); // originals unmodified. - assertEquals(a.hi, 0x01234567); - assertEquals(b.lo, 0xff52ab91); - assertEquals(b.hi, 0x92fa2123); - assertEquals(c.lo, 0x88fe7980); - assertEquals(c.hi, 0x941d668b); - - // Simple addition without carry. - a.lo = 2; - a.hi = 0; - b.lo = 3; - b.hi = 0; - c = a.add(b); - assertEquals(c.lo, 5); - assertEquals(c.hi, 0); - }); - - - /** - * Test subtractions. - */ - it('testSub', function() { - var kLength = 10; - var hiValues = [0x1682ef32, - 0x583902f7, - 0xb62f5955, - 0x6ea99bbf, - 0x25a39c20, - 0x0700a08b, - 0x00f7304d, - 0x91a5b5af, - 0x89077fd2, - 0xe09e347c]; - var loValues = [0xe1538b18, - 0xbeacd556, - 0x74100758, - 0x96e3cb26, - 0x56c37c3f, - 0xe00b3f7d, - 0x859f25d7, - 0xc2ee614a, - 0xe1d21cd7, - 0x30aae6a4]; - for (var i = 0; i < kLength; i++) { - for (var j = 0; j < kLength; j++) { - var a = new jspb.arith.UInt64(loValues[i], hiValues[j]); - var b = new jspb.arith.UInt64(loValues[j], hiValues[i]); - var c = a.add(b).sub(b); - assertEquals(c.hi, a.hi); - assertEquals(c.lo, a.lo); - } - } - }); - - - /** - * Tests 32-by-32 multiplication. - */ - it('testMul32x32', function() { - var testData = [ - // a b low(a*b) high(a*b) - [0xc0abe2f8, 0x1607898a, 0x5de711b0, 0x109471b8], - [0x915eb3cb, 0x4fb66d0e, 0xbd0d441a, 0x2d43d0bc], - [0xfe4efe70, 0x80b48c37, 0xbcddea10, 0x7fdada0c], - [0xe222fd4a, 0xe43d524a, 0xd5e0eb64, 0xc99d549c], - [0xd171f469, 0xb94ebd01, 0x4be17969, 0x979bc4fa], - [0x829cc1df, 0xe2598b38, 0xf4157dc8, 0x737c12ad], - [0xf10c3767, 0x8382881e, 0x942b3612, 0x7bd428b8], - [0xb0f6dd24, 0x232597e1, 0x079c98a4, 0x184bbce7], - [0xfcdb05a7, 0x902f55bc, 0x636199a4, 0x8e69f412], - [0x0dd0bfa9, 0x916e27b1, 0x6e2542d9, 0x07d92e65] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = testData[i][0] >>> 0; - var b = testData[i][1] >>> 0; - var cLow = testData[i][2] >>> 0; - var cHigh = testData[i][3] >>> 0; - var c = jspb.arith.UInt64.mul32x32(a, b); - assertEquals(c.lo, cLow); - assertEquals(c.hi, cHigh); - } - }); - - - /** - * Tests 64-by-32 multiplication. - */ - it('testMul', function() { - // 64x32 bits produces 96 bits of product. The multiplication function under - // test truncates the top 32 bits, so we compare against a 64-bit expected - // product. - var testData = [ - // low(a) high(a) low(a*b) high(a*b) - [0xec10955b, 0x360eb168, 0x4b7f3f5b, 0xbfcb7c59, 0x9517da5f], - [0x42b000fc, 0x9d101642, 0x6fa1ab72, 0x2584c438, 0x6a9e6d2b], - [0xf42d4fb4, 0xae366403, 0xa65a1000, 0x92434000, 0x1ff978df], - [0x17e2f56b, 0x25487693, 0xf13f98c7, 0x73794e2d, 0xa96b0c6a], - [0x492f241f, 0x76c0eb67, 0x7377ac44, 0xd4336c3c, 0xfc4b1ebe], - [0xd6b92321, 0xe184fa48, 0xd6e76904, 0x93141584, 0xcbf44da1], - [0x4bf007ea, 0x968c0a9e, 0xf5e4026a, 0x4fdb1ae4, 0x61b9fb7d], - [0x10a83be7, 0x2d685ba6, 0xc9e5fb7f, 0x2ad43499, 0x3742473d], - [0x2f261829, 0x1aca681a, 0x3d3494e3, 0x8213205b, 0x283719f8], - [0xe4f2ce21, 0x2e74b7bd, 0xd801b38b, 0xbc17feeb, 0xc6c44e0f] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); - var prod = a.mul(testData[i][2]); - assertEquals(prod.lo, testData[i][3]); - assertEquals(prod.hi, testData[i][4]); - } - }); - - - /** - * Tests 64-div-by-32 division. - */ - it('testDiv', function() { - // Compute a/b, yielding quot = a/b and rem = a%b. - var testData = [ - // --- divisors in (0, 2^32-1) to test full divisor range - // low(a) high(a) b low(quot) high(quot) rem - [0x712443f1, 0xe85cefcc, 0xc1a7050b, 0x332c79ad, 0x00000001, 0x92ffa882], - [0x11912915, 0xb2699eb5, 0x30467cbe, 0xb21b4be4, 0x00000003, 0x283465dd], - [0x0d917982, 0x201f2a6e, 0x3f35bf03, 0x8217c8e4, 0x00000000, 0x153402d6], - [0xa072c108, 0x74020c96, 0xc60568fd, 0x95f9613e, 0x00000000, 0x3f4676c2], - [0xd845d5d8, 0xcdd235c4, 0x20426475, 0x6154e78b, 0x00000006, 0x202fb751], - [0xa4dbf71f, 0x9e90465e, 0xf08e022f, 0xa8be947f, 0x00000000, 0xbe43b5ce], - [0x3dbe627f, 0xa791f4b9, 0x28a5bd89, 0x1f5dfe93, 0x00000004, 0x02bf9ed4], - [0x5c1c53ee, 0xccf5102e, 0x198576e7, 0x07e3ae31, 0x00000008, 0x02ea8fb7], - [0xfef1e581, 0x04714067, 0xca6540c1, 0x059e73ec, 0x00000000, 0x31658095], - [0x1e2dd90c, 0x13dd6667, 0x8b2184c3, 0x248d1a42, 0x00000000, 0x4ca6d0c6], - // --- divisors in (0, 2^16-1) to test larger quotient high-words - // low(a) high(a) b low(quot) high(quot) rem - [0x86722b47, 0x2cd57c9a, 0x00003123, 0x2ae41b7a, 0x0000e995, 0x00000f99], - [0x1dd7884c, 0xf5e839bc, 0x00009eeb, 0x5c886242, 0x00018c21, 0x000099b6], - [0x5c53d625, 0x899fc7e5, 0x000087d7, 0xd625007a, 0x0001035c, 0x000019af], - [0x6932d932, 0x9d0a5488, 0x000051fb, 0x9d976143, 0x0001ea63, 0x00004981], - [0x4d18bb85, 0x0c92fb31, 0x00001d9f, 0x03265ab4, 0x00006cac, 0x000001b9], - [0xbe756768, 0xdea67ccb, 0x00008a03, 0x58add442, 0x00019cff, 0x000056a2], - [0xe2466f9a, 0x2521f114, 0x0000c350, 0xa0c0860d, 0x000030ab, 0x0000a48a], - [0xf00ddad1, 0xe2f5446a, 0x00002cfc, 0x762697a6, 0x00050b96, 0x00000b69], - [0xa879152a, 0x0a70e0a5, 0x00007cdf, 0xb44151b3, 0x00001567, 0x0000363d], - [0x7179a74c, 0x46083fff, 0x0000253c, 0x4d39ba6e, 0x0001e17f, 0x00000f84] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); - var result = a.div(testData[i][2]); - var quotient = result[0]; - var remainder = result[1]; - assertEquals(quotient.lo, testData[i][3]); - assertEquals(quotient.hi, testData[i][4]); - assertEquals(remainder.lo, testData[i][5]); - } - }); - - - /** - * Tests .toString() and .fromString(). - */ - it('testStrings', function() { - var testData = [ - [0x5e84c935, 0xcae33d0e, '14619595947299359029'], - [0x62b3b8b8, 0x93480544, '10612738313170434232'], - [0x319bfb13, 0xc01c4172, '13843011313344445203'], - [0x5b8a65fb, 0xa5885b31, '11927883880638080507'], - [0x6bdb80f1, 0xb0d1b16b, '12741159895737008369'], - [0x4b82b442, 0x2e0d8c97, '3318463081876730946'], - [0x780d5208, 0x7d76752c, '9040542135845999112'], - [0x2e46800f, 0x0993778d, '690026616168284175'], - [0xf00a7e32, 0xcd8e3931, '14811839111111540274'], - [0x1baeccd6, 0x923048c4, '10533999535534820566'], - [0x03669d29, 0xbff3ab72, '13831587386756603177'], - [0x2526073e, 0x01affc81, '121593346566522686'], - [0xc24244e0, 0xd7f40d0e, '15561076969511732448'], - [0xc56a341e, 0xa68b66a7, '12000798502816461854'], - [0x8738d64d, 0xbfe78604, '13828168534871037517'], - [0x5baff03b, 0xd7572aea, '15516918227177304123'], - [0x4a843d8a, 0x864e132b, '9677693725920476554'], - [0x25b4e94d, 0x22b54dc6, '2500990681505655117'], - [0x6bbe664b, 0x55a5cc0e, '6171563226690381387'], - [0xee916c81, 0xb00aabb3, '12685140089732426881'] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); - var roundtrip = jspb.arith.UInt64.fromString(a.toString()); - assertEquals(roundtrip.lo, a.lo); - assertEquals(roundtrip.hi, a.hi); - assertEquals(a.toString(), testData[i][2]); - } - }); - - - /** - * Tests signed Int64s. These are built on UInt64s, so we only need to test - * the explicit overrides: .toString() and .fromString(). - */ - it('testSignedInt64', function() { - var testStrings = [ - '-7847499644178593666', - '3771946501229139523', - '2872856549054995060', - '-5780049594274350904', - '3383785956695105201', - '2973055184857072610', - '-3879428459215627206', - '4589812431064156631', - '8484075557333689940', - '1075325817098092407', - '-4346697501012292314', - '2488620459718316637', - '6112655187423520672', - '-3655278273928612104', - '3439154019435803196', - '1004112478843763757', - '-6587790776614368413', - '664320065099714586', - '4760412909973292912', - '-7911903989602274672' - ]; - - for (var i = 0; i < testStrings.length; i++) { - var roundtrip = - jspb.arith.Int64.fromString(testStrings[i]).toString(); - assertEquals(roundtrip, testStrings[i]); - } - }); -}); diff --git a/js/compatibility_tests/v3.0.0/binary/decoder_test.js b/js/compatibility_tests/v3.0.0/binary/decoder_test.js deleted file mode 100644 index fce2fe181..000000000 --- a/js/compatibility_tests/v3.0.0/binary/decoder_test.js +++ /dev/null @@ -1,317 +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. - -/** - * @fileoverview Test cases for jspb's binary protocol buffer decoder. - * - * There are two particular magic numbers that need to be pointed out - - * 2^64-1025 is the largest number representable as both a double and an - * unsigned 64-bit integer, and 2^63-513 is the largest number representable as - * both a double and a signed 64-bit integer. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryDecoder'); -goog.require('jspb.BinaryEncoder'); - - -/** - * Tests encoding and decoding of unsigned types. - * @param {Function} readValue - * @param {Function} writeValue - * @param {number} epsilon - * @param {number} upperLimit - * @param {Function} filter - * @suppress {missingProperties|visibility} - */ -function doTestUnsignedValue(readValue, - writeValue, epsilon, upperLimit, filter) { - var encoder = new jspb.BinaryEncoder(); - - // Encode zero and limits. - writeValue.call(encoder, filter(0)); - writeValue.call(encoder, filter(epsilon)); - writeValue.call(encoder, filter(upperLimit)); - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - writeValue.call(encoder, filter(cursor)); - } - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - // Check zero and limits. - assertEquals(filter(0), readValue.call(decoder)); - assertEquals(filter(epsilon), readValue.call(decoder)); - assertEquals(filter(upperLimit), readValue.call(decoder)); - - // Check positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - if (filter(cursor) != readValue.call(decoder)) throw 'fail!'; - } - - // Encoding values outside the valid range should assert. - assertThrows(function() {writeValue.call(encoder, -1);}); - assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);}); -} - - -/** - * Tests encoding and decoding of signed types. - * @param {Function} readValue - * @param {Function} writeValue - * @param {number} epsilon - * @param {number} lowerLimit - * @param {number} upperLimit - * @param {Function} filter - * @suppress {missingProperties} - */ -function doTestSignedValue(readValue, - writeValue, epsilon, lowerLimit, upperLimit, filter) { - var encoder = new jspb.BinaryEncoder(); - - // Encode zero and limits. - writeValue.call(encoder, filter(lowerLimit)); - writeValue.call(encoder, filter(-epsilon)); - writeValue.call(encoder, filter(0)); - writeValue.call(encoder, filter(epsilon)); - writeValue.call(encoder, filter(upperLimit)); - - var inputValues = []; - - // Encode negative values. - for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) { - var val = filter(cursor); - writeValue.call(encoder, val); - inputValues.push(val); - } - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - var val = filter(cursor); - writeValue.call(encoder, val); - inputValues.push(val); - } - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - // Check zero and limits. - assertEquals(filter(lowerLimit), readValue.call(decoder)); - assertEquals(filter(-epsilon), readValue.call(decoder)); - assertEquals(filter(0), readValue.call(decoder)); - assertEquals(filter(epsilon), readValue.call(decoder)); - assertEquals(filter(upperLimit), readValue.call(decoder)); - - // Verify decoded values. - for (var i = 0; i < inputValues.length; i++) { - assertEquals(inputValues[i], readValue.call(decoder)); - } - - // Encoding values outside the valid range should assert. - assertThrows(function() {writeValue.call(encoder, lowerLimit * 1.1);}); - assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);}); -} - -describe('binaryDecoderTest', function() { - /** - * Tests the decoder instance cache. - */ - it('testInstanceCache', /** @suppress {visibility} */ function() { - // Empty the instance caches. - jspb.BinaryDecoder.instanceCache_ = []; - - // Allocating and then freeing a decoder should put it in the instance - // cache. - jspb.BinaryDecoder.alloc().free(); - - assertEquals(1, jspb.BinaryDecoder.instanceCache_.length); - - // Allocating and then freeing three decoders should leave us with three in - // the cache. - - var decoder1 = jspb.BinaryDecoder.alloc(); - var decoder2 = jspb.BinaryDecoder.alloc(); - var decoder3 = jspb.BinaryDecoder.alloc(); - decoder1.free(); - decoder2.free(); - decoder3.free(); - - assertEquals(3, jspb.BinaryDecoder.instanceCache_.length); - }); - - - /** - * Tests reading 64-bit integers as hash strings. - */ - it('testHashStrings', function() { - var encoder = new jspb.BinaryEncoder(); - - var hashA = String.fromCharCode(0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00); - var hashB = String.fromCharCode(0x12, 0x34, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00); - var hashC = String.fromCharCode(0x12, 0x34, 0x56, 0x78, - 0x87, 0x65, 0x43, 0x21); - var hashD = String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF); - - encoder.writeVarintHash64(hashA); - encoder.writeVarintHash64(hashB); - encoder.writeVarintHash64(hashC); - encoder.writeVarintHash64(hashD); - - encoder.writeFixedHash64(hashA); - encoder.writeFixedHash64(hashB); - encoder.writeFixedHash64(hashC); - encoder.writeFixedHash64(hashD); - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - assertEquals(hashA, decoder.readVarintHash64()); - assertEquals(hashB, decoder.readVarintHash64()); - assertEquals(hashC, decoder.readVarintHash64()); - assertEquals(hashD, decoder.readVarintHash64()); - - assertEquals(hashA, decoder.readFixedHash64()); - assertEquals(hashB, decoder.readFixedHash64()); - assertEquals(hashC, decoder.readFixedHash64()); - assertEquals(hashD, decoder.readFixedHash64()); - }); - - - /** - * Verifies that misuse of the decoder class triggers assertions. - * @suppress {checkTypes|visibility} - */ - it('testDecodeErrors', function() { - // Reading a value past the end of the stream should trigger an assertion. - var decoder = jspb.BinaryDecoder.alloc([0, 1, 2]); - assertThrows(function() {decoder.readUint64()}); - - // Overlong varints should trigger assertions. - decoder.setBlock([255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0]); - assertThrows(function() {decoder.readUnsignedVarint64()}); - decoder.reset(); - assertThrows(function() {decoder.readSignedVarint64()}); - decoder.reset(); - assertThrows(function() {decoder.readZigzagVarint64()}); - decoder.reset(); - assertThrows(function() {decoder.readUnsignedVarint32()}); - }); - - - /** - * Tests encoding and decoding of unsigned integers. - */ - it('testUnsignedIntegers', function() { - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint8, - jspb.BinaryEncoder.prototype.writeUint8, - 1, 0xFF, Math.round); - - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint16, - jspb.BinaryEncoder.prototype.writeUint16, - 1, 0xFFFF, Math.round); - - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint32, - jspb.BinaryEncoder.prototype.writeUint32, - 1, 0xFFFFFFFF, Math.round); - - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint64, - jspb.BinaryEncoder.prototype.writeUint64, - 1, Math.pow(2, 64) - 1025, Math.round); - }); - - - /** - * Tests encoding and decoding of signed integers. - */ - it('testSignedIntegers', function() { - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt8, - jspb.BinaryEncoder.prototype.writeInt8, - 1, -0x80, 0x7F, Math.round); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt16, - jspb.BinaryEncoder.prototype.writeInt16, - 1, -0x8000, 0x7FFF, Math.round); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt32, - jspb.BinaryEncoder.prototype.writeInt32, - 1, -0x80000000, 0x7FFFFFFF, Math.round); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt64, - jspb.BinaryEncoder.prototype.writeInt64, - 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); - }); - - - /** - * Tests encoding and decoding of floats. - */ - it('testFloats', function() { - /** - * @param {number} x - * @return {number} - */ - function truncate(x) { - var temp = new Float32Array(1); - temp[0] = x; - return temp[0]; - } - doTestSignedValue( - jspb.BinaryDecoder.prototype.readFloat, - jspb.BinaryEncoder.prototype.writeFloat, - jspb.BinaryConstants.FLOAT32_EPS, - -jspb.BinaryConstants.FLOAT32_MAX, - jspb.BinaryConstants.FLOAT32_MAX, - truncate); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readDouble, - jspb.BinaryEncoder.prototype.writeDouble, - jspb.BinaryConstants.FLOAT64_EPS * 10, - -jspb.BinaryConstants.FLOAT64_MAX, - jspb.BinaryConstants.FLOAT64_MAX, - function(x) { return x; }); - }); -}); diff --git a/js/compatibility_tests/v3.0.0/binary/proto_test.js b/js/compatibility_tests/v3.0.0/binary/proto_test.js deleted file mode 100644 index 136483457..000000000 --- a/js/compatibility_tests/v3.0.0/binary/proto_test.js +++ /dev/null @@ -1,628 +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. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - -goog.require('goog.crypt.base64'); -goog.require('goog.testing.asserts'); -goog.require('jspb.Message'); - -// CommonJS-LoadFromFile: ../testbinary_pb proto.jspb.test -goog.require('proto.jspb.test.ExtendsWithMessage'); -goog.require('proto.jspb.test.ForeignEnum'); -goog.require('proto.jspb.test.ForeignMessage'); -goog.require('proto.jspb.test.TestAllTypes'); -goog.require('proto.jspb.test.TestExtendable'); -goog.require('proto.jspb.test.extendOptionalBool'); -goog.require('proto.jspb.test.extendOptionalBytes'); -goog.require('proto.jspb.test.extendOptionalDouble'); -goog.require('proto.jspb.test.extendOptionalFixed32'); -goog.require('proto.jspb.test.extendOptionalFixed64'); -goog.require('proto.jspb.test.extendOptionalFloat'); -goog.require('proto.jspb.test.extendOptionalForeignEnum'); -goog.require('proto.jspb.test.extendOptionalInt32'); -goog.require('proto.jspb.test.extendOptionalInt64'); -goog.require('proto.jspb.test.extendOptionalSfixed32'); -goog.require('proto.jspb.test.extendOptionalSfixed64'); -goog.require('proto.jspb.test.extendOptionalSint32'); -goog.require('proto.jspb.test.extendOptionalSint64'); -goog.require('proto.jspb.test.extendOptionalString'); -goog.require('proto.jspb.test.extendOptionalUint32'); -goog.require('proto.jspb.test.extendOptionalUint64'); -goog.require('proto.jspb.test.extendPackedRepeatedBoolList'); -goog.require('proto.jspb.test.extendPackedRepeatedDoubleList'); -goog.require('proto.jspb.test.extendPackedRepeatedFixed32List'); -goog.require('proto.jspb.test.extendPackedRepeatedFixed64List'); -goog.require('proto.jspb.test.extendPackedRepeatedFloatList'); -goog.require('proto.jspb.test.extendPackedRepeatedForeignEnumList'); -goog.require('proto.jspb.test.extendPackedRepeatedInt32List'); -goog.require('proto.jspb.test.extendPackedRepeatedInt64List'); -goog.require('proto.jspb.test.extendPackedRepeatedSfixed32List'); -goog.require('proto.jspb.test.extendPackedRepeatedSfixed64List'); -goog.require('proto.jspb.test.extendPackedRepeatedSint32List'); -goog.require('proto.jspb.test.extendPackedRepeatedSint64List'); -goog.require('proto.jspb.test.extendPackedRepeatedUint32List'); -goog.require('proto.jspb.test.extendPackedRepeatedUint64List'); -goog.require('proto.jspb.test.extendRepeatedBoolList'); -goog.require('proto.jspb.test.extendRepeatedBytesList'); -goog.require('proto.jspb.test.extendRepeatedDoubleList'); -goog.require('proto.jspb.test.extendRepeatedFixed32List'); -goog.require('proto.jspb.test.extendRepeatedFixed64List'); -goog.require('proto.jspb.test.extendRepeatedFloatList'); -goog.require('proto.jspb.test.extendRepeatedForeignEnumList'); -goog.require('proto.jspb.test.extendRepeatedInt32List'); -goog.require('proto.jspb.test.extendRepeatedInt64List'); -goog.require('proto.jspb.test.extendRepeatedSfixed32List'); -goog.require('proto.jspb.test.extendRepeatedSfixed64List'); -goog.require('proto.jspb.test.extendRepeatedSint32List'); -goog.require('proto.jspb.test.extendRepeatedSint64List'); -goog.require('proto.jspb.test.extendRepeatedStringList'); -goog.require('proto.jspb.test.extendRepeatedUint32List'); -goog.require('proto.jspb.test.extendRepeatedUint64List'); - - -var suite = {}; - -var BYTES = new Uint8Array([1, 2, 8, 9]); - -var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES); - - -/** - * Helper: fill all fields on a TestAllTypes message. - * @param {proto.jspb.test.TestAllTypes} msg - */ -function fillAllFields(msg) { - msg.setOptionalInt32(-42); - // can be exactly represented by JS number (64-bit double, i.e., 52-bit - // mantissa). - msg.setOptionalInt64(-0x7fffffff00000000); - msg.setOptionalUint32(0x80000000); - msg.setOptionalUint64(0xf000000000000000); - msg.setOptionalSint32(-100); - msg.setOptionalSint64(-0x8000000000000000); - msg.setOptionalFixed32(1234); - msg.setOptionalFixed64(0x1234567800000000); - msg.setOptionalSfixed32(-1234); - msg.setOptionalSfixed64(-0x1234567800000000); - msg.setOptionalFloat(1.5); - msg.setOptionalDouble(-1.5); - msg.setOptionalBool(true); - msg.setOptionalString('hello world'); - msg.setOptionalBytes(BYTES); - msg.setOptionalGroup(new proto.jspb.test.TestAllTypes.OptionalGroup()); - msg.getOptionalGroup().setA(100); - var submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(16); - msg.setOptionalForeignMessage(submsg); - msg.setOptionalForeignEnum(proto.jspb.test.ForeignEnum.FOREIGN_FOO); - msg.setOneofString('oneof'); - - - msg.setRepeatedInt32List([-42]); - msg.setRepeatedInt64List([-0x7fffffff00000000]); - msg.setRepeatedUint32List([0x80000000]); - msg.setRepeatedUint64List([0xf000000000000000]); - msg.setRepeatedSint32List([-100]); - msg.setRepeatedSint64List([-0x8000000000000000]); - msg.setRepeatedFixed32List([1234]); - msg.setRepeatedFixed64List([0x1234567800000000]); - msg.setRepeatedSfixed32List([-1234]); - msg.setRepeatedSfixed64List([-0x1234567800000000]); - msg.setRepeatedFloatList([1.5]); - msg.setRepeatedDoubleList([-1.5]); - msg.setRepeatedBoolList([true]); - msg.setRepeatedStringList(['hello world']); - msg.setRepeatedBytesList([BYTES, BYTES]); - msg.setRepeatedGroupList([new proto.jspb.test.TestAllTypes.RepeatedGroup()]); - msg.getRepeatedGroupList()[0].setA(100); - submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(1000); - msg.setRepeatedForeignMessageList([submsg]); - msg.setRepeatedForeignEnumList([proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - msg.setPackedRepeatedInt32List([-42]); - msg.setPackedRepeatedInt64List([-0x7fffffff00000000]); - msg.setPackedRepeatedUint32List([0x80000000]); - msg.setPackedRepeatedUint64List([0xf000000000000000]); - msg.setPackedRepeatedSint32List([-100]); - msg.setPackedRepeatedSint64List([-0x8000000000000000]); - msg.setPackedRepeatedFixed32List([1234]); - msg.setPackedRepeatedFixed64List([0x1234567800000000]); - msg.setPackedRepeatedSfixed32List([-1234]); - msg.setPackedRepeatedSfixed64List([-0x1234567800000000]); - msg.setPackedRepeatedFloatList([1.5]); - msg.setPackedRepeatedDoubleList([-1.5]); - msg.setPackedRepeatedBoolList([true]); - -} - - -/** - * Helper: compare a bytes field to an expected value - * @param {Uint8Array|string} arr - * @param {Uint8Array} expected - * @return {boolean} - */ -function bytesCompare(arr, expected) { - if (typeof arr === 'string') { - arr = goog.crypt.base64.decodeStringToUint8Array(arr); - } - if (arr.length != expected.length) { - return false; - } - for (var i = 0; i < arr.length; i++) { - if (arr[i] != expected[i]) { - return false; - } - } - return true; -} - - -/** - * Helper: verify contents of given TestAllTypes message as set by - * fillAllFields(). - * @param {proto.jspb.test.TestAllTypes} original - * @param {proto.jspb.test.TestAllTypes} copy - */ -function checkAllFields(original, copy) { - assertTrue(jspb.Message.equals(original, copy)); - - assertEquals(copy.getOptionalInt32(), -42); - assertEquals(copy.getOptionalInt64(), -0x7fffffff00000000); - assertEquals(copy.getOptionalUint32(), 0x80000000); - assertEquals(copy.getOptionalUint64(), 0xf000000000000000); - assertEquals(copy.getOptionalSint32(), -100); - assertEquals(copy.getOptionalSint64(), -0x8000000000000000); - assertEquals(copy.getOptionalFixed32(), 1234); - assertEquals(copy.getOptionalFixed64(), 0x1234567800000000); - assertEquals(copy.getOptionalSfixed32(), -1234); - assertEquals(copy.getOptionalSfixed64(), -0x1234567800000000); - assertEquals(copy.getOptionalFloat(), 1.5); - assertEquals(copy.getOptionalDouble(), -1.5); - assertEquals(copy.getOptionalBool(), true); - assertEquals(copy.getOptionalString(), 'hello world'); - assertEquals(true, bytesCompare(copy.getOptionalBytes(), BYTES)); - assertEquals(true, bytesCompare(copy.getOptionalBytes_asU8(), BYTES)); - assertEquals( - copy.getOptionalBytes_asB64(), goog.crypt.base64.encodeByteArray(BYTES)); - - assertEquals(copy.getOptionalGroup().getA(), 100); - assertEquals(copy.getOptionalForeignMessage().getC(), 16); - assertEquals(copy.getOptionalForeignEnum(), - proto.jspb.test.ForeignEnum.FOREIGN_FOO); - - - assertEquals(copy.getOneofString(), 'oneof'); - assertEquals(copy.getOneofFieldCase(), - proto.jspb.test.TestAllTypes.OneofFieldCase.ONEOF_STRING); - - assertElementsEquals(copy.getRepeatedInt32List(), [-42]); - assertElementsEquals(copy.getRepeatedInt64List(), [-0x7fffffff00000000]); - assertElementsEquals(copy.getRepeatedUint32List(), [0x80000000]); - assertElementsEquals(copy.getRepeatedUint64List(), [0xf000000000000000]); - assertElementsEquals(copy.getRepeatedSint32List(), [-100]); - assertElementsEquals(copy.getRepeatedSint64List(), [-0x8000000000000000]); - assertElementsEquals(copy.getRepeatedFixed32List(), [1234]); - assertElementsEquals(copy.getRepeatedFixed64List(), [0x1234567800000000]); - assertElementsEquals(copy.getRepeatedSfixed32List(), [-1234]); - assertElementsEquals(copy.getRepeatedSfixed64List(), [-0x1234567800000000]); - assertElementsEquals(copy.getRepeatedFloatList(), [1.5]); - assertElementsEquals(copy.getRepeatedDoubleList(), [-1.5]); - assertElementsEquals(copy.getRepeatedBoolList(), [true]); - assertElementsEquals(copy.getRepeatedStringList(), ['hello world']); - assertEquals(copy.getRepeatedBytesList().length, 2); - assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[0], BYTES)); - assertEquals(true, bytesCompare(copy.getRepeatedBytesList()[0], BYTES)); - assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[1], BYTES)); - assertEquals(copy.getRepeatedBytesList_asB64()[0], BYTES_B64); - assertEquals(copy.getRepeatedBytesList_asB64()[1], BYTES_B64); - assertEquals(copy.getRepeatedGroupList().length, 1); - assertEquals(copy.getRepeatedGroupList()[0].getA(), 100); - assertEquals(copy.getRepeatedForeignMessageList().length, 1); - assertEquals(copy.getRepeatedForeignMessageList()[0].getC(), 1000); - assertElementsEquals(copy.getRepeatedForeignEnumList(), - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - assertElementsEquals(copy.getPackedRepeatedInt32List(), [-42]); - assertElementsEquals(copy.getPackedRepeatedInt64List(), - [-0x7fffffff00000000]); - assertElementsEquals(copy.getPackedRepeatedUint32List(), [0x80000000]); - assertElementsEquals(copy.getPackedRepeatedUint64List(), - [0xf000000000000000]); - assertElementsEquals(copy.getPackedRepeatedSint32List(), [-100]); - assertElementsEquals(copy.getPackedRepeatedSint64List(), - [-0x8000000000000000]); - assertElementsEquals(copy.getPackedRepeatedFixed32List(), [1234]); - assertElementsEquals(copy.getPackedRepeatedFixed64List(), - [0x1234567800000000]); - assertElementsEquals(copy.getPackedRepeatedSfixed32List(), [-1234]); - assertElementsEquals(copy.getPackedRepeatedSfixed64List(), - [-0x1234567800000000]); - assertElementsEquals(copy.getPackedRepeatedFloatList(), [1.5]); - assertElementsEquals(copy.getPackedRepeatedDoubleList(), [-1.5]); - -} - - -/** - * Helper: verify that all expected extensions are present. - * @param {!proto.jspb.test.TestExtendable} msg - */ -function checkExtensions(msg) { - assertEquals(-42, - msg.getExtension(proto.jspb.test.extendOptionalInt32)); - assertEquals(-0x7fffffff00000000, - msg.getExtension(proto.jspb.test.extendOptionalInt64)); - assertEquals(0x80000000, - msg.getExtension(proto.jspb.test.extendOptionalUint32)); - assertEquals(0xf000000000000000, - msg.getExtension(proto.jspb.test.extendOptionalUint64)); - assertEquals(-100, - msg.getExtension(proto.jspb.test.extendOptionalSint32)); - assertEquals(-0x8000000000000000, - msg.getExtension(proto.jspb.test.extendOptionalSint64)); - assertEquals(1234, - msg.getExtension(proto.jspb.test.extendOptionalFixed32)); - assertEquals(0x1234567800000000, - msg.getExtension(proto.jspb.test.extendOptionalFixed64)); - assertEquals(-1234, - msg.getExtension(proto.jspb.test.extendOptionalSfixed32)); - assertEquals(-0x1234567800000000, - msg.getExtension(proto.jspb.test.extendOptionalSfixed64)); - assertEquals(1.5, - msg.getExtension(proto.jspb.test.extendOptionalFloat)); - assertEquals(-1.5, - msg.getExtension(proto.jspb.test.extendOptionalDouble)); - assertEquals(true, - msg.getExtension(proto.jspb.test.extendOptionalBool)); - assertEquals('hello world', - msg.getExtension(proto.jspb.test.extendOptionalString)); - assertEquals( - true, bytesCompare( - msg.getExtension(proto.jspb.test.extendOptionalBytes), BYTES)); - assertEquals(16, - msg.getExtension( - proto.jspb.test.ExtendsWithMessage.optionalExtension).getFoo()); - - - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedInt32List), - [-42]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedInt64List), - [-0x7fffffff00000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedUint32List), - [0x80000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedUint64List), - [0xf000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSint32List), - [-100]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSint64List), - [-0x8000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedFixed32List), - [1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedFixed64List), - [0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSfixed32List), - [-1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSfixed64List), - [-0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedFloatList), - [1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedDoubleList), - [-1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedBoolList), - [true]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedStringList), - ['hello world']); - assertEquals( - true, - bytesCompare( - msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0], BYTES)); - assertEquals(1000, - msg.getExtension( - proto.jspb.test.ExtendsWithMessage.repeatedExtensionList)[0] - .getFoo()); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedForeignEnumList), - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedInt32List), - [-42]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedInt64List), - [-0x7fffffff00000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedUint32List), - [0x80000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedUint64List), - [0xf000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSint32List), - [-100]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSint64List), - [-0x8000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed32List), - [1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed64List), - [0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed32List), - [-1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed64List), - [-0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedFloatList), - [1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedDoubleList), - [-1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedBoolList), - [true]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList), - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - -} - - -describe('protoBinaryTest', function() { - /** - * Tests a basic serialization-deserializaton round-trip with all supported - * field types (on the TestAllTypes message type). - */ - it('testRoundTrip', function() { - var msg = new proto.jspb.test.TestAllTypes(); - fillAllFields(msg); - var encoded = msg.serializeBinary(); - var decoded = proto.jspb.test.TestAllTypes.deserializeBinary(encoded); - checkAllFields(msg, decoded); - }); - - /** - * Test that base64 string and Uint8Array are interchangeable in bytes fields. - */ - it('testBytesFieldsGettersInterop', function() { - var msg = new proto.jspb.test.TestAllTypes(); - // Set from a base64 string and check all the getters work. - msg.setOptionalBytes(BYTES_B64); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - // Test binary serialize round trip doesn't break it. - msg = proto.jspb.test.TestAllTypes.deserializeBinary(msg.serializeBinary()); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - msg = new proto.jspb.test.TestAllTypes(); - // Set from a Uint8Array and check all the getters work. - msg.setOptionalBytes(BYTES); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - }); - - /** - * Test that bytes setters will receive result of any of the getters. - */ - it('testBytesFieldsSettersInterop', function() { - var msg = new proto.jspb.test.TestAllTypes(); - msg.setOptionalBytes(BYTES); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - msg.setOptionalBytes(msg.getOptionalBytes()); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - msg.setOptionalBytes(msg.getOptionalBytes_asB64()); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - msg.setOptionalBytes(msg.getOptionalBytes_asU8()); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - }); - - /** - * Test that bytes setters will receive result of any of the getters. - */ - it('testRepeatedBytesGetters', function() { - var msg = new proto.jspb.test.TestAllTypes(); - - function assertGetters() { - assertTrue(typeof msg.getRepeatedBytesList_asB64()[0] === 'string'); - assertTrue(typeof msg.getRepeatedBytesList_asB64()[1] === 'string'); - assertTrue(msg.getRepeatedBytesList_asU8()[0] instanceof Uint8Array); - assertTrue(msg.getRepeatedBytesList_asU8()[1] instanceof Uint8Array); - - assertTrue(bytesCompare(msg.getRepeatedBytesList()[0], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList()[1], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[0], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[1], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[0], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[1], BYTES)); - } - - msg.setRepeatedBytesList([BYTES, BYTES]); - assertGetters(); - - msg.setRepeatedBytesList([BYTES_B64, BYTES_B64]); - assertGetters(); - - msg.setRepeatedBytesList(null); - assertEquals(0, msg.getRepeatedBytesList().length); - assertEquals(0, msg.getRepeatedBytesList_asB64().length); - assertEquals(0, msg.getRepeatedBytesList_asU8().length); - }); - - /** - * Helper: fill all extension values. - * @param {proto.jspb.test.TestExtendable} msg - */ - function fillExtensions(msg) { - msg.setExtension( - proto.jspb.test.extendOptionalInt32, -42); - msg.setExtension( - proto.jspb.test.extendOptionalInt64, -0x7fffffff00000000); - msg.setExtension( - proto.jspb.test.extendOptionalUint32, 0x80000000); - msg.setExtension( - proto.jspb.test.extendOptionalUint64, 0xf000000000000000); - msg.setExtension( - proto.jspb.test.extendOptionalSint32, -100); - msg.setExtension( - proto.jspb.test.extendOptionalSint64, -0x8000000000000000); - msg.setExtension( - proto.jspb.test.extendOptionalFixed32, 1234); - msg.setExtension( - proto.jspb.test.extendOptionalFixed64, 0x1234567800000000); - msg.setExtension( - proto.jspb.test.extendOptionalSfixed32, -1234); - msg.setExtension( - proto.jspb.test.extendOptionalSfixed64, -0x1234567800000000); - msg.setExtension( - proto.jspb.test.extendOptionalFloat, 1.5); - msg.setExtension( - proto.jspb.test.extendOptionalDouble, -1.5); - msg.setExtension( - proto.jspb.test.extendOptionalBool, true); - msg.setExtension( - proto.jspb.test.extendOptionalString, 'hello world'); - msg.setExtension(proto.jspb.test.extendOptionalBytes, BYTES); - var submsg = new proto.jspb.test.ExtendsWithMessage(); - submsg.setFoo(16); - msg.setExtension( - proto.jspb.test.ExtendsWithMessage.optionalExtension, submsg); - msg.setExtension( - proto.jspb.test.extendOptionalForeignEnum, - proto.jspb.test.ForeignEnum.FOREIGN_FOO); - - - msg.setExtension( - proto.jspb.test.extendRepeatedInt32List, [-42]); - msg.setExtension( - proto.jspb.test.extendRepeatedInt64List, [-0x7fffffff00000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedUint32List, [0x80000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedUint64List, [0xf000000000000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedSint32List, [-100]); - msg.setExtension( - proto.jspb.test.extendRepeatedSint64List, [-0x8000000000000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedFixed32List, [1234]); - msg.setExtension( - proto.jspb.test.extendRepeatedFixed64List, [0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedSfixed32List, [-1234]); - msg.setExtension( - proto.jspb.test.extendRepeatedSfixed64List, [-0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedFloatList, [1.5]); - msg.setExtension( - proto.jspb.test.extendRepeatedDoubleList, [-1.5]); - msg.setExtension( - proto.jspb.test.extendRepeatedBoolList, [true]); - msg.setExtension( - proto.jspb.test.extendRepeatedStringList, ['hello world']); - msg.setExtension(proto.jspb.test.extendRepeatedBytesList, [BYTES]); - submsg = new proto.jspb.test.ExtendsWithMessage(); - submsg.setFoo(1000); - msg.setExtension( - proto.jspb.test.ExtendsWithMessage.repeatedExtensionList, [submsg]); - msg.setExtension(proto.jspb.test.extendRepeatedForeignEnumList, - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - - msg.setExtension( - proto.jspb.test.extendPackedRepeatedInt32List, [-42]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedInt64List, [-0x7fffffff00000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedUint32List, [0x80000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedUint64List, [0xf000000000000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSint32List, [-100]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSint64List, [-0x8000000000000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedFixed32List, [1234]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedFixed64List, [0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSfixed32List, [-1234]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSfixed64List, - [-0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedFloatList, [1.5]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedDoubleList, [-1.5]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedBoolList, [true]); - msg.setExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList, - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - } - - - /** - * Tests extension serialization and deserialization. - */ - it('testExtensions', function() { - var msg = new proto.jspb.test.TestExtendable(); - fillExtensions(msg); - var encoded = msg.serializeBinary(); - var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded); - checkExtensions(decoded); - }); -}); diff --git a/js/compatibility_tests/v3.0.0/binary/reader_test.js b/js/compatibility_tests/v3.0.0/binary/reader_test.js deleted file mode 100644 index 285b0e5eb..000000000 --- a/js/compatibility_tests/v3.0.0/binary/reader_test.js +++ /dev/null @@ -1,922 +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. - -/** - * @fileoverview Test cases for jspb's binary protocol buffer reader. - * - * There are two particular magic numbers that need to be pointed out - - * 2^64-1025 is the largest number representable as both a double and an - * unsigned 64-bit integer, and 2^63-513 is the largest number representable as - * both a double and a signed 64-bit integer. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryDecoder'); -goog.require('jspb.BinaryReader'); -goog.require('jspb.BinaryWriter'); - - - -describe('binaryReaderTest', function() { - /** - * Tests the reader instance cache. - */ - it('testInstanceCaches', /** @suppress {visibility} */ function() { - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); - writer.writeMessage(1, dummyMessage, () => {}); - writer.writeMessage(2, dummyMessage, () => {}); - - var buffer = writer.getResultBuffer(); - - // Empty the instance caches. - jspb.BinaryReader.instanceCache_ = []; - - // Allocating and then freeing three decoders should leave us with three in - // the cache. - - var decoder1 = jspb.BinaryDecoder.alloc(); - var decoder2 = jspb.BinaryDecoder.alloc(); - var decoder3 = jspb.BinaryDecoder.alloc(); - decoder1.free(); - decoder2.free(); - decoder3.free(); - - assertEquals(3, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - - // Allocating and then freeing a reader should remove one decoder from its - // cache, but it should stay stuck to the reader afterwards since we can't - // have a reader without a decoder. - jspb.BinaryReader.alloc().free(); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(1, jspb.BinaryReader.instanceCache_.length); - - // Allocating a reader should remove a reader from the cache. - var reader = jspb.BinaryReader.alloc(buffer); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - - // Processing the message reuses the current reader. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - }); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - }); - - assertEquals(false, reader.nextField()); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - - // Freeing the reader should put it back into the cache. - reader.free(); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(1, jspb.BinaryReader.instanceCache_.length); - }); - - - /** - * @param {number} x - * @return {number} - */ - function truncate(x) { - var temp = new Float32Array(1); - temp[0] = x; - return temp[0]; - } - - - /** - * Verifies that misuse of the reader class triggers assertions. - */ - it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() { - // Calling readMessage on a non-delimited field should trigger an - // assertion. - var reader = jspb.BinaryReader.alloc([8, 1]); - var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); - reader.nextField(); - assertThrows(function() { - reader.readMessage(dummyMessage, () => {}); - }); - - // Reading past the end of the stream should trigger an assertion. - reader = jspb.BinaryReader.alloc([9, 1]); - reader.nextField(); - assertThrows(function() {reader.readFixed64()}); - - // Reading past the end of a submessage should trigger an assertion. - reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]); - reader.nextField(); - reader.readMessage(dummyMessage, function() { - reader.nextField(); - assertThrows(function() {reader.readFixed32()}); - }); - - // Skipping an invalid field should trigger an assertion. - reader = jspb.BinaryReader.alloc([12, 1]); - reader.nextWireType_ = 1000; - assertThrows(function() {reader.skipField()}); - - // Reading fields with the wrong wire type should assert. - reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]); - reader.nextField(); - assertThrows(function() {reader.readInt32()}); - assertThrows(function() {reader.readInt32String()}); - assertThrows(function() {reader.readInt64()}); - assertThrows(function() {reader.readInt64String()}); - assertThrows(function() {reader.readUint32()}); - assertThrows(function() {reader.readUint32String()}); - assertThrows(function() {reader.readUint64()}); - assertThrows(function() {reader.readUint64String()}); - assertThrows(function() {reader.readSint32()}); - assertThrows(function() {reader.readBool()}); - assertThrows(function() {reader.readEnum()}); - - reader = jspb.BinaryReader.alloc([8, 1]); - reader.nextField(); - assertThrows(function() {reader.readFixed32()}); - assertThrows(function() {reader.readFixed64()}); - assertThrows(function() {reader.readSfixed32()}); - assertThrows(function() {reader.readSfixed64()}); - assertThrows(function() {reader.readFloat()}); - assertThrows(function() {reader.readDouble()}); - - assertThrows(function() {reader.readString()}); - assertThrows(function() {reader.readBytes()}); - }); - - - /** - * Tests encoding and decoding of unsigned field types. - * @param {Function} readField - * @param {Function} writeField - * @param {number} epsilon - * @param {number} upperLimit - * @param {Function} filter - * @private - * @suppress {missingProperties} - */ - var doTestUnsignedField_ = function(readField, - writeField, epsilon, upperLimit, filter) { - assertNotNull(readField); - assertNotNull(writeField); - - var writer = new jspb.BinaryWriter(); - - // Encode zero and limits. - writeField.call(writer, 1, filter(0)); - writeField.call(writer, 2, filter(epsilon)); - writeField.call(writer, 3, filter(upperLimit)); - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - writeField.call(writer, 4, filter(cursor)); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - // Check zero and limits. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(filter(0), readField.call(reader)); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(filter(epsilon), readField.call(reader)); - - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(filter(upperLimit), readField.call(reader)); - - // Check positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - reader.nextField(); - if (4 != reader.getFieldNumber()) throw 'fail!'; - if (filter(cursor) != readField.call(reader)) throw 'fail!'; - } - }; - - - /** - * Tests encoding and decoding of signed field types. - * @param {Function} readField - * @param {Function} writeField - * @param {number} epsilon - * @param {number} lowerLimit - * @param {number} upperLimit - * @param {Function} filter - * @private - * @suppress {missingProperties} - */ - var doTestSignedField_ = function(readField, - writeField, epsilon, lowerLimit, upperLimit, filter) { - var writer = new jspb.BinaryWriter(); - - // Encode zero and limits. - writeField.call(writer, 1, filter(lowerLimit)); - writeField.call(writer, 2, filter(-epsilon)); - writeField.call(writer, 3, filter(0)); - writeField.call(writer, 4, filter(epsilon)); - writeField.call(writer, 5, filter(upperLimit)); - - var inputValues = []; - - // Encode negative values. - for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) { - var val = filter(cursor); - writeField.call(writer, 6, val); - inputValues.push({ - fieldNumber: 6, - value: val - }); - } - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - var val = filter(cursor); - writeField.call(writer, 7, val); - inputValues.push({ - fieldNumber: 7, - value: val - }); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - // Check zero and limits. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(filter(lowerLimit), readField.call(reader)); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(filter(-epsilon), readField.call(reader)); - - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(filter(0), readField.call(reader)); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(filter(epsilon), readField.call(reader)); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(filter(upperLimit), readField.call(reader)); - - for (var i = 0; i < inputValues.length; i++) { - var expected = inputValues[i]; - reader.nextField(); - assertEquals(expected.fieldNumber, reader.getFieldNumber()); - assertEquals(expected.value, readField.call(reader)); - } - }; - - - /** - * Tests fields that use varint encoding. - */ - it('testVarintFields', function() { - assertNotUndefined(jspb.BinaryReader.prototype.readUint32); - assertNotUndefined(jspb.BinaryWriter.prototype.writeUint32); - assertNotUndefined(jspb.BinaryReader.prototype.readUint64); - assertNotUndefined(jspb.BinaryWriter.prototype.writeUint64); - assertNotUndefined(jspb.BinaryReader.prototype.readBool); - assertNotUndefined(jspb.BinaryWriter.prototype.writeBool); - doTestUnsignedField_( - jspb.BinaryReader.prototype.readUint32, - jspb.BinaryWriter.prototype.writeUint32, - 1, Math.pow(2, 32) - 1, Math.round); - - doTestUnsignedField_( - jspb.BinaryReader.prototype.readUint64, - jspb.BinaryWriter.prototype.writeUint64, - 1, Math.pow(2, 64) - 1025, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readInt32, - jspb.BinaryWriter.prototype.writeInt32, - 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readInt64, - jspb.BinaryWriter.prototype.writeInt64, - 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readEnum, - jspb.BinaryWriter.prototype.writeEnum, - 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); - - doTestUnsignedField_( - jspb.BinaryReader.prototype.readBool, - jspb.BinaryWriter.prototype.writeBool, - 1, 1, function(x) { return !!x; }); - }); - - - /** - * Tests reading a field from hexadecimal string (format: '08 BE EF'). - * @param {Function} readField - * @param {number} expected - * @param {string} hexString - */ - function doTestHexStringVarint_(readField, expected, hexString) { - var bytesCount = (hexString.length + 1) / 3; - var bytes = new Uint8Array(bytesCount); - for (var i = 0; i < bytesCount; i++) { - bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16); - } - var reader = jspb.BinaryReader.alloc(bytes); - reader.nextField(); - assertEquals(expected, readField.call(reader)); - } - - - /** - * Tests non-canonical redundant varint decoding. - */ - it('testRedundantVarintFields', function() { - assertNotNull(jspb.BinaryReader.prototype.readUint32); - assertNotNull(jspb.BinaryReader.prototype.readUint64); - assertNotNull(jspb.BinaryReader.prototype.readSint32); - assertNotNull(jspb.BinaryReader.prototype.readSint64); - - // uint32 and sint32 take no more than 5 bytes - // 08 - field prefix (type = 0 means varint) - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readUint32, - 12, '08 8C 80 80 80 00'); - - // 11 stands for -6 in zigzag encoding - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readSint32, - -6, '08 8B 80 80 80 00'); - - // uint64 and sint64 take no more than 10 bytes - // 08 - field prefix (type = 0 means varint) - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readUint64, - 12, '08 8C 80 80 80 80 80 80 80 80 00'); - - // 11 stands for -6 in zigzag encoding - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readSint64, - -6, '08 8B 80 80 80 80 80 80 80 80 00'); - }); - - - /** - * Tests 64-bit fields that are handled as strings. - */ - it('testStringInt64Fields', function() { - var writer = new jspb.BinaryWriter(); - - var testSignedData = [ - '2730538252207801776', - '-2688470994844604560', - '3398529779486536359', - '3568577411627971000', - '272477188847484900', - '-6649058714086158188', - '-7695254765712060806', - '-4525541438037104029', - '-4993706538836508568', - '4990160321893729138' - ]; - var testUnsignedData = [ - '7822732630241694882', - '6753602971916687352', - '2399935075244442116', - '8724292567325338867', - '16948784802625696584', - '4136275908516066934', - '3575388346793700364', - '5167142028379259461', - '1557573948689737699', - '17100725280812548567' - ]; - - for (var i = 0; i < testSignedData.length; i++) { - writer.writeInt64String(2 * i + 1, testSignedData[i]); - writer.writeUint64String(2 * i + 2, testUnsignedData[i]); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - for (var i = 0; i < testSignedData.length; i++) { - reader.nextField(); - assertEquals(2 * i + 1, reader.getFieldNumber()); - assertEquals(testSignedData[i], reader.readInt64String()); - reader.nextField(); - assertEquals(2 * i + 2, reader.getFieldNumber()); - assertEquals(testUnsignedData[i], reader.readUint64String()); - } - }); - - - /** - * Tests fields that use zigzag encoding. - */ - it('testZigzagFields', function() { - doTestSignedField_( - jspb.BinaryReader.prototype.readSint32, - jspb.BinaryWriter.prototype.writeSint32, - 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSint64, - jspb.BinaryWriter.prototype.writeSint64, - 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); - }); - - - /** - * Tests fields that use fixed-length encoding. - */ - it('testFixedFields', function() { - doTestUnsignedField_( - jspb.BinaryReader.prototype.readFixed32, - jspb.BinaryWriter.prototype.writeFixed32, - 1, Math.pow(2, 32) - 1, Math.round); - - doTestUnsignedField_( - jspb.BinaryReader.prototype.readFixed64, - jspb.BinaryWriter.prototype.writeFixed64, - 1, Math.pow(2, 64) - 1025, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSfixed32, - jspb.BinaryWriter.prototype.writeSfixed32, - 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSfixed64, - jspb.BinaryWriter.prototype.writeSfixed64, - 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); - }); - - - /** - * Tests floating point fields. - */ - it('testFloatFields', function() { - doTestSignedField_( - jspb.BinaryReader.prototype.readFloat, - jspb.BinaryWriter.prototype.writeFloat, - jspb.BinaryConstants.FLOAT32_MIN, - -jspb.BinaryConstants.FLOAT32_MAX, - jspb.BinaryConstants.FLOAT32_MAX, - truncate); - - doTestSignedField_( - jspb.BinaryReader.prototype.readDouble, - jspb.BinaryWriter.prototype.writeDouble, - jspb.BinaryConstants.FLOAT64_EPS * 10, - -jspb.BinaryConstants.FLOAT64_MIN, - jspb.BinaryConstants.FLOAT64_MIN, - function(x) { return x; }); - }); - - - /** - * Tests length-delimited string fields. - */ - it('testStringFields', function() { - var s1 = 'The quick brown fox jumps over the lazy dog.'; - var s2 = '人人生而自由,在尊嚴和權利上一律平等。'; - - var writer = new jspb.BinaryWriter(); - - writer.writeString(1, s1); - writer.writeString(2, s2); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(s1, reader.readString()); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(s2, reader.readString()); - }); - - - /** - * Tests length-delimited byte fields. - */ - it('testByteFields', function() { - var message = []; - var lowerLimit = 1; - var upperLimit = 256; - var scale = 1.1; - - var writer = new jspb.BinaryWriter(); - - for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) { - var len = Math.round(cursor); - var bytes = []; - for (var i = 0; i < len; i++) bytes.push(i % 256); - - writer.writeBytes(len, bytes); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) { - var len = Math.round(cursor); - if (len != reader.getFieldNumber()) throw 'fail!'; - - var bytes = reader.readBytes(); - if (len != bytes.length) throw 'fail!'; - for (var i = 0; i < bytes.length; i++) { - if (i % 256 != bytes[i]) throw 'fail!'; - } - } - }); - - - /** - * Tests nested messages. - */ - it('testNesting', function() { - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); - - writer.writeInt32(1, 100); - - // Add one message with 3 int fields. - writer.writeMessage(2, dummyMessage, function() { - writer.writeInt32(3, 300); - writer.writeInt32(4, 400); - writer.writeInt32(5, 500); - }); - - // Add one empty message. - writer.writeMessage(6, dummyMessage, () => {}); - - writer.writeInt32(7, 700); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - // Validate outermost message. - - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(100, reader.readInt32()); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - // Validate embedded message 1. - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(300, reader.readInt32()); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(400, reader.readInt32()); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(500, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }); - - reader.nextField(); - assertEquals(6, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - // Validate embedded message 2. - - assertEquals(false, reader.nextField()); - }); - - reader.nextField(); - assertEquals(7, reader.getFieldNumber()); - assertEquals(700, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }); - - /** - * Tests skipping fields of each type by interleaving them with sentinel - * values and skipping everything that's not a sentinel. - */ - it('testSkipField', function() { - var writer = new jspb.BinaryWriter(); - - var sentinel = 123456789; - - // Write varint fields of different sizes. - writer.writeInt32(1, sentinel); - writer.writeInt32(1, 1); - writer.writeInt32(1, 1000); - writer.writeInt32(1, 1000000); - writer.writeInt32(1, 1000000000); - - // Write fixed 64-bit encoded fields. - writer.writeInt32(2, sentinel); - writer.writeDouble(2, 1); - writer.writeFixed64(2, 1); - writer.writeSfixed64(2, 1); - - // Write fixed 32-bit encoded fields. - writer.writeInt32(3, sentinel); - writer.writeFloat(3, 1); - writer.writeFixed32(3, 1); - writer.writeSfixed32(3, 1); - - // Write delimited fields. - writer.writeInt32(4, sentinel); - writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - writer.writeString(4, 'The quick brown fox jumps over the lazy dog'); - - // Write a group with a nested group inside. - writer.writeInt32(5, sentinel); - var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); - writer.writeGroup(5, dummyMessage, function() { - writer.writeInt64(42, 42); - writer.writeGroup(6, dummyMessage, function() { - writer.writeInt64(84, 42); - }); - }); - - // Write final sentinel. - writer.writeInt32(6, sentinel); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - function skip(field, count) { - for (var i = 0; i < count; i++) { - reader.nextField(); - if (field != reader.getFieldNumber()) throw 'fail!'; - reader.skipField(); - } - } - - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(1, 4); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(2, 3); - - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(3, 3); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(4, 2); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(5, 1); - - reader.nextField(); - assertEquals(6, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - }); - - - /** - * Tests packed fields. - */ - it('testPackedFields', function() { - var writer = new jspb.BinaryWriter(); - - var sentinel = 123456789; - - var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]; - var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; - var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; - var boolData = [true, false, true, true, false, false, true, false]; - - for (var i = 0; i < floatData.length; i++) { - floatData[i] = truncate(floatData[i]); - } - - writer.writeInt32(1, sentinel); - - writer.writePackedInt32(2, signedData); - writer.writePackedInt64(2, signedData); - writer.writePackedUint32(2, unsignedData); - writer.writePackedUint64(2, unsignedData); - writer.writePackedSint32(2, signedData); - writer.writePackedSint64(2, signedData); - writer.writePackedFixed32(2, unsignedData); - writer.writePackedFixed64(2, unsignedData); - writer.writePackedSfixed32(2, signedData); - writer.writePackedSfixed64(2, signedData); - writer.writePackedFloat(2, floatData); - writer.writePackedDouble(2, doubleData); - writer.writePackedBool(2, boolData); - writer.writePackedEnum(2, unsignedData); - - writer.writeInt32(3, sentinel); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - reader.nextField(); - assertEquals(sentinel, reader.readInt32()); - - reader.nextField(); - assertElementsEquals(reader.readPackedInt32(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedInt64(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedUint32(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedUint64(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSint32(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSint64(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedFixed32(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedFixed64(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSfixed32(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSfixed64(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedFloat(), floatData); - - reader.nextField(); - assertElementsEquals(reader.readPackedDouble(), doubleData); - - reader.nextField(); - assertElementsEquals(reader.readPackedBool(), boolData); - - reader.nextField(); - assertElementsEquals(reader.readPackedEnum(), unsignedData); - - reader.nextField(); - assertEquals(sentinel, reader.readInt32()); - }); - - - /** - * Byte blobs inside nested messages should always have their byte offset set - * relative to the start of the outermost blob, not the start of their parent - * blob. - */ - it('testNestedBlobs', function() { - // Create a proto consisting of two nested messages, with the inner one - // containing a blob of bytes. - - var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED; - var blob = [1, 2, 3, 4, 5]; - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); - - writer.writeMessage(1, dummyMessage, function() { - writer.writeMessage(1, dummyMessage, function() { - writer.writeBytes(1, blob); - }); - }); - - // Peel off the outer two message layers. Each layer should have two bytes - // of overhead, one for the field tag and one for the length of the inner - // blob. - - var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer()); - assertEquals(fieldTag, decoder1.readUnsignedVarint32()); - assertEquals(blob.length + 4, decoder1.readUnsignedVarint32()); - - var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4)); - assertEquals(fieldTag, decoder2.readUnsignedVarint32()); - assertEquals(blob.length + 2, decoder2.readUnsignedVarint32()); - - assertEquals(fieldTag, decoder2.readUnsignedVarint32()); - assertEquals(blob.length, decoder2.readUnsignedVarint32()); - var bytes = decoder2.readBytes(blob.length); - - assertElementsEquals(bytes, blob); - }); - - - /** - * Tests read callbacks. - */ - it('testReadCallbacks', function() { - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); - - // Add an int, a submessage, and another int. - writer.writeInt32(1, 100); - - writer.writeMessage(2, dummyMessage, function() { - writer.writeInt32(3, 300); - writer.writeInt32(4, 400); - writer.writeInt32(5, 500); - }); - - writer.writeInt32(7, 700); - - // Create the reader and register a custom read callback. - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - /** - * @param {!jspb.BinaryReader} reader - * @return {*} - */ - function readCallback(reader) { - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(300, reader.readInt32()); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(400, reader.readInt32()); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(500, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }; - - reader.registerReadCallback('readCallback', readCallback); - - // Read the container message. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(100, reader.readInt32()); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - // Decode the embedded message using the registered callback. - reader.runReadCallback('readCallback'); - }); - - reader.nextField(); - assertEquals(7, reader.getFieldNumber()); - assertEquals(700, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }); -}); diff --git a/js/compatibility_tests/v3.0.0/binary/utils_test.js b/js/compatibility_tests/v3.0.0/binary/utils_test.js deleted file mode 100644 index abc36aac3..000000000 --- a/js/compatibility_tests/v3.0.0/binary/utils_test.js +++ /dev/null @@ -1,668 +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. - -/** - * @fileoverview Test cases for jspb's helper functions. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.crypt.base64'); -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryWriter'); -goog.require('jspb.utils'); - - -/** - * @param {number} x - * @return {number} - */ -function truncate(x) { - var temp = new Float32Array(1); - temp[0] = x; - return temp[0]; -} - - -/** - * Converts an 64-bit integer in split representation to a 64-bit hash string - * (8 bits encoded per character). - * @param {number} bitsLow The low 32 bits of the split 64-bit integer. - * @param {number} bitsHigh The high 32 bits of the split 64-bit integer. - * @return {string} The encoded hash string, 8 bits per character. - */ -function toHashString(bitsLow, bitsHigh) { - return String.fromCharCode((bitsLow >>> 0) & 0xFF, - (bitsLow >>> 8) & 0xFF, - (bitsLow >>> 16) & 0xFF, - (bitsLow >>> 24) & 0xFF, - (bitsHigh >>> 0) & 0xFF, - (bitsHigh >>> 8) & 0xFF, - (bitsHigh >>> 16) & 0xFF, - (bitsHigh >>> 24) & 0xFF); -} - - -describe('binaryUtilsTest', function() { - /** - * Tests lossless binary-to-decimal conversion. - */ - it('testDecimalConversion', function() { - // Check some magic numbers. - var result = - jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304); - assertEquals('10000000000000000001', result); - - result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b); - assertEquals('123456789123456789', result); - - result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c); - assertEquals('12345678901234567890', result); - - result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8); - assertEquals('9876543210987654321', result); - - // Check limits. - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000); - assertEquals('0', result); - - result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF); - assertEquals('18446744073709551615', result); - - // Check each bit of the low dword. - for (var i = 0; i < 32; i++) { - var low = (1 << i) >>> 0; - result = jspb.utils.joinUnsignedDecimalString(low, 0); - assertEquals('' + Math.pow(2, i), result); - } - - // Check the first 20 bits of the high dword. - for (var i = 0; i < 20; i++) { - var high = (1 << i) >>> 0; - result = jspb.utils.joinUnsignedDecimalString(0, high); - assertEquals('' + Math.pow(2, 32 + i), result); - } - - // V8's internal double-to-string conversion is inaccurate for values above - // 2^52, even if they're representable integers - check the rest of the bits - // manually against the correct string representations of 2^N. - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000); - assertEquals('4503599627370496', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000); - assertEquals('9007199254740992', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000); - assertEquals('18014398509481984', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000); - assertEquals('36028797018963968', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000); - assertEquals('72057594037927936', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000); - assertEquals('144115188075855872', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000); - assertEquals('288230376151711744', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000); - assertEquals('576460752303423488', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000); - assertEquals('1152921504606846976', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000); - assertEquals('2305843009213693952', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000); - assertEquals('4611686018427387904', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000); - assertEquals('9223372036854775808', result); - }); - - - /** - * Going from hash strings to decimal strings should also be lossless. - */ - it('testHashToDecimalConversion', function() { - var result; - var convert = jspb.utils.hash64ToDecimalString; - - result = convert(toHashString(0x00000000, 0x00000000), false); - assertEquals('0', result); - - result = convert(toHashString(0x00000000, 0x00000000), true); - assertEquals('0', result); - - result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false); - assertEquals('18446744073709551615', result); - - result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true); - assertEquals('-1', result); - - result = convert(toHashString(0x00000000, 0x80000000), false); - assertEquals('9223372036854775808', result); - - result = convert(toHashString(0x00000000, 0x80000000), true); - assertEquals('-9223372036854775808', result); - - result = convert(toHashString(0xacd05f15, 0x01b69b4b), false); - assertEquals('123456789123456789', result); - - result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true); - assertEquals('-123456789123456789', result); - - // And converting arrays of hashes should work the same way. - result = jspb.utils.hash64ArrayToDecimalStrings([ - toHashString(0xFFFFFFFF, 0xFFFFFFFF), - toHashString(0x00000000, 0x80000000), - toHashString(0xacd05f15, 0x01b69b4b)], false); - assertEquals(3, result.length); - assertEquals('18446744073709551615', result[0]); - assertEquals('9223372036854775808', result[1]); - assertEquals('123456789123456789', result[2]); - }); - - /* - * Going from decimal strings to hash strings should be lossless. - */ - it('testDecimalToHashConversion', function() { - var result; - var convert = jspb.utils.decimalStringToHash64; - - result = convert('0'); - assertEquals(String.fromCharCode.apply(null, - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result); - - result = convert('-1'); - assertEquals(String.fromCharCode.apply(null, - [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); - - result = convert('18446744073709551615'); - assertEquals(String.fromCharCode.apply(null, - [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); - - result = convert('9223372036854775808'); - assertEquals(String.fromCharCode.apply(null, - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result); - - result = convert('-9223372036854775808'); - assertEquals(String.fromCharCode.apply(null, - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result); - - result = convert('123456789123456789'); - assertEquals(String.fromCharCode.apply(null, - [0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01]), result); - - result = convert('-123456789123456789'); - assertEquals(String.fromCharCode.apply(null, - [0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE]), result); - }); - - /** - * Going from hash strings to hex strings should be lossless. - */ - it('testHashToHexConversion', function() { - var result; - var convert = jspb.utils.hash64ToHexString; - - result = convert(toHashString(0x00000000, 0x00000000)); - assertEquals('0x0000000000000000', result); - - result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF)); - assertEquals('0xffffffffffffffff', result); - - result = convert(toHashString(0x12345678, 0x9ABCDEF0)); - assertEquals('0x9abcdef012345678', result); - }); - - - /** - * Going from hex strings to hash strings should be lossless. - */ - it('testHexToHashConversion', function() { - var result; - var convert = jspb.utils.hexStringToHash64; - - result = convert('0x0000000000000000'); - assertEquals(String.fromCharCode.apply(null, - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result); - - result = convert('0xffffffffffffffff'); - assertEquals(String.fromCharCode.apply(null, - [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); - - // Hex string is big-endian, hash string is little-endian. - result = convert('0x123456789ABCDEF0'); - assertEquals(String.fromCharCode.apply(null, - [0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]), result); - - // Capitalization should not matter. - result = convert('0x0000abcdefABCDEF'); - assertEquals(String.fromCharCode.apply(null, - [0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]), result); - }); - - - /** - * Going from numbers to hash strings should be lossless for up to 53 bits of - * precision. - */ - it('testNumberToHashConversion', function() { - var result; - var convert = jspb.utils.numberToHash64; - - result = convert(0x0000000000000); - assertEquals('0x0000000000000000', jspb.utils.hash64ToHexString(result)); - - result = convert(0xFFFFFFFFFFFFF); - assertEquals('0x000fffffffffffff', jspb.utils.hash64ToHexString(result)); - - result = convert(0x123456789ABCD); - assertEquals('0x000123456789abcd', jspb.utils.hash64ToHexString(result)); - - result = convert(0xDCBA987654321); - assertEquals('0x000dcba987654321', jspb.utils.hash64ToHexString(result)); - - // 53 bits of precision should not be truncated. - result = convert(0x10000000000001); - assertEquals('0x0010000000000001', jspb.utils.hash64ToHexString(result)); - - // 54 bits of precision should be truncated. - result = convert(0x20000000000001); - assertNotEquals( - '0x0020000000000001', jspb.utils.hash64ToHexString(result)); - }); - - - /** - * Sanity check the behavior of Javascript's strings when doing funny things - * with unicode characters. - */ - it('sanityCheckUnicodeStrings', function() { - var strings = new Array(65536); - - // All possible unsigned 16-bit values should be storable in a string, they - // shouldn't do weird things with the length of the string, and they should - // come back out of the string unchanged. - for (var i = 0; i < 65536; i++) { - strings[i] = 'a' + String.fromCharCode(i) + 'a'; - if (3 != strings[i].length) throw 'fail!'; - if (i != strings[i].charCodeAt(1)) throw 'fail!'; - } - - // Each unicode character should compare equal to itself and not equal to a - // different unicode character. - for (var i = 0; i < 65536; i++) { - if (strings[i] != strings[i]) throw 'fail!'; - if (strings[i] == strings[(i + 1) % 65536]) throw 'fail!'; - } - }); - - - /** - * Tests conversion from 32-bit floating point numbers to split64 numbers. - */ - it('testFloat32ToSplit64', function() { - var f32_eps = jspb.BinaryConstants.FLOAT32_EPS; - var f32_min = jspb.BinaryConstants.FLOAT32_MIN; - var f32_max = jspb.BinaryConstants.FLOAT32_MAX; - - // NaN. - jspb.utils.splitFloat32(NaN); - if (!isNaN(jspb.utils.joinFloat32(jspb.utils.split64Low, - jspb.utils.split64High))) { - throw 'fail!'; - } - - /** - * @param {number} x - * @param {number=} opt_bits - */ - function test(x, opt_bits) { - jspb.utils.splitFloat32(x); - if (opt_bits !== undefined) { - if (opt_bits != jspb.utils.split64Low) throw 'fail!'; - } - if (truncate(x) != jspb.utils.joinFloat32(jspb.utils.split64Low, - jspb.utils.split64High)) { - throw 'fail!'; - } - } - - // Positive and negative infinity. - test(Infinity, 0x7f800000); - test(-Infinity, 0xff800000); - - // Positive and negative zero. - test(0, 0x00000000); - test(-0, 0x80000000); - - // Positive and negative epsilon. - test(f32_eps, 0x00000001); - test(-f32_eps, 0x80000001); - - // Positive and negative min. - test(f32_min, 0x00800000); - test(-f32_min, 0x80800000); - - // Positive and negative max. - test(f32_max, 0x7F7FFFFF); - test(-f32_max, 0xFF7FFFFF); - - // Various positive values. - var cursor = f32_eps * 10; - while (cursor != Infinity) { - test(cursor); - cursor *= 1.1; - } - - // Various negative values. - cursor = -f32_eps * 10; - while (cursor != -Infinity) { - test(cursor); - cursor *= 1.1; - } - }); - - - /** - * Tests conversion from 64-bit floating point numbers to split64 numbers. - */ - it('testFloat64ToSplit64', function() { - var f64_eps = jspb.BinaryConstants.FLOAT64_EPS; - var f64_min = jspb.BinaryConstants.FLOAT64_MIN; - var f64_max = jspb.BinaryConstants.FLOAT64_MAX; - - // NaN. - jspb.utils.splitFloat64(NaN); - if (!isNaN(jspb.utils.joinFloat64(jspb.utils.split64Low, - jspb.utils.split64High))) { - throw 'fail!'; - } - - /** - * @param {number} x - * @param {number=} opt_highBits - * @param {number=} opt_lowBits - */ - function test(x, opt_highBits, opt_lowBits) { - jspb.utils.splitFloat64(x); - if (opt_highBits !== undefined) { - if (opt_highBits != jspb.utils.split64High) throw 'fail!'; - } - if (opt_lowBits !== undefined) { - if (opt_lowBits != jspb.utils.split64Low) throw 'fail!'; - } - if (x != jspb.utils.joinFloat64(jspb.utils.split64Low, - jspb.utils.split64High)) { - throw 'fail!'; - } - } - - // Positive and negative infinity. - test(Infinity, 0x7ff00000, 0x00000000); - test(-Infinity, 0xfff00000, 0x00000000); - - // Positive and negative zero. - test(0, 0x00000000, 0x00000000); - test(-0, 0x80000000, 0x00000000); - - // Positive and negative epsilon. - test(f64_eps, 0x00000000, 0x00000001); - test(-f64_eps, 0x80000000, 0x00000001); - - // Positive and negative min. - test(f64_min, 0x00100000, 0x00000000); - test(-f64_min, 0x80100000, 0x00000000); - - // Positive and negative max. - test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF); - test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF); - - // Various positive values. - var cursor = f64_eps * 10; - while (cursor != Infinity) { - test(cursor); - cursor *= 1.1; - } - - // Various negative values. - cursor = -f64_eps * 10; - while (cursor != -Infinity) { - test(cursor); - cursor *= 1.1; - } - }); - - - /** - * Tests counting packed varints. - */ - it('testCountVarints', function() { - var values = []; - for (var i = 1; i < 1000000000; i *= 1.1) { - values.push(Math.floor(i)); - } - - var writer = new jspb.BinaryWriter(); - writer.writePackedUint64(1, values); - - var buffer = new Uint8Array(writer.getResultBuffer()); - - // We should have two more varints than we started with - one for the field - // tag, one for the packed length. - assertEquals(values.length + 2, - jspb.utils.countVarints(buffer, 0, buffer.length)); - }); - - - /** - * Tests counting matching varint fields. - */ - it('testCountVarintFields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeUint64(1, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countVarintFields(buffer, 0, buffer.length, 1)); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeUint64(123456789, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789)); - }); - - - /** - * Tests counting matching fixed32 fields. - */ - it('testCountFixed32Fields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeFixed32(1, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1)); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeFixed32(123456789, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789)); - }); - - - /** - * Tests counting matching fixed64 fields. - */ - it('testCountFixed64Fields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeDouble(1, i); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1)); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeDouble(123456789, i); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789)); - }); - - - /** - * Tests counting matching delimited fields. - */ - it('testCountDelimitedFields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000; i *= 1.1) { - writer.writeBytes(1, [Math.floor(i)]); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1)); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000; i *= 1.1) { - writer.writeBytes(123456789, [Math.floor(i)]); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789)); - }); - - - /** - * Tests byte format for debug strings. - */ - it('testDebugBytesToTextFormat', function() { - assertEquals('""', jspb.utils.debugBytesToTextFormat(null)); - assertEquals('"\\x00\\x10\\xff"', - jspb.utils.debugBytesToTextFormat([0, 16, 255])); - }); - - - /** - * Tests converting byte blob sources into byte blobs. - */ - it('testByteSourceToUint8Array', function() { - var convert = jspb.utils.byteSourceToUint8Array; - - var sourceData = []; - for (var i = 0; i < 256; i++) { - sourceData.push(i); - } - - var sourceBytes = new Uint8Array(sourceData); - var sourceBuffer = sourceBytes.buffer; - var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData); - var sourceString = String.fromCharCode.apply(null, sourceData); - - function check(result) { - assertEquals(Uint8Array, result.constructor); - assertEquals(sourceData.length, result.length); - for (var i = 0; i < result.length; i++) { - assertEquals(sourceData[i], result[i]); - } - } - - // Converting Uint8Arrays into Uint8Arrays should be a no-op. - assertEquals(sourceBytes, convert(sourceBytes)); - - // Converting Array. into Uint8Arrays should work. - check(convert(sourceData)); - - // Converting ArrayBuffers into Uint8Arrays should work. - check(convert(sourceBuffer)); - - // Converting base64-encoded strings into Uint8Arrays should work. - check(convert(sourceBase64)); - }); -}); diff --git a/js/compatibility_tests/v3.0.0/binary/writer_test.js b/js/compatibility_tests/v3.0.0/binary/writer_test.js deleted file mode 100644 index f896c3b38..000000000 --- a/js/compatibility_tests/v3.0.0/binary/writer_test.js +++ /dev/null @@ -1,122 +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. - -/** - * @fileoverview Test cases for jspb's binary protocol buffer writer. In - * practice BinaryWriter is used to drive the Decoder and Reader test cases, - * so only writer-specific tests are here. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.crypt'); -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryWriter'); - - -/** - * @param {function()} func This function should throw an error when run. - */ -function assertFails(func) { - var e = assertThrows(func); - //assertNotNull(e.toString().match(/Error/)); -} - - -describe('binaryWriterTest', function() { - /** - * Verifies that misuse of the writer class triggers assertions. - */ - it('testWriteErrors', function() { - // Submessages with invalid field indices should assert. - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); - - assertFails(function() { - writer.writeMessage(-1, dummyMessage, () => {}); - }); - - // Writing invalid field indices should assert. - writer = new jspb.BinaryWriter(); - assertFails(function() {writer.writeUint64(-1, 1);}); - - // Writing out-of-range field values should assert. - writer = new jspb.BinaryWriter(); - - assertFails(function() {writer.writeInt32(1, -Infinity);}); - assertFails(function() {writer.writeInt32(1, Infinity);}); - - assertFails(function() {writer.writeInt64(1, -Infinity);}); - assertFails(function() {writer.writeInt64(1, Infinity);}); - - assertFails(function() {writer.writeUint32(1, -1);}); - assertFails(function() {writer.writeUint32(1, Infinity);}); - - assertFails(function() {writer.writeUint64(1, -1);}); - assertFails(function() {writer.writeUint64(1, Infinity);}); - - assertFails(function() {writer.writeSint32(1, -Infinity);}); - assertFails(function() {writer.writeSint32(1, Infinity);}); - - assertFails(function() {writer.writeSint64(1, -Infinity);}); - assertFails(function() {writer.writeSint64(1, Infinity);}); - - assertFails(function() {writer.writeFixed32(1, -1);}); - assertFails(function() {writer.writeFixed32(1, Infinity);}); - - assertFails(function() {writer.writeFixed64(1, -1);}); - assertFails(function() {writer.writeFixed64(1, Infinity);}); - - assertFails(function() {writer.writeSfixed32(1, -Infinity);}); - assertFails(function() {writer.writeSfixed32(1, Infinity);}); - - assertFails(function() {writer.writeSfixed64(1, -Infinity);}); - assertFails(function() {writer.writeSfixed64(1, Infinity);}); - }); - - - /** - * Basic test of retrieving the result as a Uint8Array buffer - */ - it('testGetResultBuffer', function() { - var expected = '0864120b48656c6c6f20776f726c641a0301020320c801'; - - var writer = new jspb.BinaryWriter(); - writer.writeUint32(1, 100); - writer.writeString(2, 'Hello world'); - writer.writeBytes(3, new Uint8Array([1, 2, 3])); - writer.writeUint32(4, 200); - - var buffer = writer.getResultBuffer(); - assertEquals(expected, goog.crypt.byteArrayToHex(buffer)); - }); -}); diff --git a/js/compatibility_tests/v3.0.0/commonjs/export_asserts.js b/js/compatibility_tests/v3.0.0/commonjs/export_asserts.js deleted file mode 100644 index 5219d120c..000000000 --- a/js/compatibility_tests/v3.0.0/commonjs/export_asserts.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @fileoverview Exports symbols needed only by tests. - * - * This file exports several Closure Library symbols that are only - * used by tests. It is used to generate a file - * closure_asserts_commonjs.js that is only used at testing time. - */ - -goog.require('goog.testing.asserts'); - -var global = Function('return this')(); - -// All of the closure "assert" functions are exported at the global level. -// -// The Google Closure assert functions start with assert, eg. -// assertThrows -// assertNotThrows -// assertTrue -// ... -// -// The one exception is the "fail" function. -function shouldExport(str) { - return str.lastIndexOf('assert') === 0 || str == 'fail'; -} - -for (var key in global) { - if ((typeof key == "string") && global.hasOwnProperty(key) && - shouldExport(key)) { - exports[key] = global[key]; - } -} - -// The COMPILED variable is set by Closure compiler to "true" when it compiles -// JavaScript, so in practice this is equivalent to "exports.COMPILED = true". -// This will disable some debugging functionality in debug.js. We could -// investigate whether this can/should be enabled in CommonJS builds. -exports.COMPILED = COMPILED diff --git a/js/compatibility_tests/v3.0.0/commonjs/export_testdeps.js b/js/compatibility_tests/v3.0.0/commonjs/export_testdeps.js deleted file mode 100644 index 59c77ca2c..000000000 --- a/js/compatibility_tests/v3.0.0/commonjs/export_testdeps.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @fileoverview Export symbols needed by tests in CommonJS style. - * - * This file is like export.js, but for symbols that are only used by tests. - * However we exclude assert functions here, because they are exported into - * the global namespace, so those are handled as a special case in - * export_asserts.js. - */ - -goog.require('goog.crypt.base64'); -goog.require('jspb.arith.Int64'); -goog.require('jspb.arith.UInt64'); -goog.require('jspb.BinaryEncoder'); -goog.require('jspb.BinaryDecoder'); -goog.require('jspb.utils'); - -exports.goog = goog; -exports.jspb = jspb; diff --git a/js/compatibility_tests/v3.0.0/commonjs/import_test.js b/js/compatibility_tests/v3.0.0/commonjs/import_test.js deleted file mode 100644 index ffa34fea6..000000000 --- a/js/compatibility_tests/v3.0.0/commonjs/import_test.js +++ /dev/null @@ -1,52 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2016 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - - - -var googleProtobuf = require('google-protobuf'); -var asserts = require('closure_asserts_commonjs'); -var global = Function('return this')(); - -// Bring asserts into the global namespace. -googleProtobuf.object.extend(global, asserts); -googleProtobuf.exportSymbol('jspb.Message', googleProtobuf.Message, global); - -var test7_pb = require('./test7/test7_pb'); -googleProtobuf.exportSymbol('proto.jspb.test.framing.FramingMessage', test7_pb.FramingMessage, global); - -describe('Import test suite', function() { - it('testImportedMessage', function() { - var framing1 = new proto.jspb.test.framing.FramingMessage([]); - var framing2 = new proto.jspb.test.framing.FramingMessage([]); - assertObjectEquals(framing1.toObject(), framing2.toObject()); - }); -}); diff --git a/js/compatibility_tests/v3.0.0/commonjs/jasmine.json b/js/compatibility_tests/v3.0.0/commonjs/jasmine.json deleted file mode 100644 index 666b8edbf..000000000 --- a/js/compatibility_tests/v3.0.0/commonjs/jasmine.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "spec_dir": "", - "spec_files": [ - "*_test.js", - "binary/proto_test.js" - ], - "helpers": [ - ] -} diff --git a/js/compatibility_tests/v3.0.0/commonjs/rewrite_tests_for_commonjs.js b/js/compatibility_tests/v3.0.0/commonjs/rewrite_tests_for_commonjs.js deleted file mode 100644 index b6d90d287..000000000 --- a/js/compatibility_tests/v3.0.0/commonjs/rewrite_tests_for_commonjs.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @fileoverview Utility to translate test files to CommonJS imports. - * - * This is a somewhat hacky tool designed to do one very specific thing. - * All of the test files in *_test.js are written with Closure-style - * imports (goog.require()). This works great for running the tests - * against Closure-style generated code, but we also want to run the - * tests against CommonJS-style generated code without having to fork - * the tests. - * - * Closure-style imports import each individual type by name. This is - * very different than CommonJS imports which are by file. So we put - * special comments in these tests like: - * - * // CommonJS-LoadFromFile: test_pb - * goog.require('proto.jspb.test.CloneExtension'); - * goog.require('proto.jspb.test.Complex'); - * goog.require('proto.jspb.test.DefaultValues'); - * - * This script parses that special comment and uses it to generate proper - * CommonJS require() statements so that the tests can run and pass using - * CommonJS imports. The script will change the above statements into: - * - * var test_pb = require('test_pb'); - * googleProtobuf.exportSymbol('proto.jspb.test.CloneExtension', test_pb.CloneExtension, global); - * googleProtobuf.exportSymbol('proto.jspb.test.Complex', test_pb.Complex, global); - * googleProtobuf.exportSymbol('proto.jspb.test.DefaultValues', test_pb.DefaultValues, global); - * - * (The "exportSymbol" function will define the given names in the global - * namespace, taking care not to overwrite any previous value for - * "proto.jspb.test"). - */ - -var lineReader = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}); - -function tryStripPrefix(str, prefix) { - if (str.lastIndexOf(prefix) !== 0) { - throw "String: " + str + " didn't start with: " + prefix; - } - return str.substr(prefix.length); -} - -function camelCase(str) { - var ret = ''; - var ucaseNext = false; - for (var i = 0; i < str.length; i++) { - if (str[i] == '-') { - ucaseNext = true; - } else if (ucaseNext) { - ret += str[i].toUpperCase(); - ucaseNext = false; - } else { - ret += str[i]; - } - } - return ret; -} - -var module = null; -var pkg = null; - -// Header: goes in every file at the top. -console.log("var global = Function('return this')();"); -console.log("var googleProtobuf = require('google-protobuf');"); -console.log("var testdeps = require('testdeps_commonjs');"); -console.log("global.goog = testdeps.goog;"); -console.log("global.jspb = testdeps.jspb;"); -console.log("var asserts = require('closure_asserts_commonjs');"); -console.log(""); -console.log("// Bring asserts into the global namespace."); -console.log("googleProtobuf.object.extend(global, asserts);"); - -lineReader.on('line', function(line) { - var isRequire = line.match(/goog\.require\('([^']*)'\)/); - var isLoadFromFile = line.match(/CommonJS-LoadFromFile: (\S*) (.*)/); - var isSetTestOnly = line.match(/goog.setTestOnly()/); - if (isRequire) { - if (module) { // Skip goog.require() lines before the first directive. - var fullSym = isRequire[1]; - var sym = tryStripPrefix(fullSym, pkg); - console.log("googleProtobuf.exportSymbol('" + fullSym + "', " + module + sym + ', global);'); - } - } else if (isLoadFromFile) { - var module_path = isLoadFromFile[1].split('/'); - module = camelCase(module_path[module_path.length - 1]); - pkg = isLoadFromFile[2]; - - if (module != "googleProtobuf") { // We unconditionally require this in the header. - console.log("var " + module + " = require('./" + isLoadFromFile[1] + "');"); - } - } else if (!isSetTestOnly) { // Remove goog.setTestOnly() lines. - console.log(line); - } -}); diff --git a/js/compatibility_tests/v3.0.0/commonjs/test6/test6.proto b/js/compatibility_tests/v3.0.0/commonjs/test6/test6.proto deleted file mode 100644 index a060925f2..000000000 --- a/js/compatibility_tests/v3.0.0/commonjs/test6/test6.proto +++ /dev/null @@ -1,40 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2016 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test.importing; - -message ImportedMessage { - string string_value = 1; -} diff --git a/js/compatibility_tests/v3.0.0/commonjs/test7/test7.proto b/js/compatibility_tests/v3.0.0/commonjs/test7/test7.proto deleted file mode 100644 index f5574a3dd..000000000 --- a/js/compatibility_tests/v3.0.0/commonjs/test7/test7.proto +++ /dev/null @@ -1,42 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2016 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test.framing; - -import "test6/test6.proto"; - -message FramingMessage { - jspb.test.importing.ImportedMessage imported_message = 1; -} diff --git a/js/compatibility_tests/v3.0.0/data.proto b/js/compatibility_tests/v3.0.0/data.proto deleted file mode 100644 index 74a8a994c..000000000 --- a/js/compatibility_tests/v3.0.0/data.proto +++ /dev/null @@ -1,51 +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: mwr@google.com (Mark Rawling) - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test; - -// legacy data, must be nested -message data { - message NestedData { - required string str = 1; - } -} - -// new data, does not require nesting -message UnnestedData { - required string str = 1; -} - diff --git a/js/compatibility_tests/v3.0.0/debug_test.js b/js/compatibility_tests/v3.0.0/debug_test.js deleted file mode 100644 index 01cbf891a..000000000 --- a/js/compatibility_tests/v3.0.0/debug_test.js +++ /dev/null @@ -1,105 +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. - -goog.setTestOnly(); - -goog.require('goog.testing.asserts'); - -// CommonJS-LoadFromFile: google-protobuf -goog.require('jspb.debug'); - -// CommonJS-LoadFromFile: test_pb -goog.require('proto.jspb.test.HasExtensions'); -goog.require('proto.jspb.test.IsExtension'); -goog.require('proto.jspb.test.Simple1'); - - - -describe('debugTest', function() { - it('testSimple1', function() { - if (COMPILED) { - return; - } - var message = new proto.jspb.test.Simple1(); - message.setAString('foo'); - assertObjectEquals({ - $name: 'proto.jspb.test.Simple1', - 'aString': 'foo', - 'aRepeatedStringList': [] - }, jspb.debug.dump(message)); - - message.setABoolean(true); - message.setARepeatedStringList(['1', '2']); - - assertObjectEquals({ - $name: 'proto.jspb.test.Simple1', - 'aString': 'foo', - 'aRepeatedStringList': ['1', '2'], - 'aBoolean': true - }, jspb.debug.dump(message)); - - message.setAString(undefined); - - assertObjectEquals({ - $name: 'proto.jspb.test.Simple1', - 'aRepeatedStringList': ['1', '2'], - 'aBoolean': true - }, jspb.debug.dump(message)); - }); - - - it('testExtensions', function() { - if (COMPILED) { - return; - } - var extension = new proto.jspb.test.IsExtension(); - extension.setExt1('ext1field'); - var extendable = new proto.jspb.test.HasExtensions(); - extendable.setStr1('v1'); - extendable.setStr2('v2'); - extendable.setStr3('v3'); - extendable.setExtension(proto.jspb.test.IsExtension.extField, extension); - - assertObjectEquals({ - '$name': 'proto.jspb.test.HasExtensions', - 'str1': 'v1', - 'str2': 'v2', - 'str3': 'v3', - '$extensions': { - 'extField': { - '$name': 'proto.jspb.test.IsExtension', - 'ext1': 'ext1field' - }, - 'repeatedSimpleList': [] - } - }, jspb.debug.dump(extendable)); - }); - -}); diff --git a/js/compatibility_tests/v3.0.0/jasmine1.json b/js/compatibility_tests/v3.0.0/jasmine1.json deleted file mode 100644 index 6653c01cc..000000000 --- a/js/compatibility_tests/v3.0.0/jasmine1.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "spec_dir": "", - "spec_files": [ - "*_test.js", - "binary/*_test.js" - ], - "helpers": [ - "../../../js/node_modules/google-closure-library/closure/goog/bootstrap/nodejs.js", - "../../../js/node_loader.js", - "../../../js/deps.js", - "../../../js/google/protobuf/any.js", - "../../../js/google/protobuf/struct.js", - "../../../js/google/protobuf/timestamp.js", - "testproto_libs1.js", - "testproto_libs2.js" - ] -} diff --git a/js/compatibility_tests/v3.0.0/jasmine2.json b/js/compatibility_tests/v3.0.0/jasmine2.json deleted file mode 100644 index 3208078f7..000000000 --- a/js/compatibility_tests/v3.0.0/jasmine2.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "spec_dir": "", - "spec_files": [ - "*_test.js", - "binary/*_test.js" - ], - "helpers": [ - "../../../js/node_modules/google-closure-library/closure/goog/bootstrap/nodejs.js", - "../../../js/node_loader.js", - "../../../js/deps.js", - "../../../js/google/protobuf/any.js", - "../../../js/google/protobuf/struct.js", - "../../../js/google/protobuf/timestamp.js", - "testproto_libs1_new.js", - "testproto_libs2.js" - ] -} diff --git a/js/compatibility_tests/v3.0.0/jasmine3.json b/js/compatibility_tests/v3.0.0/jasmine3.json deleted file mode 100644 index 3fb9a1b01..000000000 --- a/js/compatibility_tests/v3.0.0/jasmine3.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "spec_dir": "", - "spec_files": [ - "*_test.js", - "binary/*_test.js" - ], - "helpers": [ - "../../../js/node_modules/google-closure-library/closure/goog/bootstrap/nodejs.js", - "../../../js/node_loader.js", - "../../../js/deps.js", - "../../../js/google/protobuf/any.js", - "../../../js/google/protobuf/struct.js", - "../../../js/google/protobuf/timestamp.js", - "testproto_libs1.js", - "testproto_libs2_new.js" - ] -} diff --git a/js/compatibility_tests/v3.0.0/message_test.js b/js/compatibility_tests/v3.0.0/message_test.js deleted file mode 100644 index 79a12e09c..000000000 --- a/js/compatibility_tests/v3.0.0/message_test.js +++ /dev/null @@ -1,1081 +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. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - -goog.setTestOnly(); - -goog.require('goog.json'); -goog.require('goog.testing.asserts'); -goog.require('goog.userAgent'); - -// CommonJS-LoadFromFile: google-protobuf jspb -goog.require('jspb.Message'); - -// CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta -goog.require('proto.jspb.exttest.beta.floatingStrField'); - -// CommonJS-LoadFromFile: test3_pb proto.jspb.exttest -goog.require('proto.jspb.exttest.floatingMsgField'); - -// CommonJS-LoadFromFile: test4_pb proto.jspb.exttest -goog.require('proto.jspb.exttest.floatingMsgFieldTwo'); - -// CommonJS-LoadFromFile: test_pb proto.jspb.test -goog.require('proto.jspb.test.CloneExtension'); -goog.require('proto.jspb.test.Complex'); -goog.require('proto.jspb.test.DefaultValues'); -goog.require('proto.jspb.test.Empty'); -goog.require('proto.jspb.test.EnumContainer'); -goog.require('proto.jspb.test.floatingMsgField'); -goog.require('proto.jspb.test.FloatingPointFields'); -goog.require('proto.jspb.test.floatingStrField'); -goog.require('proto.jspb.test.HasExtensions'); -goog.require('proto.jspb.test.IndirectExtension'); -goog.require('proto.jspb.test.IsExtension'); -goog.require('proto.jspb.test.OptionalFields'); -goog.require('proto.jspb.test.OuterEnum'); -goog.require('proto.jspb.test.OuterMessage.Complex'); -goog.require('proto.jspb.test.Simple1'); -goog.require('proto.jspb.test.Simple2'); -goog.require('proto.jspb.test.SpecialCases'); -goog.require('proto.jspb.test.TestClone'); -goog.require('proto.jspb.test.TestEndsWithBytes'); -goog.require('proto.jspb.test.TestGroup'); -goog.require('proto.jspb.test.TestGroup1'); -goog.require('proto.jspb.test.TestMessageWithOneof'); -goog.require('proto.jspb.test.TestReservedNames'); -goog.require('proto.jspb.test.TestReservedNamesExtension'); - -// CommonJS-LoadFromFile: test2_pb proto.jspb.test -goog.require('proto.jspb.test.ExtensionMessage'); -goog.require('proto.jspb.test.TestExtensionsMessage'); - - - - -describe('Message test suite', function() { - it('testEmptyProto', function() { - var empty1 = new proto.jspb.test.Empty([]); - var empty2 = new proto.jspb.test.Empty([]); - assertObjectEquals({}, empty1.toObject()); - assertObjectEquals('Message should not be corrupted:', empty2, empty1); - }); - - it('testTopLevelEnum', function() { - var response = new proto.jspb.test.EnumContainer([]); - response.setOuterEnum(proto.jspb.test.OuterEnum.FOO); - assertEquals(proto.jspb.test.OuterEnum.FOO, response.getOuterEnum()); - }); - - it('testByteStrings', function() { - var data = new proto.jspb.test.DefaultValues([]); - data.setBytesField('some_bytes'); - assertEquals('some_bytes', data.getBytesField()); - }); - - it('testComplexConversion', function() { - var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1]; - var data2 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1]; - var foo = new proto.jspb.test.Complex(data1); - var bar = new proto.jspb.test.Complex(data2); - var result = foo.toObject(); - assertObjectEquals({ - aString: 'a', - anOutOfOrderBool: 1, - aNestedMessage: { - anInt: 11 - }, - aRepeatedMessageList: [{anInt: 22}, {anInt: 33}], - aRepeatedStringList: ['s1', 's2'] - }, result); - - // Now test with the jspb instances included. - result = foo.toObject(true /* opt_includeInstance */); - assertObjectEquals({ - aString: 'a', - anOutOfOrderBool: 1, - aNestedMessage: { - anInt: 11, - $jspbMessageInstance: foo.getANestedMessage() - }, - aRepeatedMessageList: [ - {anInt: 22, $jspbMessageInstance: foo.getARepeatedMessageList()[0]}, - {anInt: 33, $jspbMessageInstance: foo.getARepeatedMessageList()[1]} - ], - aRepeatedStringList: ['s1', 's2'], - $jspbMessageInstance: foo - }, result); - - }); - - it('testMissingFields', function() { - var foo = new proto.jspb.test.Complex([ - undefined, undefined, undefined, [], - undefined, undefined, undefined, undefined]); - var bar = new proto.jspb.test.Complex([ - undefined, undefined, undefined, [], - undefined, undefined, undefined, undefined]); - var result = foo.toObject(); - assertObjectEquals({ - aString: undefined, - anOutOfOrderBool: undefined, - aNestedMessage: { - anInt: undefined - }, - // Note: JsPb converts undefined repeated fields to empty arrays. - aRepeatedMessageList: [], - aRepeatedStringList: [] - }, result); - - }); - - it('testNestedComplexMessage', function() { - // Instantiate the message and set a unique field, just to ensure that we - // are not getting jspb.test.Complex instead. - var msg = new proto.jspb.test.OuterMessage.Complex(); - msg.setInnerComplexField(5); - }); - - it('testSpecialCases', function() { - // Note: Some property names are reserved in JavaScript. - // These names are converted to the Js property named pb_. - var special = - new proto.jspb.test.SpecialCases(['normal', 'default', 'function', - 'var']); - var result = special.toObject(); - assertObjectEquals({ - normal: 'normal', - pb_default: 'default', - pb_function: 'function', - pb_var: 'var' - }, result); - }); - - it('testDefaultValues', function() { - var defaultString = "default<>\'\"abc"; - var response = new proto.jspb.test.DefaultValues(); - - // Test toObject - var expectedObject = { - stringField: defaultString, - boolField: true, - intField: 11, - enumField: 13, - emptyField: '', - bytesField: 'bW9v' - }; - assertObjectEquals(expectedObject, response.toObject()); - - - // Test getters - response = new proto.jspb.test.DefaultValues(); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertEquals('', response.getEmptyField()); - assertEquals('bW9v', response.getBytesField()); - - function makeDefault(values) { - return new proto.jspb.test.DefaultValues(values); - } - - // Test with undefined values, - // Use push to workaround IE treating undefined array elements as holes. - response = makeDefault([undefined, undefined, undefined, undefined]); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - - // Test with null values, as would be returned by a JSON serializer. - response = makeDefault([null, null, null, null]); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - - // Test with false-like values. - response = makeDefault(['', false, 0, 0]); - assertEquals('', response.getStringField()); - assertEquals(false, response.getBoolField()); - assertEquals(true, response.getIntField() == 0); - assertEquals(true, response.getEnumField() == 0); - assertTrue(response.hasStringField()); - assertTrue(response.hasBoolField()); - assertTrue(response.hasIntField()); - assertTrue(response.hasEnumField()); - - // Test that clearing the values reverts them to the default state. - response = makeDefault(['blah', false, 111, 77]); - response.clearStringField(); response.clearBoolField(); - response.clearIntField(); response.clearEnumField(); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - - // Test that setFoo(null) clears the values. - response = makeDefault(['blah', false, 111, 77]); - response.setStringField(null); response.setBoolField(null); - response.setIntField(undefined); response.setEnumField(undefined); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - }); - - it('testMessageRegistration', function() { - // goog.require(SomeResponse) will include its library, which will in - // turn add SomeResponse to the message registry. - assertEquals(jspb.Message.registry_['res'], proto.jspb.test.SomeResponse); - }); - - it('testClearFields', function() { - var data = ['str', true, [11], [[22], [33]], ['s1', 's2']]; - var foo = new proto.jspb.test.OptionalFields(data); - foo.clearAString(); - foo.clearABool(); - foo.clearANestedMessage(); - foo.clearARepeatedMessageList(); - foo.clearARepeatedStringList(); - assertEquals('', foo.getAString()); - assertEquals(false, foo.getABool()); - assertUndefined(foo.getANestedMessage()); - assertFalse(foo.hasAString()); - assertFalse(foo.hasABool()); - assertObjectEquals([], foo.getARepeatedMessageList()); - assertObjectEquals([], foo.getARepeatedStringList()); - // NOTE: We want the missing fields in 'expected' to be undefined, - // but we actually get a sparse array instead. We could use something - // like [1,undefined,2] to avoid this, except that this is still - // sparse on IE. No comment... - var expected = [,,, [], []]; - expected[0] = expected[1] = expected[2] = undefined; - assertObjectEquals(expected, foo.toArray()); - - // Test set(null). We could deprecated this in favor of clear(), but - // it's also convenient to have. - data = ['str', true, [11], [[22], [33]], ['s1', 's2']]; - foo = new proto.jspb.test.OptionalFields(data); - foo.setAString(null); - foo.setABool(null); - foo.setANestedMessage(null); - foo.setARepeatedMessageList(null); - foo.setARepeatedStringList(null); - assertEquals('', foo.getAString()); - assertEquals(false, foo.getABool()); - assertNull(foo.getANestedMessage()); - assertFalse(foo.hasAString()); - assertFalse(foo.hasABool()); - assertObjectEquals([], foo.getARepeatedMessageList()); - assertObjectEquals([], foo.getARepeatedStringList()); - assertObjectEquals([null, null, null, [], []], foo.toArray()); - - // Test set(undefined). Again, not something we really need, and not - // supported directly by our typing, but it should 'do the right thing'. - data = ['str', true, [11], [[22], [33]], ['s1', 's2']]; - foo = new proto.jspb.test.OptionalFields(data); - foo.setAString(undefined); - foo.setABool(undefined); - foo.setANestedMessage(undefined); - foo.setARepeatedMessageList(undefined); - foo.setARepeatedStringList(undefined); - assertEquals('', foo.getAString()); - assertEquals(false, foo.getABool()); - assertUndefined(foo.getANestedMessage()); - assertFalse(foo.hasAString()); - assertFalse(foo.hasABool()); - assertObjectEquals([], foo.getARepeatedMessageList()); - assertObjectEquals([], foo.getARepeatedStringList()); - expected = [,,, [], []]; - expected[0] = expected[1] = expected[2] = undefined; - assertObjectEquals(expected, foo.toArray()); - }); - - it('testDifferenceRawObject', function() { - var p1 = new proto.jspb.test.HasExtensions(['hi', 'diff', {}]); - var p2 = new proto.jspb.test.HasExtensions(['hi', 'what', - {1000: 'unique'}]); - var diff = /** @type {proto.jspb.test.HasExtensions} */ - (jspb.Message.difference(p1, p2)); - assertEquals('', diff.getStr1()); - assertEquals('what', diff.getStr2()); - assertEquals('', diff.getStr3()); - assertEquals('unique', diff.extensionObject_[1000]); - }); - - it('testEqualsSimple', function() { - var s1 = new proto.jspb.test.Simple1(['hi']); - assertTrue(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi']))); - assertFalse(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['bye']))); - var s1b = new proto.jspb.test.Simple1(['hi', ['hello']]); - assertTrue(jspb.Message.equals(s1b, - new proto.jspb.test.Simple1(['hi', ['hello']]))); - assertTrue(jspb.Message.equals(s1b, - new proto.jspb.test.Simple1(['hi', ['hello', undefined, - undefined, undefined]]))); - assertFalse(jspb.Message.equals(s1b, - new proto.jspb.test.Simple1(['no', ['hello']]))); - // Test with messages of different types - var s2 = new proto.jspb.test.Simple2(['hi']); - assertFalse(jspb.Message.equals(s1, s2)); - }); - - it('testEquals_softComparison', function() { - var s1 = new proto.jspb.test.Simple1(['hi', [], null]); - assertTrue(jspb.Message.equals(s1, - new proto.jspb.test.Simple1(['hi', []]))); - - var s1b = new proto.jspb.test.Simple1(['hi', [], true]); - assertTrue(jspb.Message.equals(s1b, - new proto.jspb.test.Simple1(['hi', [], 1]))); - }); - - it('testEqualsComplex', function() { - var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1]; - var data2 = ['a',,, [, 11], [[, 22], [, 34]],, ['s1', 's2'],, 1]; - var data3 = ['a',,, [, 11], [[, 22]],, ['s1', 's2'],, 1]; - var data4 = ['hi']; - var c1a = new proto.jspb.test.Complex(data1); - var c1b = new proto.jspb.test.Complex(data1); - var c2 = new proto.jspb.test.Complex(data2); - var c3 = new proto.jspb.test.Complex(data3); - var s1 = new proto.jspb.test.Simple1(data4); - - assertTrue(jspb.Message.equals(c1a, c1b)); - assertFalse(jspb.Message.equals(c1a, c2)); - assertFalse(jspb.Message.equals(c2, c3)); - assertFalse(jspb.Message.equals(c1a, s1)); - }); - - it('testEqualsExtensionsConstructed', function() { - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([]), - new proto.jspb.test.HasExtensions([{}]) - )); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]) - )); - assertFalse(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}]) - )); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]) - )); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}]) - )); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]) - )); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}]) - )); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]) - )); - }); - - it('testEqualsExtensionsUnconstructed', function() { - assertTrue(jspb.Message.compareFields([], [{}])); - assertTrue(jspb.Message.compareFields([,,, {}], [])); - assertTrue(jspb.Message.compareFields([,,, {}], [,, {}])); - assertTrue(jspb.Message.compareFields( - ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}])); - assertFalse(jspb.Message.compareFields( - ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'b'}]}])); - assertTrue(jspb.Message.compareFields( - [{100: [{200: 'a'}]}], [{100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - [{100: [{200: 'a'}]}], [,,, {100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - [,,, {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - ['hi', {100: [{200: 'a'}]}], ['hi',,, {100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - ['hi',,, {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}])); - }); - - it('testToMap', function() { - var p1 = new proto.jspb.test.Simple1(['k', ['v']]); - var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]); - var soymap = jspb.Message.toMap([p1, p2], - proto.jspb.test.Simple1.prototype.getAString, - proto.jspb.test.Simple1.prototype.toObject); - assertEquals('k', soymap['k'].aString); - assertArrayEquals(['v'], soymap['k'].aRepeatedStringList); - var protomap = jspb.Message.toMap([p1, p2], - proto.jspb.test.Simple1.prototype.getAString); - assertEquals('k', protomap['k'].getAString()); - assertArrayEquals(['v'], protomap['k'].getARepeatedStringList()); - }); - - it('testClone', function() { - var supportsUint8Array = - !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'); - var original = new proto.jspb.test.TestClone(); - original.setStr('v1'); - var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]); - var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]); - var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]); - original.setSimple1(simple1); - original.setSimple2List([simple2, simple3]); - var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123'; - original.setBytesField(bytes1); - var extension = new proto.jspb.test.CloneExtension(); - extension.setExt('e1'); - original.setExtension(proto.jspb.test.IsExtension.extField, extension); - var clone = original.cloneMessage(); - assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],, - [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }], - clone.toArray()); - clone.setStr('v2'); - var simple4 = new proto.jspb.test.Simple1(['a1', ['b1', 'c1']]); - var simple5 = new proto.jspb.test.Simple1(['a2', ['b2', 'c2']]); - var simple6 = new proto.jspb.test.Simple1(['a3', ['b3', 'c3']]); - clone.setSimple1(simple4); - clone.setSimple2List([simple5, simple6]); - if (supportsUint8Array) { - clone.getBytesField()[0] = 4; - assertObjectEquals(bytes1, original.getBytesField()); - } - var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456'; - clone.setBytesField(bytes2); - var newExtension = new proto.jspb.test.CloneExtension(); - newExtension.setExt('e2'); - clone.setExtension(proto.jspb.test.CloneExtension.extField, newExtension); - assertArrayEquals(['v2',, ['a1', ['b1', 'c1']],, - [['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]], bytes2,, { 100: [, 'e2'] }], - clone.toArray()); - assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],, - [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }], - original.toArray()); - }); - - it('testCopyInto', function() { - var supportsUint8Array = - !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'); - var original = new proto.jspb.test.TestClone(); - original.setStr('v1'); - var dest = new proto.jspb.test.TestClone(); - dest.setStr('override'); - var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]); - var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]); - var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]); - var destSimple1 = new proto.jspb.test.Simple1(['ox1', ['oy1', 'oz1']]); - var destSimple2 = new proto.jspb.test.Simple1(['ox2', ['oy2', 'oz2']]); - var destSimple3 = new proto.jspb.test.Simple1(['ox3', ['oy3', 'oz3']]); - original.setSimple1(simple1); - original.setSimple2List([simple2, simple3]); - dest.setSimple1(destSimple1); - dest.setSimple2List([destSimple2, destSimple3]); - var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123'; - var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456'; - original.setBytesField(bytes1); - dest.setBytesField(bytes2); - var extension = new proto.jspb.test.CloneExtension(); - extension.setExt('e1'); - original.setExtension(proto.jspb.test.CloneExtension.extField, extension); - - jspb.Message.copyInto(original, dest); - assertArrayEquals(original.toArray(), dest.toArray()); - assertEquals('x1', dest.getSimple1().getAString()); - assertEquals('e1', - dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt()); - dest.getSimple1().setAString('new value'); - assertNotEquals(dest.getSimple1().getAString(), - original.getSimple1().getAString()); - if (supportsUint8Array) { - dest.getBytesField()[0] = 7; - assertObjectEquals(bytes1, original.getBytesField()); - assertObjectEquals(new Uint8Array([7, 2, 3]), dest.getBytesField()); - } else { - dest.setBytesField('789'); - assertObjectEquals(bytes1, original.getBytesField()); - assertObjectEquals('789', dest.getBytesField()); - } - dest.getExtension(proto.jspb.test.CloneExtension.extField). - setExt('new value'); - assertNotEquals( - dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt(), - original.getExtension( - proto.jspb.test.CloneExtension.extField).getExt()); - }); - - it('testCopyInto_notSameType', function() { - var a = new proto.jspb.test.TestClone(); - var b = new proto.jspb.test.Simple1(['str', ['s1', 's2']]); - - var e = assertThrows(function() { - jspb.Message.copyInto(a, b); - }); - assertContains('should have the same type', e.message); - }); - - it('testExtensions', function() { - var extension1 = new proto.jspb.test.IsExtension(['ext1field']); - var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2']]); - var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); - extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1); - extendable.setExtension(proto.jspb.test.IndirectExtension.simple, - extension2); - extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy'); - extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList, - ['a', 'b']); - var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]); - var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2']]); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedSimpleList, - [s1, s2]); - assertObjectEquals(extension1, - extendable.getExtension(proto.jspb.test.IsExtension.extField)); - assertObjectEquals(extension2, - extendable.getExtension(proto.jspb.test.IndirectExtension.simple)); - assertObjectEquals('xyzzy', - extendable.getExtension(proto.jspb.test.IndirectExtension.str)); - assertObjectEquals(['a', 'b'], extendable.getExtension( - proto.jspb.test.IndirectExtension.repeatedStrList)); - assertObjectEquals([s1, s2], extendable.getExtension( - proto.jspb.test.IndirectExtension.repeatedSimpleList)); - // Not supported yet, but it should work... - extendable.setExtension(proto.jspb.test.IndirectExtension.simple, null); - assertNull( - extendable.getExtension(proto.jspb.test.IndirectExtension.simple)); - extendable.setExtension(proto.jspb.test.IndirectExtension.str, null); - assertNull(extendable.getExtension(proto.jspb.test.IndirectExtension.str)); - - - // Extension fields with jspb.ignore = true are ignored. - assertUndefined(proto.jspb.test.IndirectExtension['ignored']); - assertUndefined(proto.jspb.test.HasExtensions['ignoredFloating']); - }); - - it('testFloatingExtensions', function() { - // From an autogenerated container. - var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); - var extension = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]); - extendable.setExtension(proto.jspb.test.simple1, extension); - assertObjectEquals(extension, - extendable.getExtension(proto.jspb.test.simple1)); - - // From _lib mode. - extension = new proto.jspb.test.ExtensionMessage(['s1']); - extendable = new proto.jspb.test.TestExtensionsMessage([16]); - extendable.setExtension(proto.jspb.test.floatingMsgField, extension); - extendable.setExtension(proto.jspb.test.floatingStrField, 's2'); - assertObjectEquals(extension, - extendable.getExtension(proto.jspb.test.floatingMsgField)); - assertObjectEquals('s2', - extendable.getExtension(proto.jspb.test.floatingStrField)); - assertNotUndefined(proto.jspb.exttest.floatingMsgField); - assertNotUndefined(proto.jspb.exttest.floatingMsgFieldTwo); - assertNotUndefined(proto.jspb.exttest.beta.floatingStrField); - }); - - it('testToObject_extendedObject', function() { - var extension1 = new proto.jspb.test.IsExtension(['ext1field']); - var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2'], true]); - var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); - extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1); - extendable.setExtension(proto.jspb.test.IndirectExtension.simple, - extension2); - extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy'); - extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList, - ['a', 'b']); - var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2'], true]); - var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2'], false]); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedSimpleList, - [s1, s2]); - assertObjectEquals({ - str1: 'v1', str2: 'v2', str3: 'v3', - extField: { ext1: 'ext1field' }, - simple: { - aString: 'str', aRepeatedStringList: ['s1', 's2'], aBoolean: true - }, - str: 'xyzzy', - repeatedStrList: ['a', 'b'], - repeatedSimpleList: [ - { aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true}, - { aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false} - ] - }, extendable.toObject()); - - // Now, with instances included. - assertObjectEquals({ - str1: 'v1', str2: 'v2', str3: 'v3', - extField: { - ext1: 'ext1field', - $jspbMessageInstance: - extendable.getExtension(proto.jspb.test.IsExtension.extField) - }, - simple: { - aString: 'str', - aRepeatedStringList: ['s1', 's2'], - aBoolean: true, - $jspbMessageInstance: - extendable.getExtension(proto.jspb.test.IndirectExtension.simple) - }, - str: 'xyzzy', - repeatedStrList: ['a', 'b'], - repeatedSimpleList: [{ - aString: 'foo', - aRepeatedStringList: ['s1', 's2'], - aBoolean: true, - $jspbMessageInstance: s1 - }, { - aString: 'bar', - aRepeatedStringList: ['t1', 't2'], - aBoolean: false, - $jspbMessageInstance: s2 - }], - $jspbMessageInstance: extendable - }, extendable.toObject(true /* opt_includeInstance */)); - }); - - it('testInitialization_emptyArray', function() { - var msg = new proto.jspb.test.HasExtensions([]); - if (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) { - assertArrayEquals([], msg.toArray()); - } else { - // Extension object is created past all regular fields. - assertArrayEquals([,,, {}], msg.toArray()); - } - }); - - it('testInitialization_justExtensionObject', function() { - var msg = new proto.jspb.test.Empty([{1: 'hi'}]); - // The extensionObject is not moved from its original location. - assertArrayEquals([{1: 'hi'}], msg.toArray()); - }); - - it('testInitialization_incompleteList', function() { - var msg = new proto.jspb.test.Empty([1, {4: 'hi'}]); - // The extensionObject is not moved from its original location. - assertArrayEquals([1, {4: 'hi'}], msg.toArray()); - }); - - it('testInitialization_forwardCompatible', function() { - var msg = new proto.jspb.test.Empty([1, 2, 3, {1: 'hi'}]); - assertArrayEquals([1, 2, 3, {1: 'hi'}], msg.toArray()); - }); - - it('testExtendedMessageEnsureObject', function() { - var data = new proto.jspb.test.HasExtensions(['str1', - {'a_key': 'an_object'}]); - assertEquals('an_object', data.extensionObject_['a_key']); - }); - - it('testToObject_hasExtensionField', function() { - var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]); - var obj = data.toObject(); - assertEquals('str1', obj.str1); - assertEquals('ext1', obj.extField.ext1); - }); - - it('testGetExtension', function() { - var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]); - assertEquals('str1', data.getStr1()); - var extension = data.getExtension(proto.jspb.test.IsExtension.extField); - assertNotNull(extension); - assertEquals('ext1', extension.getExt1()); - }); - - it('testSetExtension', function() { - var data = new proto.jspb.test.HasExtensions(); - var extensionMessage = new proto.jspb.test.IsExtension(['is_extension']); - data.setExtension(proto.jspb.test.IsExtension.extField, extensionMessage); - var obj = data.toObject(); - assertNotNull( - data.getExtension(proto.jspb.test.IsExtension.extField)); - assertEquals('is_extension', obj.extField.ext1); - }); - - /** - * Note that group is long deprecated, we only support it because JsPb has - * a goal of being able to generate JS classes for all proto descriptors. - */ - it('testGroups', function() { - var group = new proto.jspb.test.TestGroup(); - var someGroup = new proto.jspb.test.TestGroup.RepeatedGroup(); - someGroup.setId('g1'); - someGroup.setSomeBoolList([true, false]); - group.setRepeatedGroupList([someGroup]); - var groups = group.getRepeatedGroupList(); - assertEquals('g1', groups[0].getId()); - assertObjectEquals([true, false], groups[0].getSomeBoolList()); - assertObjectEquals({id: 'g1', someBoolList: [true, false]}, - groups[0].toObject()); - assertObjectEquals({ - repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}], - requiredGroup: {id: undefined}, - optionalGroup: undefined, - requiredSimple: {aRepeatedStringList: [], aString: undefined}, - optionalSimple: undefined, - id: undefined - }, group.toObject()); - var group1 = new proto.jspb.test.TestGroup1(); - group1.setGroup(someGroup); - assertEquals(someGroup, group1.getGroup()); - }); - - it('testNonExtensionFieldsAfterExtensionRange', function() { - var data = [{'1': 'a_string'}]; - var message = new proto.jspb.test.Complex(data); - assertArrayEquals([], message.getARepeatedStringList()); - }); - - it('testReservedGetterNames', function() { - var message = new proto.jspb.test.TestReservedNames(); - message.setExtension$(11); - message.setExtension(proto.jspb.test.TestReservedNamesExtension.foo, 12); - assertEquals(11, message.getExtension$()); - assertEquals(12, message.getExtension( - proto.jspb.test.TestReservedNamesExtension.foo)); - assertObjectEquals({extension: 11, foo: 12}, message.toObject()); - }); - - it('testInitializeMessageWithUnsetOneof', function() { - var message = new proto.jspb.test.TestMessageWithOneof([]); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase. - PARTIAL_ONEOF_NOT_SET, - message.getPartialOneofCase()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase. - RECURSIVE_ONEOF_NOT_SET, - message.getRecursiveOneofCase()); - }); - - it('testInitializeMessageWithSingleValueSetInOneof', function() { - var message = new proto.jspb.test.TestMessageWithOneof([,, 'x']); - - assertEquals('x', message.getPone()); - assertEquals('', message.getPthree()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, - message.getPartialOneofCase()); - }); - - it('testKeepsLastWireValueSetInUnion_multipleValues', function() { - var message = new proto.jspb.test.TestMessageWithOneof([,, 'x',, 'y']); - - assertEquals('', message.getPone()); - assertEquals('y', message.getPthree()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE, - message.getPartialOneofCase()); - }); - - it('testSettingOneofFieldClearsOthers', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals('', message.getPone()); - assertEquals('', message.getPthree()); - assertFalse(message.hasPone()); - assertFalse(message.hasPthree()); - - message.setPone('hi'); - assertEquals('hi', message.getPone()); - assertEquals('', message.getPthree()); - assertTrue(message.hasPone()); - assertFalse(message.hasPthree()); - - message.setPthree('bye'); - assertEquals('', message.getPone()); - assertEquals('bye', message.getPthree()); - assertFalse(message.hasPone()); - assertTrue(message.hasPthree()); - }); - - it('testSettingOneofFieldDoesNotClearFieldsFromOtherUnions', function() { - var other = new proto.jspb.test.TestMessageWithOneof; - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals('', message.getPone()); - assertEquals('', message.getPthree()); - assertUndefined(message.getRone()); - assertFalse(message.hasPone()); - assertFalse(message.hasPthree()); - - message.setPone('hi'); - message.setRone(other); - assertEquals('hi', message.getPone()); - assertEquals('', message.getPthree()); - assertEquals(other, message.getRone()); - assertTrue(message.hasPone()); - assertFalse(message.hasPthree()); - - message.setPthree('bye'); - assertEquals('', message.getPone()); - assertEquals('bye', message.getPthree()); - assertEquals(other, message.getRone()); - assertFalse(message.hasPone()); - assertTrue(message.hasPthree()); - }); - - it('testUnsetsOneofCaseWhenFieldIsCleared', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase. - PARTIAL_ONEOF_NOT_SET, - message.getPartialOneofCase()); - - message.setPone('hi'); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, - message.getPartialOneofCase()); - - message.clearPone(); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase. - PARTIAL_ONEOF_NOT_SET, - message.getPartialOneofCase()); - }); - - it('testMessageWithDefaultOneofValues', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals(1234, message.getAone()); - assertEquals(0, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase - .DEFAULT_ONEOF_A_NOT_SET, - message.getDefaultOneofACase()); - - message.setAone(567); - assertEquals(567, message.getAone()); - assertEquals(0, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE, - message.getDefaultOneofACase()); - - message.setAtwo(890); - assertEquals(1234, message.getAone()); - assertEquals(890, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO, - message.getDefaultOneofACase()); - - message.clearAtwo(); - assertEquals(1234, message.getAone()); - assertEquals(0, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase - .DEFAULT_ONEOF_A_NOT_SET, - message.getDefaultOneofACase()); - }); - - it('testMessageWithDefaultOneofValues_defaultNotOnFirstField', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals(0, message.getBone()); - assertEquals(1234, message.getBtwo()); - assertFalse(message.hasBone()); - assertFalse(message.hasBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase - .DEFAULT_ONEOF_B_NOT_SET, - message.getDefaultOneofBCase()); - - message.setBone(2); - assertEquals(2, message.getBone()); - assertEquals(1234, message.getBtwo()); - assertTrue(message.hasBone()); - assertFalse(message.hasBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE, - message.getDefaultOneofBCase()); - - message.setBtwo(3); - assertEquals(0, message.getBone()); - assertFalse(message.hasBone()); - assertTrue(message.hasBtwo()); - assertEquals(3, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, - message.getDefaultOneofBCase()); - - message.clearBtwo(); - assertEquals(0, message.getBone()); - assertFalse(message.hasBone()); - assertFalse(message.hasBtwo()); - assertEquals(1234, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase - .DEFAULT_ONEOF_B_NOT_SET, - message.getDefaultOneofBCase()); - }); - - it('testInitializeMessageWithOneofDefaults', function() { - var message = - new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567)); - assertEquals(567, message.getAone()); - assertEquals(0, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE, - message.getDefaultOneofACase()); - - message = - new proto.jspb.test.TestMessageWithOneof(new Array(10).concat(890)); - assertEquals(1234, message.getAone()); - assertEquals(890, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO, - message.getDefaultOneofACase()); - - message = - new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567, 890)); - assertEquals(1234, message.getAone()); - assertEquals(890, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO, - message.getDefaultOneofACase()); - }); - - it('testInitializeMessageWithOneofDefaults_defaultNotSetOnFirstField', - function() { - var message; - - message = - new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567)); - assertEquals(567, message.getBone()); - assertEquals(1234, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE, - message.getDefaultOneofBCase()); - - message = - new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890)); - assertEquals(0, message.getBone()); - assertEquals(890, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, - message.getDefaultOneofBCase()); - - message = new proto.jspb.test.TestMessageWithOneof( - new Array(11).concat(567, 890)); - assertEquals(0, message.getBone()); - assertEquals(890, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, - message.getDefaultOneofBCase()); - }); - - it('testOneofContainingAnotherMessage', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals( - proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase. - RECURSIVE_ONEOF_NOT_SET, - message.getRecursiveOneofCase()); - - var other = new proto.jspb.test.TestMessageWithOneof; - message.setRone(other); - assertEquals(other, message.getRone()); - assertEquals('', message.getRtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RONE, - message.getRecursiveOneofCase()); - - message.setRtwo('hi'); - assertUndefined(message.getRone()); - assertEquals('hi', message.getRtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RTWO, - message.getRecursiveOneofCase()); - }); - - it('testQueryingOneofCaseEnsuresOnlyOneFieldIsSetInUnderlyingArray', - function() { - var message = new proto.jspb.test.TestMessageWithOneof; - message.setPone('x'); - assertEquals('x', message.getPone()); - assertEquals('', message.getPthree()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, - message.getPartialOneofCase()); - - var array = message.toArray(); - assertEquals('x', array[2]); - assertUndefined(array[4]); - array[4] = 'y'; - - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE, - message.getPartialOneofCase()); - assertUndefined(array[2]); - assertEquals('y', array[4]); - }); - - it('testFloatingPointFieldsSupportNan', function() { - var assertNan = function(x) { - assertTrue( - 'Expected ' + x + ' (' + goog.typeOf(x) + ') to be NaN.', - typeof x === 'number' && isNaN(x)); - }; - - var message = new proto.jspb.test.FloatingPointFields([ - 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN', - 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN' - ]); - assertNan(message.getOptionalFloatField()); - assertNan(message.getRequiredFloatField()); - assertNan(message.getRepeatedFloatFieldList()[0]); - assertNan(message.getRepeatedFloatFieldList()[1]); - assertNan(message.getDefaultFloatField()); - assertNan(message.getOptionalDoubleField()); - assertNan(message.getRequiredDoubleField()); - assertNan(message.getRepeatedDoubleFieldList()[0]); - assertNan(message.getRepeatedDoubleFieldList()[1]); - assertNan(message.getDefaultDoubleField()); - }); - -}); diff --git a/js/compatibility_tests/v3.0.0/proto3_test.js b/js/compatibility_tests/v3.0.0/proto3_test.js deleted file mode 100644 index d020a11fc..000000000 --- a/js/compatibility_tests/v3.0.0/proto3_test.js +++ /dev/null @@ -1,329 +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. - -goog.require('goog.crypt.base64'); -goog.require('goog.testing.asserts'); - -// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test -goog.require('proto.jspb.test.ForeignMessage'); - -// CommonJS-LoadFromFile: proto3_test_pb proto.jspb.test -goog.require('proto.jspb.test.Proto3Enum'); -goog.require('proto.jspb.test.TestProto3'); - - -var BYTES = new Uint8Array([1, 2, 8, 9]); -var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES); - - -/** - * Helper: compare a bytes field to an expected value - * @param {Uint8Array|string} arr - * @param {Uint8Array} expected - * @return {boolean} - */ -function bytesCompare(arr, expected) { - if (typeof arr === 'string') { - arr = goog.crypt.base64.decodeStringToUint8Array(arr); - } - if (arr.length != expected.length) { - return false; - } - for (var i = 0; i < arr.length; i++) { - if (arr[i] != expected[i]) { - return false; - } - } - return true; -} - - -describe('proto3Test', function() { - /** - * Test defaults for proto3 message fields. - */ - it('testProto3FieldDefaults', function() { - var msg = new proto.jspb.test.TestProto3(); - - assertEquals(msg.getOptionalInt32(), 0); - assertEquals(msg.getOptionalInt64(), 0); - assertEquals(msg.getOptionalUint32(), 0); - assertEquals(msg.getOptionalUint64(), 0); - assertEquals(msg.getOptionalSint32(), 0); - assertEquals(msg.getOptionalSint64(), 0); - assertEquals(msg.getOptionalFixed32(), 0); - assertEquals(msg.getOptionalFixed64(), 0); - assertEquals(msg.getOptionalSfixed32(), 0); - assertEquals(msg.getOptionalSfixed64(), 0); - assertEquals(msg.getOptionalFloat(), 0); - assertEquals(msg.getOptionalDouble(), 0); - assertEquals(msg.getOptionalString(), ''); - - // TODO(b/26173701): when we change bytes fields default getter to return - // Uint8Array, we'll want to switch this assertion to match the u8 case. - assertEquals(typeof msg.getOptionalBytes(), 'string'); - assertEquals(msg.getOptionalBytes_asU8() instanceof Uint8Array, true); - assertEquals(typeof msg.getOptionalBytes_asB64(), 'string'); - assertEquals(msg.getOptionalBytes().length, 0); - assertEquals(msg.getOptionalBytes_asU8().length, 0); - assertEquals(msg.getOptionalBytes_asB64(), ''); - - assertEquals(msg.getOptionalForeignEnum(), - proto.jspb.test.Proto3Enum.PROTO3_FOO); - assertEquals(msg.getOptionalForeignMessage(), undefined); - assertEquals(msg.getOptionalForeignMessage(), undefined); - - assertEquals(msg.getRepeatedInt32List().length, 0); - assertEquals(msg.getRepeatedInt64List().length, 0); - assertEquals(msg.getRepeatedUint32List().length, 0); - assertEquals(msg.getRepeatedUint64List().length, 0); - assertEquals(msg.getRepeatedSint32List().length, 0); - assertEquals(msg.getRepeatedSint64List().length, 0); - assertEquals(msg.getRepeatedFixed32List().length, 0); - assertEquals(msg.getRepeatedFixed64List().length, 0); - assertEquals(msg.getRepeatedSfixed32List().length, 0); - assertEquals(msg.getRepeatedSfixed64List().length, 0); - assertEquals(msg.getRepeatedFloatList().length, 0); - assertEquals(msg.getRepeatedDoubleList().length, 0); - assertEquals(msg.getRepeatedStringList().length, 0); - assertEquals(msg.getRepeatedBytesList().length, 0); - assertEquals(msg.getRepeatedForeignEnumList().length, 0); - assertEquals(msg.getRepeatedForeignMessageList().length, 0); - - }); - - - /** - * Test that all fields can be set and read via a serialization roundtrip. - */ - it('testProto3FieldSetGet', function() { - var msg = new proto.jspb.test.TestProto3(); - - msg.setOptionalInt32(-42); - msg.setOptionalInt64(-0x7fffffff00000000); - msg.setOptionalUint32(0x80000000); - msg.setOptionalUint64(0xf000000000000000); - msg.setOptionalSint32(-100); - msg.setOptionalSint64(-0x8000000000000000); - msg.setOptionalFixed32(1234); - msg.setOptionalFixed64(0x1234567800000000); - msg.setOptionalSfixed32(-1234); - msg.setOptionalSfixed64(-0x1234567800000000); - msg.setOptionalFloat(1.5); - msg.setOptionalDouble(-1.5); - msg.setOptionalBool(true); - msg.setOptionalString('hello world'); - msg.setOptionalBytes(BYTES); - var submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(16); - msg.setOptionalForeignMessage(submsg); - msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); - - msg.setRepeatedInt32List([-42]); - msg.setRepeatedInt64List([-0x7fffffff00000000]); - msg.setRepeatedUint32List([0x80000000]); - msg.setRepeatedUint64List([0xf000000000000000]); - msg.setRepeatedSint32List([-100]); - msg.setRepeatedSint64List([-0x8000000000000000]); - msg.setRepeatedFixed32List([1234]); - msg.setRepeatedFixed64List([0x1234567800000000]); - msg.setRepeatedSfixed32List([-1234]); - msg.setRepeatedSfixed64List([-0x1234567800000000]); - msg.setRepeatedFloatList([1.5]); - msg.setRepeatedDoubleList([-1.5]); - msg.setRepeatedBoolList([true]); - msg.setRepeatedStringList(['hello world']); - msg.setRepeatedBytesList([BYTES]); - submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(1000); - msg.setRepeatedForeignMessageList([submsg]); - msg.setRepeatedForeignEnumList([proto.jspb.test.Proto3Enum.PROTO3_BAR]); - - msg.setOneofString('asdf'); - - var serialized = msg.serializeBinary(); - msg = proto.jspb.test.TestProto3.deserializeBinary(serialized); - - assertEquals(msg.getOptionalInt32(), -42); - assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000); - assertEquals(msg.getOptionalUint32(), 0x80000000); - assertEquals(msg.getOptionalUint64(), 0xf000000000000000); - assertEquals(msg.getOptionalSint32(), -100); - assertEquals(msg.getOptionalSint64(), -0x8000000000000000); - assertEquals(msg.getOptionalFixed32(), 1234); - assertEquals(msg.getOptionalFixed64(), 0x1234567800000000); - assertEquals(msg.getOptionalSfixed32(), -1234); - assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000); - assertEquals(msg.getOptionalFloat(), 1.5); - assertEquals(msg.getOptionalDouble(), -1.5); - assertEquals(msg.getOptionalBool(), true); - assertEquals(msg.getOptionalString(), 'hello world'); - assertEquals(true, bytesCompare(msg.getOptionalBytes(), BYTES)); - assertEquals(msg.getOptionalForeignMessage().getC(), 16); - assertEquals(msg.getOptionalForeignEnum(), - proto.jspb.test.Proto3Enum.PROTO3_BAR); - - assertElementsEquals(msg.getRepeatedInt32List(), [-42]); - assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]); - assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]); - assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]); - assertElementsEquals(msg.getRepeatedSint32List(), [-100]); - assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]); - assertElementsEquals(msg.getRepeatedFixed32List(), [1234]); - assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]); - assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]); - assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]); - assertElementsEquals(msg.getRepeatedFloatList(), [1.5]); - assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]); - assertElementsEquals(msg.getRepeatedBoolList(), [true]); - assertElementsEquals(msg.getRepeatedStringList(), ['hello world']); - assertEquals(msg.getRepeatedBytesList().length, 1); - assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES)); - assertEquals(msg.getRepeatedForeignMessageList().length, 1); - assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000); - assertElementsEquals(msg.getRepeatedForeignEnumList(), - [proto.jspb.test.Proto3Enum.PROTO3_BAR]); - - assertEquals(msg.getOneofString(), 'asdf'); - }); - - - /** - * Test that oneofs continue to have a notion of field presence. - */ - it('testOneofs', function() { - var msg = new proto.jspb.test.TestProto3(); - - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes(), ''); - assertFalse(msg.hasOneofUint32()); - assertFalse(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - msg.setOneofUint32(42); - assertEquals(msg.getOneofUint32(), 42); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes(), ''); - assertTrue(msg.hasOneofUint32()); - assertFalse(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - - var submsg = new proto.jspb.test.ForeignMessage(); - msg.setOneofForeignMessage(submsg); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), submsg); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes(), ''); - assertFalse(msg.hasOneofUint32()); - assertFalse(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - msg.setOneofString('hello'); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), 'hello'); - assertEquals(msg.getOneofBytes(), ''); - assertFalse(msg.hasOneofUint32()); - assertTrue(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes_asB64(), - goog.crypt.base64.encodeString('\u00FF\u00FF')); - assertFalse(msg.hasOneofUint32()); - assertFalse(msg.hasOneofString()); - assertTrue(msg.hasOneofBytes()); - }); - - - /** - * Test that "default"-valued primitive fields are not emitted on the wire. - */ - it('testNoSerializeDefaults', function() { - var msg = new proto.jspb.test.TestProto3(); - - // Set each primitive to a non-default value, then back to its default, to - // ensure that the serialization is actually checking the value and not just - // whether it has ever been set. - msg.setOptionalInt32(42); - msg.setOptionalInt32(0); - msg.setOptionalDouble(3.14); - msg.setOptionalDouble(0.0); - msg.setOptionalBool(true); - msg.setOptionalBool(false); - msg.setOptionalString('hello world'); - msg.setOptionalString(''); - msg.setOptionalBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); - msg.setOptionalBytes(''); - msg.setOptionalForeignMessage(new proto.jspb.test.ForeignMessage()); - msg.setOptionalForeignMessage(null); - msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); - msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO); - msg.setOneofUint32(32); - msg.setOneofUint32(null); - - - var serialized = msg.serializeBinary(); - assertEquals(0, serialized.length); - }); - - /** - * Test that base64 string and Uint8Array are interchangeable in bytes fields. - */ - it('testBytesFieldsInterop', function() { - var msg = new proto.jspb.test.TestProto3(); - // Set as a base64 string and check all the getters work. - msg.setOptionalBytes(BYTES_B64); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - // Test binary serialize round trip doesn't break it. - msg = proto.jspb.test.TestProto3.deserializeBinary(msg.serializeBinary()); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - msg = new proto.jspb.test.TestProto3(); - // Set as a Uint8Array and check all the getters work. - msg.setOptionalBytes(BYTES); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - }); -}); diff --git a/js/compatibility_tests/v3.0.0/proto3_test.proto b/js/compatibility_tests/v3.0.0/proto3_test.proto deleted file mode 100644 index acb671649..000000000 --- a/js/compatibility_tests/v3.0.0/proto3_test.proto +++ /dev/null @@ -1,89 +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. - -syntax = "proto3"; - -import "testbinary.proto"; - -package jspb.test; - -message TestProto3 { - int32 optional_int32 = 1; - int64 optional_int64 = 2; - uint32 optional_uint32 = 3; - uint64 optional_uint64 = 4; - sint32 optional_sint32 = 5; - sint64 optional_sint64 = 6; - fixed32 optional_fixed32 = 7; - fixed64 optional_fixed64 = 8; - sfixed32 optional_sfixed32 = 9; - sfixed64 optional_sfixed64 = 10; - float optional_float = 11; - double optional_double = 12; - bool optional_bool = 13; - string optional_string = 14; - bytes optional_bytes = 15; - - ForeignMessage optional_foreign_message = 19; - Proto3Enum optional_foreign_enum = 22; - - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated ForeignMessage repeated_foreign_message = 49; - repeated Proto3Enum repeated_foreign_enum = 52; - - - oneof oneof_field { - uint32 oneof_uint32 = 111; - ForeignMessage oneof_foreign_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } -} - -enum Proto3Enum { - PROTO3_FOO = 0; - PROTO3_BAR = 1; - PROTO3_BAZ = 2; -} diff --git a/js/compatibility_tests/v3.0.0/test.proto b/js/compatibility_tests/v3.0.0/test.proto deleted file mode 100644 index 937ffb89c..000000000 --- a/js/compatibility_tests/v3.0.0/test.proto +++ /dev/null @@ -1,236 +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: mwr@google.com (Mark Rawling) - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -import "google/protobuf/descriptor.proto"; - -package jspb.test; - -message Empty { -} - -enum OuterEnum { - FOO = 1; - BAR = 2; -} - -message EnumContainer { - optional OuterEnum outer_enum = 1; -} - -message Simple1 { - required string a_string = 1; - repeated string a_repeated_string = 2; - optional bool a_boolean = 3; -} - -// A message that differs from Simple1 only by name -message Simple2 { - required string a_string = 1; - repeated string a_repeated_string = 2; -} - -message SpecialCases { - required string normal = 1; - // Examples of Js reserved names that are converted to pb_. - required string default = 2; - required string function = 3; - required string var = 4; -} - -message OptionalFields { - message Nested { - optional int32 an_int = 1; - } - optional string a_string = 1; - required bool a_bool = 2; - optional Nested a_nested_message = 3; - repeated Nested a_repeated_message = 4; - repeated string a_repeated_string = 5; -} - -message HasExtensions { - optional string str1 = 1; - optional string str2 = 2; - optional string str3 = 3; - extensions 10 to max; -} - -message Complex { - message Nested { - required int32 an_int = 2; - } - required string a_string = 1; - required bool an_out_of_order_bool = 9; - optional Nested a_nested_message = 4; - repeated Nested a_repeated_message = 5; - repeated string a_repeated_string = 7; -} - -message OuterMessage { - // Make sure this doesn't conflict with the other Complex message. - message Complex { - optional int32 inner_complex_field = 1; - } -} - -message IsExtension { - extend HasExtensions { - optional IsExtension ext_field = 100; - } - optional string ext1 = 1; - - // Extensions of proto2 Descriptor messages will be ignored. - extend google.protobuf.EnumOptions { - optional string simple_option = 42113038; - } -} - -message IndirectExtension { - extend HasExtensions { - optional Simple1 simple = 101; - optional string str = 102; - repeated string repeated_str = 103; - repeated Simple1 repeated_simple = 104; - } -} - -extend HasExtensions { - optional Simple1 simple1 = 105; -} - -message DefaultValues { - enum Enum { - E1 = 13; - E2 = 77; - } - optional string string_field = 1 [default="default<>\'\"abc"]; - optional bool bool_field = 2 [default=true]; - optional int64 int_field = 3 [default=11]; - optional Enum enum_field = 4 [default=E1]; - optional string empty_field = 6 [default=""]; - optional bytes bytes_field = 8 [default="moo"]; // Base64 encoding is "bW9v" -} - -message FloatingPointFields { - optional float optional_float_field = 1; - required float required_float_field = 2; - repeated float repeated_float_field = 3; - optional float default_float_field = 4 [default = 2.0]; - optional double optional_double_field = 5; - required double required_double_field = 6; - repeated double repeated_double_field = 7; - optional double default_double_field = 8 [default = 2.0]; -} - -message TestClone { - optional string str = 1; - optional Simple1 simple1 = 3; - repeated Simple1 simple2 = 5; - optional bytes bytes_field = 6; - optional string unused = 7; - extensions 10 to max; -} - -message CloneExtension { - extend TestClone { - optional CloneExtension ext_field = 100; - } - optional string ext = 2; -} - -message TestGroup { - repeated group RepeatedGroup = 1 { - required string id = 1; - repeated bool some_bool = 2; - } - required group RequiredGroup = 2 { - required string id = 1; - } - optional group OptionalGroup = 3 { - required string id = 1; - } - optional string id = 4; - required Simple2 required_simple = 5; - optional Simple2 optional_simple = 6; -} - -message TestGroup1 { - optional TestGroup.RepeatedGroup group = 1; -} - -message TestReservedNames { - optional int32 extension = 1; - extensions 10 to max; -} - -message TestReservedNamesExtension { - extend TestReservedNames { - optional int32 foo = 10; - } -} - -message TestMessageWithOneof { - - oneof partial_oneof { - string pone = 3; - string pthree = 5; - } - - oneof recursive_oneof { - TestMessageWithOneof rone = 6; - string rtwo = 7; - } - - optional bool normal_field = 8; - repeated string repeated_field = 9; - - oneof default_oneof_a { - int32 aone = 10 [default = 1234]; - int32 atwo = 11; - } - - oneof default_oneof_b { - int32 bone = 12; - int32 btwo = 13 [default = 1234]; - } -} - -message TestEndsWithBytes { - optional int32 value = 1; - optional bytes data = 2; -} - diff --git a/js/compatibility_tests/v3.0.0/test.sh b/js/compatibility_tests/v3.0.0/test.sh deleted file mode 100755 index 5b92ed1ce..000000000 --- a/js/compatibility_tests/v3.0.0/test.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/bash - -set -e - -# Download protoc 3.0.0 from Maven if it is not already present. -OLD_PROTOC_URL=https://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0/protoc-3.0.0-linux-x86_64.exe -if [ ! -f protoc ]; then - wget $OLD_PROTOC_URL -O protoc - chmod +x protoc -fi - -pushd ../.. -npm install && npm test -popd - -old_protoc=./protoc -new_protoc=../../../src/protoc - -# The protos in group 2 have some dependencies on protos in group 1. The tests -# will verify that the generated code for one group can be regenerated -# independently of the other group in a compatible way. -# -# Note: these lists of protos duplicate the lists in gulpfile.js. Ideally we -# should find a good way of having a single source of truth for this. -group1_protos="data.proto test3.proto test5.proto commonjs/test6/test6.proto testbinary.proto testempty.proto test.proto" -group2_protos="proto3_test.proto test2.proto test4.proto commonjs/test7/test7.proto" - -# We test the following cases: -# -# Case 1: build groups 1 and 2 with the old protoc -# Case 2: build group 1 with new protoc but group 2 with old protoc -# Case 3: build group 1 with old protoc but group 2 with new protoc -# -# In each case, we use the current runtime. - -# -# CommonJS tests -# -mkdir -p commonjs_out{1,2,3} -# Case 1 -$old_protoc --js_out=import_style=commonjs,binary:commonjs_out1 -I ../../../src -I commonjs -I . $group1_protos -$old_protoc --js_out=import_style=commonjs,binary:commonjs_out1 -I ../../../src -I commonjs -I . $group2_protos -# Case 2 -$new_protoc --js_out=import_style=commonjs,binary:commonjs_out2 -I ../../../src -I commonjs -I . $group1_protos -$old_protoc --js_out=import_style=commonjs,binary:commonjs_out2 -I ../../../src -I commonjs -I . $group2_protos -# Case 3 -$old_protoc --js_out=import_style=commonjs,binary:commonjs_out3 -I ../../../src -I commonjs -I . $group1_protos -$new_protoc --js_out=import_style=commonjs,binary:commonjs_out3 -I ../../../src -I commonjs -I . $group2_protos - -mkdir -p commonjs_out/binary -for file in *_test.js binary/*_test.js; do - node commonjs/rewrite_tests_for_commonjs.js < "$file" > "commonjs_out/$file" -done -cp commonjs/{jasmine.json,import_test.js} commonjs_out/ -mkdir -p commonjs_out/test_node_modules -../../node_modules/.bin/google-closure-compiler \ - --entry_point=commonjs/export_asserts.js \ - --js=commonjs/export_asserts.js \ - --js=../../node_modules/google-closure-library/closure/goog/**.js \ - --js=../../node_modules/google-closure-library/third_party/closure/goog/**.js \ - > commonjs_out/test_node_modules/closure_asserts_commonjs.js -../../node_modules/.bin/google-closure-compiler \ - --entry_point=commonjs/export_testdeps.js \ - --js=commonjs/export_testdeps.js \ - --js=../../binary/*.js \ - --js=!../../binary/*_test.js \ - --js=../../node_modules/google-closure-library/closure/goog/**.js \ - --js=../../node_modules/google-closure-library/third_party/closure/goog/**.js \ - > commonjs_out/test_node_modules/testdeps_commonjs.js -cp ../../google-protobuf.js commonjs_out/test_node_modules -cp -r ../../commonjs_out/node_modules commonjs_out - -echo -echo "Running tests with CommonJS imports" -echo "-----------------------------------" -for i in 1 2 3; do - cp -r commonjs_out/* "commonjs_out$i" - pushd "commonjs_out$i" - JASMINE_CONFIG_PATH=jasmine.json NODE_PATH=test_node_modules ../../../node_modules/.bin/jasmine - popd -done - -# -# Closure tests -# -$old_protoc --js_out=library=testproto_libs1,binary:. -I ../../../src -I commonjs -I . $group1_protos -$old_protoc --js_out=library=testproto_libs2,binary:. -I ../../../src -I commonjs -I . $group2_protos -$new_protoc --js_out=library=testproto_libs1_new,binary:. -I ../../../src -I commonjs -I . $group1_protos -$new_protoc --js_out=library=testproto_libs2_new,binary:. -I ../../../src -I commonjs -I . $group2_protos - -echo -echo "Running tests with Closure-style imports" -echo "----------------------------------------" - -# Case 1 -JASMINE_CONFIG_PATH=jasmine1.json ../../node_modules/.bin/jasmine -# Case 2 -JASMINE_CONFIG_PATH=jasmine2.json ../../node_modules/.bin/jasmine -# Case 3 -JASMINE_CONFIG_PATH=jasmine3.json ../../node_modules/.bin/jasmine - -# Remove these files so that calcdeps.py does not get confused by them the next -# time this script runs. -rm testproto_libs[12]* diff --git a/js/compatibility_tests/v3.0.0/test2.proto b/js/compatibility_tests/v3.0.0/test2.proto deleted file mode 100644 index 44e55effc..000000000 --- a/js/compatibility_tests/v3.0.0/test2.proto +++ /dev/null @@ -1,54 +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. - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test; - -message TestExtensionsMessage { - optional int32 intfield = 1; - extensions 100 to max; -} - -message ExtensionMessage { - extend TestExtensionsMessage { - optional ExtensionMessage ext_field = 100; - } - optional string ext1 = 1; -} - -// Floating extensions are only supported when generating a _lib.js library. -extend TestExtensionsMessage { - optional ExtensionMessage floating_msg_field = 101; - optional string floating_str_field = 102; -} diff --git a/js/compatibility_tests/v3.0.0/test3.proto b/js/compatibility_tests/v3.0.0/test3.proto deleted file mode 100644 index 940a552ed..000000000 --- a/js/compatibility_tests/v3.0.0/test3.proto +++ /dev/null @@ -1,53 +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. - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.exttest; - -message TestExtensionsMessage { - optional int32 intfield = 1; - extensions 100 to max; -} - -message ExtensionMessage { - extend TestExtensionsMessage { - optional ExtensionMessage ext_field = 100; - } - optional string ext1 = 1; -} - -extend TestExtensionsMessage { - optional ExtensionMessage floating_msg_field = 101; - optional string floating_str_field = 102; -} diff --git a/js/compatibility_tests/v3.0.0/test4.proto b/js/compatibility_tests/v3.0.0/test4.proto deleted file mode 100644 index cf2451e9c..000000000 --- a/js/compatibility_tests/v3.0.0/test4.proto +++ /dev/null @@ -1,42 +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. - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.exttest; - -import "test3.proto"; - -extend TestExtensionsMessage { - optional ExtensionMessage floating_msg_field_two = 103; -} diff --git a/js/compatibility_tests/v3.0.0/test5.proto b/js/compatibility_tests/v3.0.0/test5.proto deleted file mode 100644 index 34979517e..000000000 --- a/js/compatibility_tests/v3.0.0/test5.proto +++ /dev/null @@ -1,44 +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. - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.exttest.beta; - -message TestBetaExtensionsMessage { - extensions 100 to max; -} - -extend TestBetaExtensionsMessage { - optional string floating_str_field = 101; -} diff --git a/js/compatibility_tests/v3.0.0/testbinary.proto b/js/compatibility_tests/v3.0.0/testbinary.proto deleted file mode 100644 index 116f17fb5..000000000 --- a/js/compatibility_tests/v3.0.0/testbinary.proto +++ /dev/null @@ -1,212 +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. - -// LINT: ALLOW_GROUPS - -syntax = "proto2"; - - -package jspb.test; - -// These types are borrowed from `unittest.proto` in the protobuf tree. We want -// to ensure that the binary-format support will handle all field types -// properly. -message TestAllTypes { - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - optional group OptionalGroup = 16 { - optional int32 a = 17; - } - - optional ForeignMessage optional_foreign_message = 19; - optional ForeignEnum optional_foreign_enum = 22; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } - - repeated ForeignMessage repeated_foreign_message = 49; - repeated ForeignEnum repeated_foreign_enum = 52; - - // Packed repeated - repeated int32 packed_repeated_int32 = 61 [packed=true]; - repeated int64 packed_repeated_int64 = 62 [packed=true]; - repeated uint32 packed_repeated_uint32 = 63 [packed=true]; - repeated uint64 packed_repeated_uint64 = 64 [packed=true]; - repeated sint32 packed_repeated_sint32 = 65 [packed=true]; - repeated sint64 packed_repeated_sint64 = 66 [packed=true]; - repeated fixed32 packed_repeated_fixed32 = 67 [packed=true]; - repeated fixed64 packed_repeated_fixed64 = 68 [packed=true]; - repeated sfixed32 packed_repeated_sfixed32 = 69 [packed=true]; - repeated sfixed64 packed_repeated_sfixed64 = 70 [packed=true]; - repeated float packed_repeated_float = 71 [packed=true]; - repeated double packed_repeated_double = 72 [packed=true]; - repeated bool packed_repeated_bool = 73 [packed=true]; - - oneof oneof_field { - uint32 oneof_uint32 = 111; - ForeignMessage oneof_foreign_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } - -} - -message ForeignMessage { - optional int32 c = 1; -} - -enum ForeignEnum { - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -message TestExtendable { - extensions 1 to max; -} - -message ExtendsWithMessage { - extend TestExtendable { - optional ExtendsWithMessage optional_extension = 19; - repeated ExtendsWithMessage repeated_extension = 49; - } - optional int32 foo = 1; -} - -extend TestExtendable { - optional int32 extend_optional_int32 = 1; - optional int64 extend_optional_int64 = 2; - optional uint32 extend_optional_uint32 = 3; - optional uint64 extend_optional_uint64 = 4; - optional sint32 extend_optional_sint32 = 5; - optional sint64 extend_optional_sint64 = 6; - optional fixed32 extend_optional_fixed32 = 7; - optional fixed64 extend_optional_fixed64 = 8; - optional sfixed32 extend_optional_sfixed32 = 9; - optional sfixed64 extend_optional_sfixed64 = 10; - optional float extend_optional_float = 11; - optional double extend_optional_double = 12; - optional bool extend_optional_bool = 13; - optional string extend_optional_string = 14; - optional bytes extend_optional_bytes = 15; - optional ForeignEnum extend_optional_foreign_enum = 22; - - repeated int32 extend_repeated_int32 = 31; - repeated int64 extend_repeated_int64 = 32; - repeated uint32 extend_repeated_uint32 = 33; - repeated uint64 extend_repeated_uint64 = 34; - repeated sint32 extend_repeated_sint32 = 35; - repeated sint64 extend_repeated_sint64 = 36; - repeated fixed32 extend_repeated_fixed32 = 37; - repeated fixed64 extend_repeated_fixed64 = 38; - repeated sfixed32 extend_repeated_sfixed32 = 39; - repeated sfixed64 extend_repeated_sfixed64 = 40; - repeated float extend_repeated_float = 41; - repeated double extend_repeated_double = 42; - repeated bool extend_repeated_bool = 43; - repeated string extend_repeated_string = 44; - repeated bytes extend_repeated_bytes = 45; - repeated ForeignEnum extend_repeated_foreign_enum = 52; - - repeated int32 extend_packed_repeated_int32 = 61 [packed=true]; - repeated int64 extend_packed_repeated_int64 = 62 [packed=true]; - repeated uint32 extend_packed_repeated_uint32 = 63 [packed=true]; - repeated uint64 extend_packed_repeated_uint64 = 64 [packed=true]; - repeated sint32 extend_packed_repeated_sint32 = 65 [packed=true]; - repeated sint64 extend_packed_repeated_sint64 = 66 [packed=true]; - repeated fixed32 extend_packed_repeated_fixed32 = 67 [packed=true]; - repeated fixed64 extend_packed_repeated_fixed64 = 68 [packed=true]; - repeated sfixed32 extend_packed_repeated_sfixed32 = 69 [packed=true]; - repeated sfixed64 extend_packed_repeated_sfixed64 = 70 [packed=true]; - repeated float extend_packed_repeated_float = 71 [packed=true]; - repeated double extend_packed_repeated_double = 72 [packed=true]; - repeated bool extend_packed_repeated_bool = 73 [packed=true]; - repeated ForeignEnum extend_packed_repeated_foreign_enum = 82 - [packed=true]; - -} - -message TestMapFields { - map map_string_string = 1; - map map_string_int32 = 2; - map map_string_int64 = 3; - map map_string_bool = 4; - map map_string_double = 5; - map map_string_enum = 6; - map map_string_msg = 7; - - map map_int32_string = 8; - map map_int64_string = 9; - map map_bool_string = 10; - - optional TestMapFields test_map_fields = 11; - map map_string_testmapfields = 12; -} - -enum MapValueEnum { - MAP_VALUE_FOO = 0; - MAP_VALUE_BAR = 1; - MAP_VALUE_BAZ = 2; -} - -message MapValueMessage { - optional int32 foo = 1; -} diff --git a/js/compatibility_tests/v3.0.0/testempty.proto b/js/compatibility_tests/v3.0.0/testempty.proto deleted file mode 100644 index 960bce4e5..000000000 --- a/js/compatibility_tests/v3.0.0/testempty.proto +++ /dev/null @@ -1,34 +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. - -syntax = "proto2"; - -package javatests.com.google.apps.jspb; - diff --git a/js/compatibility_tests/v3.1.0/binary/arith_test.js b/js/compatibility_tests/v3.1.0/binary/arith_test.js deleted file mode 100644 index 89796bf79..000000000 --- a/js/compatibility_tests/v3.1.0/binary/arith_test.js +++ /dev/null @@ -1,355 +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. - -/** - * @fileoverview Test cases for Int64-manipulation functions. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author cfallin@google.com (Chris Fallin) - */ - -goog.require('goog.testing.asserts'); -goog.require('jspb.arith.Int64'); -goog.require('jspb.arith.UInt64'); - - -describe('binaryArithTest', function() { - /** - * Tests comparison operations. - */ - it('testCompare', function() { - var a = new jspb.arith.UInt64(1234, 5678); - var b = new jspb.arith.UInt64(1234, 5678); - assertEquals(a.cmp(b), 0); - assertEquals(b.cmp(a), 0); - b.lo -= 1; - assertEquals(a.cmp(b), 1); - assertEquals(b.cmp(a), -1); - b.lo += 2; - assertEquals(a.cmp(b), -1); - assertEquals(b.cmp(a), 1); - b.lo = a.lo; - b.hi = a.hi - 1; - assertEquals(a.cmp(b), 1); - assertEquals(b.cmp(a), -1); - - assertEquals(a.zero(), false); - assertEquals(a.msb(), false); - assertEquals(a.lsb(), false); - a.hi = 0; - a.lo = 0; - assertEquals(a.zero(), true); - a.hi = 0x80000000; - assertEquals(a.zero(), false); - assertEquals(a.msb(), true); - a.lo = 0x00000001; - assertEquals(a.lsb(), true); - }); - - - /** - * Tests shifts. - */ - it('testShifts', function() { - var a = new jspb.arith.UInt64(1, 0); - assertEquals(a.lo, 1); - assertEquals(a.hi, 0); - var orig = a; - a = a.leftShift(); - assertEquals(orig.lo, 1); // original unmodified. - assertEquals(orig.hi, 0); - assertEquals(a.lo, 2); - assertEquals(a.hi, 0); - a = a.leftShift(); - assertEquals(a.lo, 4); - assertEquals(a.hi, 0); - for (var i = 0; i < 29; i++) { - a = a.leftShift(); - } - assertEquals(a.lo, 0x80000000); - assertEquals(a.hi, 0); - a = a.leftShift(); - assertEquals(a.lo, 0); - assertEquals(a.hi, 1); - a = a.leftShift(); - assertEquals(a.lo, 0); - assertEquals(a.hi, 2); - a = a.rightShift(); - a = a.rightShift(); - assertEquals(a.lo, 0x80000000); - assertEquals(a.hi, 0); - a = a.rightShift(); - assertEquals(a.lo, 0x40000000); - assertEquals(a.hi, 0); - }); - - - /** - * Tests additions. - */ - it('testAdd', function() { - var a = new jspb.arith.UInt64(/* lo = */ 0x89abcdef, - /* hi = */ 0x01234567); - var b = new jspb.arith.UInt64(/* lo = */ 0xff52ab91, - /* hi = */ 0x92fa2123); - // Addition with carry. - var c = a.add(b); - assertEquals(a.lo, 0x89abcdef); // originals unmodified. - assertEquals(a.hi, 0x01234567); - assertEquals(b.lo, 0xff52ab91); - assertEquals(b.hi, 0x92fa2123); - assertEquals(c.lo, 0x88fe7980); - assertEquals(c.hi, 0x941d668b); - - // Simple addition without carry. - a.lo = 2; - a.hi = 0; - b.lo = 3; - b.hi = 0; - c = a.add(b); - assertEquals(c.lo, 5); - assertEquals(c.hi, 0); - }); - - - /** - * Test subtractions. - */ - it('testSub', function() { - var kLength = 10; - var hiValues = [0x1682ef32, - 0x583902f7, - 0xb62f5955, - 0x6ea99bbf, - 0x25a39c20, - 0x0700a08b, - 0x00f7304d, - 0x91a5b5af, - 0x89077fd2, - 0xe09e347c]; - var loValues = [0xe1538b18, - 0xbeacd556, - 0x74100758, - 0x96e3cb26, - 0x56c37c3f, - 0xe00b3f7d, - 0x859f25d7, - 0xc2ee614a, - 0xe1d21cd7, - 0x30aae6a4]; - for (var i = 0; i < kLength; i++) { - for (var j = 0; j < kLength; j++) { - var a = new jspb.arith.UInt64(loValues[i], hiValues[j]); - var b = new jspb.arith.UInt64(loValues[j], hiValues[i]); - var c = a.add(b).sub(b); - assertEquals(c.hi, a.hi); - assertEquals(c.lo, a.lo); - } - } - }); - - - /** - * Tests 32-by-32 multiplication. - */ - it('testMul32x32', function() { - var testData = [ - // a b low(a*b) high(a*b) - [0xc0abe2f8, 0x1607898a, 0x5de711b0, 0x109471b8], - [0x915eb3cb, 0x4fb66d0e, 0xbd0d441a, 0x2d43d0bc], - [0xfe4efe70, 0x80b48c37, 0xbcddea10, 0x7fdada0c], - [0xe222fd4a, 0xe43d524a, 0xd5e0eb64, 0xc99d549c], - [0xd171f469, 0xb94ebd01, 0x4be17969, 0x979bc4fa], - [0x829cc1df, 0xe2598b38, 0xf4157dc8, 0x737c12ad], - [0xf10c3767, 0x8382881e, 0x942b3612, 0x7bd428b8], - [0xb0f6dd24, 0x232597e1, 0x079c98a4, 0x184bbce7], - [0xfcdb05a7, 0x902f55bc, 0x636199a4, 0x8e69f412], - [0x0dd0bfa9, 0x916e27b1, 0x6e2542d9, 0x07d92e65] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = testData[i][0] >>> 0; - var b = testData[i][1] >>> 0; - var cLow = testData[i][2] >>> 0; - var cHigh = testData[i][3] >>> 0; - var c = jspb.arith.UInt64.mul32x32(a, b); - assertEquals(c.lo, cLow); - assertEquals(c.hi, cHigh); - } - }); - - - /** - * Tests 64-by-32 multiplication. - */ - it('testMul', function() { - // 64x32 bits produces 96 bits of product. The multiplication function under - // test truncates the top 32 bits, so we compare against a 64-bit expected - // product. - var testData = [ - // low(a) high(a) low(a*b) high(a*b) - [0xec10955b, 0x360eb168, 0x4b7f3f5b, 0xbfcb7c59, 0x9517da5f], - [0x42b000fc, 0x9d101642, 0x6fa1ab72, 0x2584c438, 0x6a9e6d2b], - [0xf42d4fb4, 0xae366403, 0xa65a1000, 0x92434000, 0x1ff978df], - [0x17e2f56b, 0x25487693, 0xf13f98c7, 0x73794e2d, 0xa96b0c6a], - [0x492f241f, 0x76c0eb67, 0x7377ac44, 0xd4336c3c, 0xfc4b1ebe], - [0xd6b92321, 0xe184fa48, 0xd6e76904, 0x93141584, 0xcbf44da1], - [0x4bf007ea, 0x968c0a9e, 0xf5e4026a, 0x4fdb1ae4, 0x61b9fb7d], - [0x10a83be7, 0x2d685ba6, 0xc9e5fb7f, 0x2ad43499, 0x3742473d], - [0x2f261829, 0x1aca681a, 0x3d3494e3, 0x8213205b, 0x283719f8], - [0xe4f2ce21, 0x2e74b7bd, 0xd801b38b, 0xbc17feeb, 0xc6c44e0f] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); - var prod = a.mul(testData[i][2]); - assertEquals(prod.lo, testData[i][3]); - assertEquals(prod.hi, testData[i][4]); - } - }); - - - /** - * Tests 64-div-by-32 division. - */ - it('testDiv', function() { - // Compute a/b, yielding quot = a/b and rem = a%b. - var testData = [ - // --- divisors in (0, 2^32-1) to test full divisor range - // low(a) high(a) b low(quot) high(quot) rem - [0x712443f1, 0xe85cefcc, 0xc1a7050b, 0x332c79ad, 0x00000001, 0x92ffa882], - [0x11912915, 0xb2699eb5, 0x30467cbe, 0xb21b4be4, 0x00000003, 0x283465dd], - [0x0d917982, 0x201f2a6e, 0x3f35bf03, 0x8217c8e4, 0x00000000, 0x153402d6], - [0xa072c108, 0x74020c96, 0xc60568fd, 0x95f9613e, 0x00000000, 0x3f4676c2], - [0xd845d5d8, 0xcdd235c4, 0x20426475, 0x6154e78b, 0x00000006, 0x202fb751], - [0xa4dbf71f, 0x9e90465e, 0xf08e022f, 0xa8be947f, 0x00000000, 0xbe43b5ce], - [0x3dbe627f, 0xa791f4b9, 0x28a5bd89, 0x1f5dfe93, 0x00000004, 0x02bf9ed4], - [0x5c1c53ee, 0xccf5102e, 0x198576e7, 0x07e3ae31, 0x00000008, 0x02ea8fb7], - [0xfef1e581, 0x04714067, 0xca6540c1, 0x059e73ec, 0x00000000, 0x31658095], - [0x1e2dd90c, 0x13dd6667, 0x8b2184c3, 0x248d1a42, 0x00000000, 0x4ca6d0c6], - // --- divisors in (0, 2^16-1) to test larger quotient high-words - // low(a) high(a) b low(quot) high(quot) rem - [0x86722b47, 0x2cd57c9a, 0x00003123, 0x2ae41b7a, 0x0000e995, 0x00000f99], - [0x1dd7884c, 0xf5e839bc, 0x00009eeb, 0x5c886242, 0x00018c21, 0x000099b6], - [0x5c53d625, 0x899fc7e5, 0x000087d7, 0xd625007a, 0x0001035c, 0x000019af], - [0x6932d932, 0x9d0a5488, 0x000051fb, 0x9d976143, 0x0001ea63, 0x00004981], - [0x4d18bb85, 0x0c92fb31, 0x00001d9f, 0x03265ab4, 0x00006cac, 0x000001b9], - [0xbe756768, 0xdea67ccb, 0x00008a03, 0x58add442, 0x00019cff, 0x000056a2], - [0xe2466f9a, 0x2521f114, 0x0000c350, 0xa0c0860d, 0x000030ab, 0x0000a48a], - [0xf00ddad1, 0xe2f5446a, 0x00002cfc, 0x762697a6, 0x00050b96, 0x00000b69], - [0xa879152a, 0x0a70e0a5, 0x00007cdf, 0xb44151b3, 0x00001567, 0x0000363d], - [0x7179a74c, 0x46083fff, 0x0000253c, 0x4d39ba6e, 0x0001e17f, 0x00000f84] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); - var result = a.div(testData[i][2]); - var quotient = result[0]; - var remainder = result[1]; - assertEquals(quotient.lo, testData[i][3]); - assertEquals(quotient.hi, testData[i][4]); - assertEquals(remainder.lo, testData[i][5]); - } - }); - - - /** - * Tests .toString() and .fromString(). - */ - it('testStrings', function() { - var testData = [ - [0x5e84c935, 0xcae33d0e, '14619595947299359029'], - [0x62b3b8b8, 0x93480544, '10612738313170434232'], - [0x319bfb13, 0xc01c4172, '13843011313344445203'], - [0x5b8a65fb, 0xa5885b31, '11927883880638080507'], - [0x6bdb80f1, 0xb0d1b16b, '12741159895737008369'], - [0x4b82b442, 0x2e0d8c97, '3318463081876730946'], - [0x780d5208, 0x7d76752c, '9040542135845999112'], - [0x2e46800f, 0x0993778d, '690026616168284175'], - [0xf00a7e32, 0xcd8e3931, '14811839111111540274'], - [0x1baeccd6, 0x923048c4, '10533999535534820566'], - [0x03669d29, 0xbff3ab72, '13831587386756603177'], - [0x2526073e, 0x01affc81, '121593346566522686'], - [0xc24244e0, 0xd7f40d0e, '15561076969511732448'], - [0xc56a341e, 0xa68b66a7, '12000798502816461854'], - [0x8738d64d, 0xbfe78604, '13828168534871037517'], - [0x5baff03b, 0xd7572aea, '15516918227177304123'], - [0x4a843d8a, 0x864e132b, '9677693725920476554'], - [0x25b4e94d, 0x22b54dc6, '2500990681505655117'], - [0x6bbe664b, 0x55a5cc0e, '6171563226690381387'], - [0xee916c81, 0xb00aabb3, '12685140089732426881'] - ]; - - for (var i = 0; i < testData.length; i++) { - var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]); - var roundtrip = jspb.arith.UInt64.fromString(a.toString()); - assertEquals(roundtrip.lo, a.lo); - assertEquals(roundtrip.hi, a.hi); - assertEquals(a.toString(), testData[i][2]); - } - }); - - - /** - * Tests signed Int64s. These are built on UInt64s, so we only need to test - * the explicit overrides: .toString() and .fromString(). - */ - it('testSignedInt64', function() { - var testStrings = [ - '-7847499644178593666', - '3771946501229139523', - '2872856549054995060', - '-5780049594274350904', - '3383785956695105201', - '2973055184857072610', - '-3879428459215627206', - '4589812431064156631', - '8484075557333689940', - '1075325817098092407', - '-4346697501012292314', - '2488620459718316637', - '6112655187423520672', - '-3655278273928612104', - '3439154019435803196', - '1004112478843763757', - '-6587790776614368413', - '664320065099714586', - '4760412909973292912', - '-7911903989602274672' - ]; - - for (var i = 0; i < testStrings.length; i++) { - var roundtrip = - jspb.arith.Int64.fromString(testStrings[i]).toString(); - assertEquals(roundtrip, testStrings[i]); - } - }); -}); diff --git a/js/compatibility_tests/v3.1.0/binary/decoder_test.js b/js/compatibility_tests/v3.1.0/binary/decoder_test.js deleted file mode 100644 index 01100fd45..000000000 --- a/js/compatibility_tests/v3.1.0/binary/decoder_test.js +++ /dev/null @@ -1,327 +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. - -/** - * @fileoverview Test cases for jspb's binary protocol buffer decoder. - * - * There are two particular magic numbers that need to be pointed out - - * 2^64-1025 is the largest number representable as both a double and an - * unsigned 64-bit integer, and 2^63-513 is the largest number representable as - * both a double and a signed 64-bit integer. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryDecoder'); -goog.require('jspb.BinaryEncoder'); - - -/** - * Tests encoding and decoding of unsigned types. - * @param {Function} readValue - * @param {Function} writeValue - * @param {number} epsilon - * @param {number} upperLimit - * @param {Function} filter - * @suppress {missingProperties|visibility} - */ -function doTestUnsignedValue(readValue, - writeValue, epsilon, upperLimit, filter) { - var encoder = new jspb.BinaryEncoder(); - - // Encode zero and limits. - writeValue.call(encoder, filter(0)); - writeValue.call(encoder, filter(epsilon)); - writeValue.call(encoder, filter(upperLimit)); - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - writeValue.call(encoder, filter(cursor)); - } - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - // Check zero and limits. - assertEquals(filter(0), readValue.call(decoder)); - assertEquals(filter(epsilon), readValue.call(decoder)); - assertEquals(filter(upperLimit), readValue.call(decoder)); - - // Check positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - if (filter(cursor) != readValue.call(decoder)) throw 'fail!'; - } - - // Encoding values outside the valid range should assert. - assertThrows(function() {writeValue.call(encoder, -1);}); - assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);}); -} - - -/** - * Tests encoding and decoding of signed types. - * @param {Function} readValue - * @param {Function} writeValue - * @param {number} epsilon - * @param {number} lowerLimit - * @param {number} upperLimit - * @param {Function} filter - * @suppress {missingProperties} - */ -function doTestSignedValue(readValue, - writeValue, epsilon, lowerLimit, upperLimit, filter) { - var encoder = new jspb.BinaryEncoder(); - - // Encode zero and limits. - writeValue.call(encoder, filter(lowerLimit)); - writeValue.call(encoder, filter(-epsilon)); - writeValue.call(encoder, filter(0)); - writeValue.call(encoder, filter(epsilon)); - writeValue.call(encoder, filter(upperLimit)); - - var inputValues = []; - - // Encode negative values. - for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) { - var val = filter(cursor); - writeValue.call(encoder, val); - inputValues.push(val); - } - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - var val = filter(cursor); - writeValue.call(encoder, val); - inputValues.push(val); - } - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - // Check zero and limits. - assertEquals(filter(lowerLimit), readValue.call(decoder)); - assertEquals(filter(-epsilon), readValue.call(decoder)); - assertEquals(filter(0), readValue.call(decoder)); - assertEquals(filter(epsilon), readValue.call(decoder)); - assertEquals(filter(upperLimit), readValue.call(decoder)); - - // Verify decoded values. - for (var i = 0; i < inputValues.length; i++) { - assertEquals(inputValues[i], readValue.call(decoder)); - } - - // Encoding values outside the valid range should assert, except for doubles - // whose range runs all the way to infinity. - var pastLowerLimit = lowerLimit * 1.1; - var pastUpperLimit = upperLimit * 1.1; - if (pastLowerLimit !== -Infinity) { - expect(function() { - writeValue.call(encoder, lowerLimit * 1.1); - }).toThrow(); - } - if (pastUpperLimit !== Infinity) { - expect(function() { - writeValue.call(encoder, upperLimit * 1.1); - }).toThrow(); - } -} - -describe('binaryDecoderTest', function() { - /** - * Tests the decoder instance cache. - */ - it('testInstanceCache', /** @suppress {visibility} */ function() { - // Empty the instance caches. - jspb.BinaryDecoder.instanceCache_ = []; - - // Allocating and then freeing a decoder should put it in the instance - // cache. - jspb.BinaryDecoder.alloc().free(); - - assertEquals(1, jspb.BinaryDecoder.instanceCache_.length); - - // Allocating and then freeing three decoders should leave us with three in - // the cache. - - var decoder1 = jspb.BinaryDecoder.alloc(); - var decoder2 = jspb.BinaryDecoder.alloc(); - var decoder3 = jspb.BinaryDecoder.alloc(); - decoder1.free(); - decoder2.free(); - decoder3.free(); - - assertEquals(3, jspb.BinaryDecoder.instanceCache_.length); - }); - - - /** - * Tests reading 64-bit integers as hash strings. - */ - it('testHashStrings', function() { - var encoder = new jspb.BinaryEncoder(); - - var hashA = String.fromCharCode(0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00); - var hashB = String.fromCharCode(0x12, 0x34, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00); - var hashC = String.fromCharCode(0x12, 0x34, 0x56, 0x78, - 0x87, 0x65, 0x43, 0x21); - var hashD = String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF); - - encoder.writeVarintHash64(hashA); - encoder.writeVarintHash64(hashB); - encoder.writeVarintHash64(hashC); - encoder.writeVarintHash64(hashD); - - encoder.writeFixedHash64(hashA); - encoder.writeFixedHash64(hashB); - encoder.writeFixedHash64(hashC); - encoder.writeFixedHash64(hashD); - - var decoder = jspb.BinaryDecoder.alloc(encoder.end()); - - assertEquals(hashA, decoder.readVarintHash64()); - assertEquals(hashB, decoder.readVarintHash64()); - assertEquals(hashC, decoder.readVarintHash64()); - assertEquals(hashD, decoder.readVarintHash64()); - - assertEquals(hashA, decoder.readFixedHash64()); - assertEquals(hashB, decoder.readFixedHash64()); - assertEquals(hashC, decoder.readFixedHash64()); - assertEquals(hashD, decoder.readFixedHash64()); - }); - - - /** - * Verifies that misuse of the decoder class triggers assertions. - */ - it('testDecodeErrors', function() { - // Reading a value past the end of the stream should trigger an assertion. - var decoder = jspb.BinaryDecoder.alloc([0, 1, 2]); - assertThrows(function() {decoder.readUint64()}); - - // Overlong varints should trigger assertions. - decoder.setBlock([255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 0]); - assertThrows(function() {decoder.readUnsignedVarint64()}); - decoder.reset(); - assertThrows(function() {decoder.readSignedVarint64()}); - decoder.reset(); - assertThrows(function() {decoder.readZigzagVarint64()}); - decoder.reset(); - assertThrows(function() {decoder.readUnsignedVarint32()}); - }); - - - /** - * Tests encoding and decoding of unsigned integers. - */ - it('testUnsignedIntegers', function() { - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint8, - jspb.BinaryEncoder.prototype.writeUint8, - 1, 0xFF, Math.round); - - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint16, - jspb.BinaryEncoder.prototype.writeUint16, - 1, 0xFFFF, Math.round); - - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint32, - jspb.BinaryEncoder.prototype.writeUint32, - 1, 0xFFFFFFFF, Math.round); - - doTestUnsignedValue( - jspb.BinaryDecoder.prototype.readUint64, - jspb.BinaryEncoder.prototype.writeUint64, - 1, Math.pow(2, 64) - 1025, Math.round); - }); - - - /** - * Tests encoding and decoding of signed integers. - */ - it('testSignedIntegers', function() { - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt8, - jspb.BinaryEncoder.prototype.writeInt8, - 1, -0x80, 0x7F, Math.round); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt16, - jspb.BinaryEncoder.prototype.writeInt16, - 1, -0x8000, 0x7FFF, Math.round); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt32, - jspb.BinaryEncoder.prototype.writeInt32, - 1, -0x80000000, 0x7FFFFFFF, Math.round); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readInt64, - jspb.BinaryEncoder.prototype.writeInt64, - 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); - }); - - - /** - * Tests encoding and decoding of floats. - */ - it('testFloats', function() { - /** - * @param {number} x - * @return {number} - */ - function truncate(x) { - var temp = new Float32Array(1); - temp[0] = x; - return temp[0]; - } - doTestSignedValue( - jspb.BinaryDecoder.prototype.readFloat, - jspb.BinaryEncoder.prototype.writeFloat, - jspb.BinaryConstants.FLOAT32_EPS, - -jspb.BinaryConstants.FLOAT32_MAX, - jspb.BinaryConstants.FLOAT32_MAX, - truncate); - - doTestSignedValue( - jspb.BinaryDecoder.prototype.readDouble, - jspb.BinaryEncoder.prototype.writeDouble, - jspb.BinaryConstants.FLOAT64_EPS * 10, - -jspb.BinaryConstants.FLOAT64_MAX, - jspb.BinaryConstants.FLOAT64_MAX, - function(x) { return x; }); - }); -}); diff --git a/js/compatibility_tests/v3.1.0/binary/proto_test.js b/js/compatibility_tests/v3.1.0/binary/proto_test.js deleted file mode 100644 index ff9d97262..000000000 --- a/js/compatibility_tests/v3.1.0/binary/proto_test.js +++ /dev/null @@ -1,628 +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. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - -goog.require('goog.crypt.base64'); -goog.require('goog.testing.asserts'); -goog.require('jspb.Message'); - -// CommonJS-LoadFromFile: ../testbinary_pb proto.jspb.test -goog.require('proto.jspb.test.ExtendsWithMessage'); -goog.require('proto.jspb.test.ForeignEnum'); -goog.require('proto.jspb.test.ForeignMessage'); -goog.require('proto.jspb.test.TestAllTypes'); -goog.require('proto.jspb.test.TestExtendable'); -goog.require('proto.jspb.test.extendOptionalBool'); -goog.require('proto.jspb.test.extendOptionalBytes'); -goog.require('proto.jspb.test.extendOptionalDouble'); -goog.require('proto.jspb.test.extendOptionalFixed32'); -goog.require('proto.jspb.test.extendOptionalFixed64'); -goog.require('proto.jspb.test.extendOptionalFloat'); -goog.require('proto.jspb.test.extendOptionalForeignEnum'); -goog.require('proto.jspb.test.extendOptionalInt32'); -goog.require('proto.jspb.test.extendOptionalInt64'); -goog.require('proto.jspb.test.extendOptionalSfixed32'); -goog.require('proto.jspb.test.extendOptionalSfixed64'); -goog.require('proto.jspb.test.extendOptionalSint32'); -goog.require('proto.jspb.test.extendOptionalSint64'); -goog.require('proto.jspb.test.extendOptionalString'); -goog.require('proto.jspb.test.extendOptionalUint32'); -goog.require('proto.jspb.test.extendOptionalUint64'); -goog.require('proto.jspb.test.extendPackedRepeatedBoolList'); -goog.require('proto.jspb.test.extendPackedRepeatedDoubleList'); -goog.require('proto.jspb.test.extendPackedRepeatedFixed32List'); -goog.require('proto.jspb.test.extendPackedRepeatedFixed64List'); -goog.require('proto.jspb.test.extendPackedRepeatedFloatList'); -goog.require('proto.jspb.test.extendPackedRepeatedForeignEnumList'); -goog.require('proto.jspb.test.extendPackedRepeatedInt32List'); -goog.require('proto.jspb.test.extendPackedRepeatedInt64List'); -goog.require('proto.jspb.test.extendPackedRepeatedSfixed32List'); -goog.require('proto.jspb.test.extendPackedRepeatedSfixed64List'); -goog.require('proto.jspb.test.extendPackedRepeatedSint32List'); -goog.require('proto.jspb.test.extendPackedRepeatedSint64List'); -goog.require('proto.jspb.test.extendPackedRepeatedUint32List'); -goog.require('proto.jspb.test.extendPackedRepeatedUint64List'); -goog.require('proto.jspb.test.extendRepeatedBoolList'); -goog.require('proto.jspb.test.extendRepeatedBytesList'); -goog.require('proto.jspb.test.extendRepeatedDoubleList'); -goog.require('proto.jspb.test.extendRepeatedFixed32List'); -goog.require('proto.jspb.test.extendRepeatedFixed64List'); -goog.require('proto.jspb.test.extendRepeatedFloatList'); -goog.require('proto.jspb.test.extendRepeatedForeignEnumList'); -goog.require('proto.jspb.test.extendRepeatedInt32List'); -goog.require('proto.jspb.test.extendRepeatedInt64List'); -goog.require('proto.jspb.test.extendRepeatedSfixed32List'); -goog.require('proto.jspb.test.extendRepeatedSfixed64List'); -goog.require('proto.jspb.test.extendRepeatedSint32List'); -goog.require('proto.jspb.test.extendRepeatedSint64List'); -goog.require('proto.jspb.test.extendRepeatedStringList'); -goog.require('proto.jspb.test.extendRepeatedUint32List'); -goog.require('proto.jspb.test.extendRepeatedUint64List'); - - -var suite = {}; - -var BYTES = new Uint8Array([1, 2, 8, 9]); - -var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES); - - -/** - * Helper: fill all fields on a TestAllTypes message. - * @param {proto.jspb.test.TestAllTypes} msg - */ -function fillAllFields(msg) { - msg.setOptionalInt32(-42); - // can be exactly represented by JS number (64-bit double, i.e., 52-bit - // mantissa). - msg.setOptionalInt64(-0x7fffffff00000000); - msg.setOptionalUint32(0x80000000); - msg.setOptionalUint64(0xf000000000000000); - msg.setOptionalSint32(-100); - msg.setOptionalSint64(-0x8000000000000000); - msg.setOptionalFixed32(1234); - msg.setOptionalFixed64(0x1234567800000000); - msg.setOptionalSfixed32(-1234); - msg.setOptionalSfixed64(-0x1234567800000000); - msg.setOptionalFloat(1.5); - msg.setOptionalDouble(-1.5); - msg.setOptionalBool(true); - msg.setOptionalString('hello world'); - msg.setOptionalBytes(BYTES); - msg.setOptionalGroup(new proto.jspb.test.TestAllTypes.OptionalGroup()); - msg.getOptionalGroup().setA(100); - var submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(16); - msg.setOptionalForeignMessage(submsg); - msg.setOptionalForeignEnum(proto.jspb.test.ForeignEnum.FOREIGN_FOO); - msg.setOneofString('oneof'); - - - msg.setRepeatedInt32List([-42]); - msg.setRepeatedInt64List([-0x7fffffff00000000]); - msg.setRepeatedUint32List([0x80000000]); - msg.setRepeatedUint64List([0xf000000000000000]); - msg.setRepeatedSint32List([-100]); - msg.setRepeatedSint64List([-0x8000000000000000]); - msg.setRepeatedFixed32List([1234]); - msg.setRepeatedFixed64List([0x1234567800000000]); - msg.setRepeatedSfixed32List([-1234]); - msg.setRepeatedSfixed64List([-0x1234567800000000]); - msg.setRepeatedFloatList([1.5]); - msg.setRepeatedDoubleList([-1.5]); - msg.setRepeatedBoolList([true]); - msg.setRepeatedStringList(['hello world']); - msg.setRepeatedBytesList([BYTES, BYTES]); - msg.setRepeatedGroupList([new proto.jspb.test.TestAllTypes.RepeatedGroup()]); - msg.getRepeatedGroupList()[0].setA(100); - submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(1000); - msg.setRepeatedForeignMessageList([submsg]); - msg.setRepeatedForeignEnumList([proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - msg.setPackedRepeatedInt32List([-42]); - msg.setPackedRepeatedInt64List([-0x7fffffff00000000]); - msg.setPackedRepeatedUint32List([0x80000000]); - msg.setPackedRepeatedUint64List([0xf000000000000000]); - msg.setPackedRepeatedSint32List([-100]); - msg.setPackedRepeatedSint64List([-0x8000000000000000]); - msg.setPackedRepeatedFixed32List([1234]); - msg.setPackedRepeatedFixed64List([0x1234567800000000]); - msg.setPackedRepeatedSfixed32List([-1234]); - msg.setPackedRepeatedSfixed64List([-0x1234567800000000]); - msg.setPackedRepeatedFloatList([1.5]); - msg.setPackedRepeatedDoubleList([-1.5]); - msg.setPackedRepeatedBoolList([true]); - -} - - -/** - * Helper: compare a bytes field to an expected value - * @param {Uint8Array|string} arr - * @param {Uint8Array} expected - * @return {boolean} - */ -function bytesCompare(arr, expected) { - if (typeof arr === 'string') { - arr = goog.crypt.base64.decodeStringToUint8Array(arr); - } - if (arr.length != expected.length) { - return false; - } - for (var i = 0; i < arr.length; i++) { - if (arr[i] != expected[i]) { - return false; - } - } - return true; -} - - -/** - * Helper: verify contents of given TestAllTypes message as set by - * fillAllFields(). - * @param {proto.jspb.test.TestAllTypes} original - * @param {proto.jspb.test.TestAllTypes} copy - */ -function checkAllFields(original, copy) { - assertTrue(jspb.Message.equals(original, copy)); - - assertEquals(copy.getOptionalInt32(), -42); - assertEquals(copy.getOptionalInt64(), -0x7fffffff00000000); - assertEquals(copy.getOptionalUint32(), 0x80000000); - assertEquals(copy.getOptionalUint64(), 0xf000000000000000); - assertEquals(copy.getOptionalSint32(), -100); - assertEquals(copy.getOptionalSint64(), -0x8000000000000000); - assertEquals(copy.getOptionalFixed32(), 1234); - assertEquals(copy.getOptionalFixed64(), 0x1234567800000000); - assertEquals(copy.getOptionalSfixed32(), -1234); - assertEquals(copy.getOptionalSfixed64(), -0x1234567800000000); - assertEquals(copy.getOptionalFloat(), 1.5); - assertEquals(copy.getOptionalDouble(), -1.5); - assertEquals(copy.getOptionalBool(), true); - assertEquals(copy.getOptionalString(), 'hello world'); - assertEquals(true, bytesCompare(copy.getOptionalBytes(), BYTES)); - assertEquals(true, bytesCompare(copy.getOptionalBytes_asU8(), BYTES)); - assertEquals( - copy.getOptionalBytes_asB64(), goog.crypt.base64.encodeByteArray(BYTES)); - - assertEquals(copy.getOptionalGroup().getA(), 100); - assertEquals(copy.getOptionalForeignMessage().getC(), 16); - assertEquals(copy.getOptionalForeignEnum(), - proto.jspb.test.ForeignEnum.FOREIGN_FOO); - - - assertEquals(copy.getOneofString(), 'oneof'); - assertEquals(copy.getOneofFieldCase(), - proto.jspb.test.TestAllTypes.OneofFieldCase.ONEOF_STRING); - - assertElementsEquals(copy.getRepeatedInt32List(), [-42]); - assertElementsEquals(copy.getRepeatedInt64List(), [-0x7fffffff00000000]); - assertElementsEquals(copy.getRepeatedUint32List(), [0x80000000]); - assertElementsEquals(copy.getRepeatedUint64List(), [0xf000000000000000]); - assertElementsEquals(copy.getRepeatedSint32List(), [-100]); - assertElementsEquals(copy.getRepeatedSint64List(), [-0x8000000000000000]); - assertElementsEquals(copy.getRepeatedFixed32List(), [1234]); - assertElementsEquals(copy.getRepeatedFixed64List(), [0x1234567800000000]); - assertElementsEquals(copy.getRepeatedSfixed32List(), [-1234]); - assertElementsEquals(copy.getRepeatedSfixed64List(), [-0x1234567800000000]); - assertElementsEquals(copy.getRepeatedFloatList(), [1.5]); - assertElementsEquals(copy.getRepeatedDoubleList(), [-1.5]); - assertElementsEquals(copy.getRepeatedBoolList(), [true]); - assertElementsEquals(copy.getRepeatedStringList(), ['hello world']); - assertEquals(copy.getRepeatedBytesList().length, 2); - assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[0], BYTES)); - assertEquals(true, bytesCompare(copy.getRepeatedBytesList()[0], BYTES)); - assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[1], BYTES)); - assertEquals(copy.getRepeatedBytesList_asB64()[0], BYTES_B64); - assertEquals(copy.getRepeatedBytesList_asB64()[1], BYTES_B64); - assertEquals(copy.getRepeatedGroupList().length, 1); - assertEquals(copy.getRepeatedGroupList()[0].getA(), 100); - assertEquals(copy.getRepeatedForeignMessageList().length, 1); - assertEquals(copy.getRepeatedForeignMessageList()[0].getC(), 1000); - assertElementsEquals(copy.getRepeatedForeignEnumList(), - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - assertElementsEquals(copy.getPackedRepeatedInt32List(), [-42]); - assertElementsEquals(copy.getPackedRepeatedInt64List(), - [-0x7fffffff00000000]); - assertElementsEquals(copy.getPackedRepeatedUint32List(), [0x80000000]); - assertElementsEquals(copy.getPackedRepeatedUint64List(), - [0xf000000000000000]); - assertElementsEquals(copy.getPackedRepeatedSint32List(), [-100]); - assertElementsEquals(copy.getPackedRepeatedSint64List(), - [-0x8000000000000000]); - assertElementsEquals(copy.getPackedRepeatedFixed32List(), [1234]); - assertElementsEquals(copy.getPackedRepeatedFixed64List(), - [0x1234567800000000]); - assertElementsEquals(copy.getPackedRepeatedSfixed32List(), [-1234]); - assertElementsEquals(copy.getPackedRepeatedSfixed64List(), - [-0x1234567800000000]); - assertElementsEquals(copy.getPackedRepeatedFloatList(), [1.5]); - assertElementsEquals(copy.getPackedRepeatedDoubleList(), [-1.5]); - -} - - -/** - * Helper: verify that all expected extensions are present. - * @param {!proto.jspb.test.TestExtendable} msg - */ -function checkExtensions(msg) { - assertEquals(-42, - msg.getExtension(proto.jspb.test.extendOptionalInt32)); - assertEquals(-0x7fffffff00000000, - msg.getExtension(proto.jspb.test.extendOptionalInt64)); - assertEquals(0x80000000, - msg.getExtension(proto.jspb.test.extendOptionalUint32)); - assertEquals(0xf000000000000000, - msg.getExtension(proto.jspb.test.extendOptionalUint64)); - assertEquals(-100, - msg.getExtension(proto.jspb.test.extendOptionalSint32)); - assertEquals(-0x8000000000000000, - msg.getExtension(proto.jspb.test.extendOptionalSint64)); - assertEquals(1234, - msg.getExtension(proto.jspb.test.extendOptionalFixed32)); - assertEquals(0x1234567800000000, - msg.getExtension(proto.jspb.test.extendOptionalFixed64)); - assertEquals(-1234, - msg.getExtension(proto.jspb.test.extendOptionalSfixed32)); - assertEquals(-0x1234567800000000, - msg.getExtension(proto.jspb.test.extendOptionalSfixed64)); - assertEquals(1.5, - msg.getExtension(proto.jspb.test.extendOptionalFloat)); - assertEquals(-1.5, - msg.getExtension(proto.jspb.test.extendOptionalDouble)); - assertEquals(true, - msg.getExtension(proto.jspb.test.extendOptionalBool)); - assertEquals('hello world', - msg.getExtension(proto.jspb.test.extendOptionalString)); - assertEquals( - true, bytesCompare( - msg.getExtension(proto.jspb.test.extendOptionalBytes), BYTES)); - assertEquals(16, - msg.getExtension( - proto.jspb.test.ExtendsWithMessage.optionalExtension).getFoo()); - - - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedInt32List), - [-42]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedInt64List), - [-0x7fffffff00000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedUint32List), - [0x80000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedUint64List), - [0xf000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSint32List), - [-100]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSint64List), - [-0x8000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedFixed32List), - [1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedFixed64List), - [0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSfixed32List), - [-1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedSfixed64List), - [-0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedFloatList), - [1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedDoubleList), - [-1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedBoolList), - [true]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedStringList), - ['hello world']); - assertEquals( - true, - bytesCompare( - msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0], BYTES)); - assertEquals(1000, - msg.getExtension( - proto.jspb.test.ExtendsWithMessage.repeatedExtensionList)[0] - .getFoo()); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendRepeatedForeignEnumList), - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedInt32List), - [-42]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedInt64List), - [-0x7fffffff00000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedUint32List), - [0x80000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedUint64List), - [0xf000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSint32List), - [-100]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSint64List), - [-0x8000000000000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed32List), - [1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed64List), - [0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed32List), - [-1234]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed64List), - [-0x1234567800000000]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedFloatList), - [1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedDoubleList), - [-1.5]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedBoolList), - [true]); - assertElementsEquals( - msg.getExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList), - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - -} - - -describe('protoBinaryTest', function() { - /** - * Tests a basic serialization-deserializaton round-trip with all supported - * field types (on the TestAllTypes message type). - */ - it('testRoundTrip', function() { - var msg = new proto.jspb.test.TestAllTypes(); - fillAllFields(msg); - var encoded = msg.serializeBinary(); - var decoded = proto.jspb.test.TestAllTypes.deserializeBinary(encoded); - checkAllFields(msg, decoded); - }); - - /** - * Test that base64 string and Uint8Array are interchangeable in bytes fields. - */ - it('testBytesFieldsGettersInterop', function() { - var msg = new proto.jspb.test.TestAllTypes(); - // Set from a base64 string and check all the getters work. - msg.setOptionalBytes(BYTES_B64); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - // Test binary serialize round trip doesn't break it. - msg = proto.jspb.test.TestAllTypes.deserializeBinary(msg.serializeBinary()); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - msg = new proto.jspb.test.TestAllTypes(); - // Set from a Uint8Array and check all the getters work. - msg.setOptionalBytes(BYTES); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - }); - - /** - * Test that bytes setters will receive result of any of the getters. - */ - it('testBytesFieldsSettersInterop', function() { - var msg = new proto.jspb.test.TestAllTypes(); - msg.setOptionalBytes(BYTES); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - msg.setOptionalBytes(msg.getOptionalBytes()); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - msg.setOptionalBytes(msg.getOptionalBytes_asB64()); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - msg.setOptionalBytes(msg.getOptionalBytes_asU8()); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - }); - - /** - * Test that bytes setters will receive result of any of the getters. - */ - it('testRepeatedBytesGetters', function() { - var msg = new proto.jspb.test.TestAllTypes(); - - function assertGetters() { - assertTrue(typeof msg.getRepeatedBytesList_asB64()[0] === 'string'); - assertTrue(typeof msg.getRepeatedBytesList_asB64()[1] === 'string'); - assertTrue(msg.getRepeatedBytesList_asU8()[0] instanceof Uint8Array); - assertTrue(msg.getRepeatedBytesList_asU8()[1] instanceof Uint8Array); - - assertTrue(bytesCompare(msg.getRepeatedBytesList()[0], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList()[1], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[0], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[1], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[0], BYTES)); - assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[1], BYTES)); - } - - msg.setRepeatedBytesList([BYTES, BYTES]); - assertGetters(); - - msg.setRepeatedBytesList([BYTES_B64, BYTES_B64]); - assertGetters(); - - msg.setRepeatedBytesList([]); - assertEquals(0, msg.getRepeatedBytesList().length); - assertEquals(0, msg.getRepeatedBytesList_asB64().length); - assertEquals(0, msg.getRepeatedBytesList_asU8().length); - }); - - /** - * Helper: fill all extension values. - * @param {proto.jspb.test.TestExtendable} msg - */ - function fillExtensions(msg) { - msg.setExtension( - proto.jspb.test.extendOptionalInt32, -42); - msg.setExtension( - proto.jspb.test.extendOptionalInt64, -0x7fffffff00000000); - msg.setExtension( - proto.jspb.test.extendOptionalUint32, 0x80000000); - msg.setExtension( - proto.jspb.test.extendOptionalUint64, 0xf000000000000000); - msg.setExtension( - proto.jspb.test.extendOptionalSint32, -100); - msg.setExtension( - proto.jspb.test.extendOptionalSint64, -0x8000000000000000); - msg.setExtension( - proto.jspb.test.extendOptionalFixed32, 1234); - msg.setExtension( - proto.jspb.test.extendOptionalFixed64, 0x1234567800000000); - msg.setExtension( - proto.jspb.test.extendOptionalSfixed32, -1234); - msg.setExtension( - proto.jspb.test.extendOptionalSfixed64, -0x1234567800000000); - msg.setExtension( - proto.jspb.test.extendOptionalFloat, 1.5); - msg.setExtension( - proto.jspb.test.extendOptionalDouble, -1.5); - msg.setExtension( - proto.jspb.test.extendOptionalBool, true); - msg.setExtension( - proto.jspb.test.extendOptionalString, 'hello world'); - msg.setExtension(proto.jspb.test.extendOptionalBytes, BYTES); - var submsg = new proto.jspb.test.ExtendsWithMessage(); - submsg.setFoo(16); - msg.setExtension( - proto.jspb.test.ExtendsWithMessage.optionalExtension, submsg); - msg.setExtension( - proto.jspb.test.extendOptionalForeignEnum, - proto.jspb.test.ForeignEnum.FOREIGN_FOO); - - - msg.setExtension( - proto.jspb.test.extendRepeatedInt32List, [-42]); - msg.setExtension( - proto.jspb.test.extendRepeatedInt64List, [-0x7fffffff00000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedUint32List, [0x80000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedUint64List, [0xf000000000000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedSint32List, [-100]); - msg.setExtension( - proto.jspb.test.extendRepeatedSint64List, [-0x8000000000000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedFixed32List, [1234]); - msg.setExtension( - proto.jspb.test.extendRepeatedFixed64List, [0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedSfixed32List, [-1234]); - msg.setExtension( - proto.jspb.test.extendRepeatedSfixed64List, [-0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendRepeatedFloatList, [1.5]); - msg.setExtension( - proto.jspb.test.extendRepeatedDoubleList, [-1.5]); - msg.setExtension( - proto.jspb.test.extendRepeatedBoolList, [true]); - msg.setExtension( - proto.jspb.test.extendRepeatedStringList, ['hello world']); - msg.setExtension(proto.jspb.test.extendRepeatedBytesList, [BYTES]); - submsg = new proto.jspb.test.ExtendsWithMessage(); - submsg.setFoo(1000); - msg.setExtension( - proto.jspb.test.ExtendsWithMessage.repeatedExtensionList, [submsg]); - msg.setExtension(proto.jspb.test.extendRepeatedForeignEnumList, - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - - msg.setExtension( - proto.jspb.test.extendPackedRepeatedInt32List, [-42]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedInt64List, [-0x7fffffff00000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedUint32List, [0x80000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedUint64List, [0xf000000000000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSint32List, [-100]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSint64List, [-0x8000000000000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedFixed32List, [1234]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedFixed64List, [0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSfixed32List, [-1234]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedSfixed64List, - [-0x1234567800000000]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedFloatList, [1.5]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedDoubleList, [-1.5]); - msg.setExtension( - proto.jspb.test.extendPackedRepeatedBoolList, [true]); - msg.setExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList, - [proto.jspb.test.ForeignEnum.FOREIGN_FOO]); - - } - - - /** - * Tests extension serialization and deserialization. - */ - it('testExtensions', function() { - var msg = new proto.jspb.test.TestExtendable(); - fillExtensions(msg); - var encoded = msg.serializeBinary(); - var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded); - checkExtensions(decoded); - }); -}); diff --git a/js/compatibility_tests/v3.1.0/binary/reader_test.js b/js/compatibility_tests/v3.1.0/binary/reader_test.js deleted file mode 100644 index 3b051768a..000000000 --- a/js/compatibility_tests/v3.1.0/binary/reader_test.js +++ /dev/null @@ -1,946 +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. - -/** - * @fileoverview Test cases for jspb's binary protocol buffer reader. - * - * There are two particular magic numbers that need to be pointed out - - * 2^64-1025 is the largest number representable as both a double and an - * unsigned 64-bit integer, and 2^63-513 is the largest number representable as - * both a double and a signed 64-bit integer. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryDecoder'); -goog.require('jspb.BinaryReader'); -goog.require('jspb.BinaryWriter'); -goog.requireType('jspb.BinaryMessage'); - - -describe('binaryReaderTest', function() { - /** - * Tests the reader instance cache. - */ - it('testInstanceCaches', /** @suppress {visibility} */ function() { - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - writer.writeMessage(1, dummyMessage, () => {}); - writer.writeMessage(2, dummyMessage, () => {}); - - var buffer = writer.getResultBuffer(); - - // Empty the instance caches. - jspb.BinaryReader.instanceCache_ = []; - - // Allocating and then freeing three decoders should leave us with three in - // the cache. - - var decoder1 = jspb.BinaryDecoder.alloc(); - var decoder2 = jspb.BinaryDecoder.alloc(); - var decoder3 = jspb.BinaryDecoder.alloc(); - decoder1.free(); - decoder2.free(); - decoder3.free(); - - assertEquals(3, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - - // Allocating and then freeing a reader should remove one decoder from its - // cache, but it should stay stuck to the reader afterwards since we can't - // have a reader without a decoder. - jspb.BinaryReader.alloc().free(); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(1, jspb.BinaryReader.instanceCache_.length); - - // Allocating a reader should remove a reader from the cache. - var reader = jspb.BinaryReader.alloc(buffer); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - - // Processing the message reuses the current reader. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - }); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - }); - - assertEquals(false, reader.nextField()); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(0, jspb.BinaryReader.instanceCache_.length); - - // Freeing the reader should put it back into the cache. - reader.free(); - - assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); - assertEquals(1, jspb.BinaryReader.instanceCache_.length); - }); - - - /** - * @param {number} x - * @return {number} - */ - function truncate(x) { - var temp = new Float32Array(1); - temp[0] = x; - return temp[0]; - } - - - /** - * Verifies that misuse of the reader class triggers assertions. - */ - it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() { - // Calling readMessage on a non-delimited field should trigger an - // assertion. - var reader = jspb.BinaryReader.alloc([8, 1]); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - reader.nextField(); - assertThrows(function() { - reader.readMessage(dummyMessage, () => {}); - }); - - // Reading past the end of the stream should trigger an assertion. - reader = jspb.BinaryReader.alloc([9, 1]); - reader.nextField(); - assertThrows(function() { - reader.readFixed64() - }); - - // Reading past the end of a submessage should trigger an assertion. - reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]); - reader.nextField(); - reader.readMessage(dummyMessage, function() { - reader.nextField(); - assertThrows(function() { - reader.readFixed32() - }); - }); - - // Skipping an invalid field should trigger an assertion. - reader = jspb.BinaryReader.alloc([12, 1]); - reader.nextWireType_ = 1000; - assertThrows(function() { - reader.skipField() - }); - - // Reading fields with the wrong wire type should assert. - reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]); - reader.nextField(); - assertThrows(function() { - reader.readInt32() - }); - assertThrows(function() { - reader.readInt32String() - }); - assertThrows(function() { - reader.readInt64() - }); - assertThrows(function() { - reader.readInt64String() - }); - assertThrows(function() { - reader.readUint32() - }); - assertThrows(function() { - reader.readUint32String() - }); - assertThrows(function() { - reader.readUint64() - }); - assertThrows(function() { - reader.readUint64String() - }); - assertThrows(function() { - reader.readSint32() - }); - assertThrows(function() { - reader.readBool() - }); - assertThrows(function() { - reader.readEnum() - }); - - reader = jspb.BinaryReader.alloc([8, 1]); - reader.nextField(); - assertThrows(function() { - reader.readFixed32() - }); - assertThrows(function() { - reader.readFixed64() - }); - assertThrows(function() { - reader.readSfixed32() - }); - assertThrows(function() { - reader.readSfixed64() - }); - assertThrows(function() { - reader.readFloat() - }); - assertThrows(function() { - reader.readDouble() - }); - - assertThrows(function() { - reader.readString() - }); - assertThrows(function() { - reader.readBytes() - }); - }); - - - /** - * Tests encoding and decoding of unsigned field types. - * @param {Function} readField - * @param {Function} writeField - * @param {number} epsilon - * @param {number} upperLimit - * @param {Function} filter - * @private - * @suppress {missingProperties} - */ - var doTestUnsignedField_ = function( - readField, writeField, epsilon, upperLimit, filter) { - assertNotNull(readField); - assertNotNull(writeField); - - var writer = new jspb.BinaryWriter(); - - // Encode zero and limits. - writeField.call(writer, 1, filter(0)); - writeField.call(writer, 2, filter(epsilon)); - writeField.call(writer, 3, filter(upperLimit)); - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - writeField.call(writer, 4, filter(cursor)); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - // Check zero and limits. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(filter(0), readField.call(reader)); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(filter(epsilon), readField.call(reader)); - - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(filter(upperLimit), readField.call(reader)); - - // Check positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - reader.nextField(); - if (4 != reader.getFieldNumber()) throw 'fail!'; - if (filter(cursor) != readField.call(reader)) throw 'fail!'; - } - }; - - - /** - * Tests encoding and decoding of signed field types. - * @param {Function} readField - * @param {Function} writeField - * @param {number} epsilon - * @param {number} lowerLimit - * @param {number} upperLimit - * @param {Function} filter - * @private - * @suppress {missingProperties} - */ - var doTestSignedField_ = function( - readField, writeField, epsilon, lowerLimit, upperLimit, filter) { - var writer = new jspb.BinaryWriter(); - - // Encode zero and limits. - writeField.call(writer, 1, filter(lowerLimit)); - writeField.call(writer, 2, filter(-epsilon)); - writeField.call(writer, 3, filter(0)); - writeField.call(writer, 4, filter(epsilon)); - writeField.call(writer, 5, filter(upperLimit)); - - var inputValues = []; - - // Encode negative values. - for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) { - var val = filter(cursor); - writeField.call(writer, 6, val); - inputValues.push({fieldNumber: 6, value: val}); - } - - // Encode positive values. - for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { - var val = filter(cursor); - writeField.call(writer, 7, val); - inputValues.push({fieldNumber: 7, value: val}); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - // Check zero and limits. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(filter(lowerLimit), readField.call(reader)); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(filter(-epsilon), readField.call(reader)); - - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(filter(0), readField.call(reader)); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(filter(epsilon), readField.call(reader)); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(filter(upperLimit), readField.call(reader)); - - for (var i = 0; i < inputValues.length; i++) { - var expected = inputValues[i]; - reader.nextField(); - assertEquals(expected.fieldNumber, reader.getFieldNumber()); - assertEquals(expected.value, readField.call(reader)); - } - }; - - - /** - * Tests fields that use varint encoding. - */ - it('testVarintFields', function() { - assertNotUndefined(jspb.BinaryReader.prototype.readUint32); - assertNotUndefined(jspb.BinaryWriter.prototype.writeUint32); - assertNotUndefined(jspb.BinaryReader.prototype.readUint64); - assertNotUndefined(jspb.BinaryWriter.prototype.writeUint64); - assertNotUndefined(jspb.BinaryReader.prototype.readBool); - assertNotUndefined(jspb.BinaryWriter.prototype.writeBool); - doTestUnsignedField_( - jspb.BinaryReader.prototype.readUint32, - jspb.BinaryWriter.prototype.writeUint32, 1, Math.pow(2, 32) - 1, - Math.round); - - doTestUnsignedField_( - jspb.BinaryReader.prototype.readUint64, - jspb.BinaryWriter.prototype.writeUint64, 1, Math.pow(2, 64) - 1025, - Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readInt32, - jspb.BinaryWriter.prototype.writeInt32, 1, -Math.pow(2, 31), - Math.pow(2, 31) - 1, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readInt64, - jspb.BinaryWriter.prototype.writeInt64, 1, -Math.pow(2, 63), - Math.pow(2, 63) - 513, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readEnum, - jspb.BinaryWriter.prototype.writeEnum, 1, -Math.pow(2, 31), - Math.pow(2, 31) - 1, Math.round); - - doTestUnsignedField_( - jspb.BinaryReader.prototype.readBool, - jspb.BinaryWriter.prototype.writeBool, 1, 1, function(x) { - return !!x; - }); - }); - - - /** - * Tests reading a field from hexadecimal string (format: '08 BE EF'). - * @param {Function} readField - * @param {number} expected - * @param {string} hexString - */ - function doTestHexStringVarint_(readField, expected, hexString) { - var bytesCount = (hexString.length + 1) / 3; - var bytes = new Uint8Array(bytesCount); - for (var i = 0; i < bytesCount; i++) { - bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16); - } - var reader = jspb.BinaryReader.alloc(bytes); - reader.nextField(); - assertEquals(expected, readField.call(reader)); - } - - - /** - * Tests non-canonical redundant varint decoding. - */ - it('testRedundantVarintFields', function() { - assertNotNull(jspb.BinaryReader.prototype.readUint32); - assertNotNull(jspb.BinaryReader.prototype.readUint64); - assertNotNull(jspb.BinaryReader.prototype.readSint32); - assertNotNull(jspb.BinaryReader.prototype.readSint64); - - // uint32 and sint32 take no more than 5 bytes - // 08 - field prefix (type = 0 means varint) - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readUint32, 12, '08 8C 80 80 80 00'); - - // 11 stands for -6 in zigzag encoding - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readSint32, -6, '08 8B 80 80 80 00'); - - // uint64 and sint64 take no more than 10 bytes - // 08 - field prefix (type = 0 means varint) - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readUint64, 12, - '08 8C 80 80 80 80 80 80 80 80 00'); - - // 11 stands for -6 in zigzag encoding - doTestHexStringVarint_( - jspb.BinaryReader.prototype.readSint64, -6, - '08 8B 80 80 80 80 80 80 80 80 00'); - }); - - - /** - * Tests 64-bit fields that are handled as strings. - */ - it('testStringInt64Fields', function() { - var writer = new jspb.BinaryWriter(); - - var testSignedData = [ - '2730538252207801776', '-2688470994844604560', '3398529779486536359', - '3568577411627971000', '272477188847484900', '-6649058714086158188', - '-7695254765712060806', '-4525541438037104029', '-4993706538836508568', - '4990160321893729138' - ]; - var testUnsignedData = [ - '7822732630241694882', '6753602971916687352', '2399935075244442116', - '8724292567325338867', '16948784802625696584', '4136275908516066934', - '3575388346793700364', '5167142028379259461', '1557573948689737699', - '17100725280812548567' - ]; - - for (var i = 0; i < testSignedData.length; i++) { - writer.writeInt64String(2 * i + 1, testSignedData[i]); - writer.writeUint64String(2 * i + 2, testUnsignedData[i]); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - for (var i = 0; i < testSignedData.length; i++) { - reader.nextField(); - assertEquals(2 * i + 1, reader.getFieldNumber()); - assertEquals(testSignedData[i], reader.readInt64String()); - reader.nextField(); - assertEquals(2 * i + 2, reader.getFieldNumber()); - assertEquals(testUnsignedData[i], reader.readUint64String()); - } - }); - - - /** - * Tests fields that use zigzag encoding. - */ - it('testZigzagFields', function() { - doTestSignedField_( - jspb.BinaryReader.prototype.readSint32, - jspb.BinaryWriter.prototype.writeSint32, 1, -Math.pow(2, 31), - Math.pow(2, 31) - 1, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSint64, - jspb.BinaryWriter.prototype.writeSint64, 1, -Math.pow(2, 63), - Math.pow(2, 63) - 513, Math.round); - }); - - - /** - * Tests fields that use fixed-length encoding. - */ - it('testFixedFields', function() { - doTestUnsignedField_( - jspb.BinaryReader.prototype.readFixed32, - jspb.BinaryWriter.prototype.writeFixed32, 1, Math.pow(2, 32) - 1, - Math.round); - - doTestUnsignedField_( - jspb.BinaryReader.prototype.readFixed64, - jspb.BinaryWriter.prototype.writeFixed64, 1, Math.pow(2, 64) - 1025, - Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSfixed32, - jspb.BinaryWriter.prototype.writeSfixed32, 1, -Math.pow(2, 31), - Math.pow(2, 31) - 1, Math.round); - - doTestSignedField_( - jspb.BinaryReader.prototype.readSfixed64, - jspb.BinaryWriter.prototype.writeSfixed64, 1, -Math.pow(2, 63), - Math.pow(2, 63) - 513, Math.round); - }); - - - /** - * Tests floating point fields. - */ - it('testFloatFields', function() { - doTestSignedField_( - jspb.BinaryReader.prototype.readFloat, - jspb.BinaryWriter.prototype.writeFloat, - jspb.BinaryConstants.FLOAT32_MIN, -jspb.BinaryConstants.FLOAT32_MAX, - jspb.BinaryConstants.FLOAT32_MAX, truncate); - - doTestSignedField_( - jspb.BinaryReader.prototype.readDouble, - jspb.BinaryWriter.prototype.writeDouble, - jspb.BinaryConstants.FLOAT64_EPS * 10, - -jspb.BinaryConstants.FLOAT64_MIN, jspb.BinaryConstants.FLOAT64_MIN, - function(x) { - return x; - }); - }); - - - /** - * Tests length-delimited string fields. - */ - it('testStringFields', function() { - var s1 = 'The quick brown fox jumps over the lazy dog.'; - var s2 = '人人生而自由,在尊嚴和權利上一律平等。'; - - var writer = new jspb.BinaryWriter(); - - writer.writeString(1, s1); - writer.writeString(2, s2); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(s1, reader.readString()); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(s2, reader.readString()); - }); - - - /** - * Tests length-delimited byte fields. - */ - it('testByteFields', function() { - var message = []; - var lowerLimit = 1; - var upperLimit = 256; - var scale = 1.1; - - var writer = new jspb.BinaryWriter(); - - for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) { - var len = Math.round(cursor); - var bytes = []; - for (var i = 0; i < len; i++) bytes.push(i % 256); - - writer.writeBytes(len, bytes); - } - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) { - var len = Math.round(cursor); - if (len != reader.getFieldNumber()) throw 'fail!'; - - var bytes = reader.readBytes(); - if (len != bytes.length) throw 'fail!'; - for (var i = 0; i < bytes.length; i++) { - if (i % 256 != bytes[i]) throw 'fail!'; - } - } - }); - - - /** - * Tests nested messages. - */ - it('testNesting', function() { - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - - writer.writeInt32(1, 100); - - // Add one message with 3 int fields. - writer.writeMessage(2, dummyMessage, function() { - writer.writeInt32(3, 300); - writer.writeInt32(4, 400); - writer.writeInt32(5, 500); - }); - - // Add one empty message. - writer.writeMessage(6, dummyMessage, () => {}); - - writer.writeInt32(7, 700); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - // Validate outermost message. - - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(100, reader.readInt32()); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - // Validate embedded message 1. - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(300, reader.readInt32()); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(400, reader.readInt32()); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(500, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }); - - reader.nextField(); - assertEquals(6, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - // Validate embedded message 2. - - assertEquals(false, reader.nextField()); - }); - - reader.nextField(); - assertEquals(7, reader.getFieldNumber()); - assertEquals(700, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }); - - /** - * Tests skipping fields of each type by interleaving them with sentinel - * values and skipping everything that's not a sentinel. - */ - it('testSkipField', function() { - var writer = new jspb.BinaryWriter(); - - var sentinel = 123456789; - - // Write varint fields of different sizes. - writer.writeInt32(1, sentinel); - writer.writeInt32(1, 1); - writer.writeInt32(1, 1000); - writer.writeInt32(1, 1000000); - writer.writeInt32(1, 1000000000); - - // Write fixed 64-bit encoded fields. - writer.writeInt32(2, sentinel); - writer.writeDouble(2, 1); - writer.writeFixed64(2, 1); - writer.writeSfixed64(2, 1); - - // Write fixed 32-bit encoded fields. - writer.writeInt32(3, sentinel); - writer.writeFloat(3, 1); - writer.writeFixed32(3, 1); - writer.writeSfixed32(3, 1); - - // Write delimited fields. - writer.writeInt32(4, sentinel); - writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - writer.writeString(4, 'The quick brown fox jumps over the lazy dog'); - - // Write a group with a nested group inside. - writer.writeInt32(5, sentinel); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - writer.writeGroup(5, dummyMessage, function() { - writer.writeInt64(42, 42); - writer.writeGroup(6, dummyMessage, function() { - writer.writeInt64(84, 42); - }); - }); - - // Write final sentinel. - writer.writeInt32(6, sentinel); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - function skip(field, count) { - for (var i = 0; i < count; i++) { - reader.nextField(); - if (field != reader.getFieldNumber()) throw 'fail!'; - reader.skipField(); - } - } - - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(1, 4); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(2, 3); - - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(3, 3); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(4, 2); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - skip(5, 1); - - reader.nextField(); - assertEquals(6, reader.getFieldNumber()); - assertEquals(sentinel, reader.readInt32()); - }); - - - /** - * Tests packed fields. - */ - it('testPackedFields', function() { - var writer = new jspb.BinaryWriter(); - - var sentinel = 123456789; - - var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]; - var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; - var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; - var boolData = [true, false, true, true, false, false, true, false]; - - for (var i = 0; i < floatData.length; i++) { - floatData[i] = truncate(floatData[i]); - } - - writer.writeInt32(1, sentinel); - - writer.writePackedInt32(2, signedData); - writer.writePackedInt64(2, signedData); - writer.writePackedUint32(2, unsignedData); - writer.writePackedUint64(2, unsignedData); - writer.writePackedSint32(2, signedData); - writer.writePackedSint64(2, signedData); - writer.writePackedFixed32(2, unsignedData); - writer.writePackedFixed64(2, unsignedData); - writer.writePackedSfixed32(2, signedData); - writer.writePackedSfixed64(2, signedData); - writer.writePackedFloat(2, floatData); - writer.writePackedDouble(2, doubleData); - writer.writePackedBool(2, boolData); - writer.writePackedEnum(2, unsignedData); - - writer.writeInt32(3, sentinel); - - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - reader.nextField(); - assertEquals(sentinel, reader.readInt32()); - - reader.nextField(); - assertElementsEquals(reader.readPackedInt32(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedInt64(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedUint32(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedUint64(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSint32(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSint64(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedFixed32(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedFixed64(), unsignedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSfixed32(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedSfixed64(), signedData); - - reader.nextField(); - assertElementsEquals(reader.readPackedFloat(), floatData); - - reader.nextField(); - assertElementsEquals(reader.readPackedDouble(), doubleData); - - reader.nextField(); - assertElementsEquals(reader.readPackedBool(), boolData); - - reader.nextField(); - assertElementsEquals(reader.readPackedEnum(), unsignedData); - - reader.nextField(); - assertEquals(sentinel, reader.readInt32()); - }); - - - /** - * Byte blobs inside nested messages should always have their byte offset set - * relative to the start of the outermost blob, not the start of their parent - * blob. - */ - it('testNestedBlobs', function() { - // Create a proto consisting of two nested messages, with the inner one - // containing a blob of bytes. - - var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED; - var blob = [1, 2, 3, 4, 5]; - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - - writer.writeMessage(1, dummyMessage, function() { - writer.writeMessage(1, dummyMessage, function() { - writer.writeBytes(1, blob); - }); - }); - - // Peel off the outer two message layers. Each layer should have two bytes - // of overhead, one for the field tag and one for the length of the inner - // blob. - - var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer()); - assertEquals(fieldTag, decoder1.readUnsignedVarint32()); - assertEquals(blob.length + 4, decoder1.readUnsignedVarint32()); - - var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4)); - assertEquals(fieldTag, decoder2.readUnsignedVarint32()); - assertEquals(blob.length + 2, decoder2.readUnsignedVarint32()); - - assertEquals(fieldTag, decoder2.readUnsignedVarint32()); - assertEquals(blob.length, decoder2.readUnsignedVarint32()); - var bytes = decoder2.readBytes(blob.length); - - assertElementsEquals(bytes, blob); - }); - - - /** - * Tests read callbacks. - */ - it('testReadCallbacks', function() { - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - - // Add an int, a submessage, and another int. - writer.writeInt32(1, 100); - - writer.writeMessage(2, dummyMessage, function() { - writer.writeInt32(3, 300); - writer.writeInt32(4, 400); - writer.writeInt32(5, 500); - }); - - writer.writeInt32(7, 700); - - // Create the reader and register a custom read callback. - var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); - - /** - * @param {!jspb.BinaryReader} reader - * @return {*} - */ - function readCallback(reader) { - reader.nextField(); - assertEquals(3, reader.getFieldNumber()); - assertEquals(300, reader.readInt32()); - - reader.nextField(); - assertEquals(4, reader.getFieldNumber()); - assertEquals(400, reader.readInt32()); - - reader.nextField(); - assertEquals(5, reader.getFieldNumber()); - assertEquals(500, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }; - - reader.registerReadCallback('readCallback', readCallback); - - // Read the container message. - reader.nextField(); - assertEquals(1, reader.getFieldNumber()); - assertEquals(100, reader.readInt32()); - - reader.nextField(); - assertEquals(2, reader.getFieldNumber()); - reader.readMessage(dummyMessage, function() { - // Decode the embedded message using the registered callback. - reader.runReadCallback('readCallback'); - }); - - reader.nextField(); - assertEquals(7, reader.getFieldNumber()); - assertEquals(700, reader.readInt32()); - - assertEquals(false, reader.nextField()); - }); -}); diff --git a/js/compatibility_tests/v3.1.0/binary/utils_test.js b/js/compatibility_tests/v3.1.0/binary/utils_test.js deleted file mode 100644 index abc36aac3..000000000 --- a/js/compatibility_tests/v3.1.0/binary/utils_test.js +++ /dev/null @@ -1,668 +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. - -/** - * @fileoverview Test cases for jspb's helper functions. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.crypt.base64'); -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryConstants'); -goog.require('jspb.BinaryWriter'); -goog.require('jspb.utils'); - - -/** - * @param {number} x - * @return {number} - */ -function truncate(x) { - var temp = new Float32Array(1); - temp[0] = x; - return temp[0]; -} - - -/** - * Converts an 64-bit integer in split representation to a 64-bit hash string - * (8 bits encoded per character). - * @param {number} bitsLow The low 32 bits of the split 64-bit integer. - * @param {number} bitsHigh The high 32 bits of the split 64-bit integer. - * @return {string} The encoded hash string, 8 bits per character. - */ -function toHashString(bitsLow, bitsHigh) { - return String.fromCharCode((bitsLow >>> 0) & 0xFF, - (bitsLow >>> 8) & 0xFF, - (bitsLow >>> 16) & 0xFF, - (bitsLow >>> 24) & 0xFF, - (bitsHigh >>> 0) & 0xFF, - (bitsHigh >>> 8) & 0xFF, - (bitsHigh >>> 16) & 0xFF, - (bitsHigh >>> 24) & 0xFF); -} - - -describe('binaryUtilsTest', function() { - /** - * Tests lossless binary-to-decimal conversion. - */ - it('testDecimalConversion', function() { - // Check some magic numbers. - var result = - jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304); - assertEquals('10000000000000000001', result); - - result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b); - assertEquals('123456789123456789', result); - - result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c); - assertEquals('12345678901234567890', result); - - result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8); - assertEquals('9876543210987654321', result); - - // Check limits. - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000); - assertEquals('0', result); - - result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF); - assertEquals('18446744073709551615', result); - - // Check each bit of the low dword. - for (var i = 0; i < 32; i++) { - var low = (1 << i) >>> 0; - result = jspb.utils.joinUnsignedDecimalString(low, 0); - assertEquals('' + Math.pow(2, i), result); - } - - // Check the first 20 bits of the high dword. - for (var i = 0; i < 20; i++) { - var high = (1 << i) >>> 0; - result = jspb.utils.joinUnsignedDecimalString(0, high); - assertEquals('' + Math.pow(2, 32 + i), result); - } - - // V8's internal double-to-string conversion is inaccurate for values above - // 2^52, even if they're representable integers - check the rest of the bits - // manually against the correct string representations of 2^N. - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000); - assertEquals('4503599627370496', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000); - assertEquals('9007199254740992', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000); - assertEquals('18014398509481984', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000); - assertEquals('36028797018963968', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000); - assertEquals('72057594037927936', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000); - assertEquals('144115188075855872', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000); - assertEquals('288230376151711744', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000); - assertEquals('576460752303423488', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000); - assertEquals('1152921504606846976', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000); - assertEquals('2305843009213693952', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000); - assertEquals('4611686018427387904', result); - - result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000); - assertEquals('9223372036854775808', result); - }); - - - /** - * Going from hash strings to decimal strings should also be lossless. - */ - it('testHashToDecimalConversion', function() { - var result; - var convert = jspb.utils.hash64ToDecimalString; - - result = convert(toHashString(0x00000000, 0x00000000), false); - assertEquals('0', result); - - result = convert(toHashString(0x00000000, 0x00000000), true); - assertEquals('0', result); - - result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false); - assertEquals('18446744073709551615', result); - - result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true); - assertEquals('-1', result); - - result = convert(toHashString(0x00000000, 0x80000000), false); - assertEquals('9223372036854775808', result); - - result = convert(toHashString(0x00000000, 0x80000000), true); - assertEquals('-9223372036854775808', result); - - result = convert(toHashString(0xacd05f15, 0x01b69b4b), false); - assertEquals('123456789123456789', result); - - result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true); - assertEquals('-123456789123456789', result); - - // And converting arrays of hashes should work the same way. - result = jspb.utils.hash64ArrayToDecimalStrings([ - toHashString(0xFFFFFFFF, 0xFFFFFFFF), - toHashString(0x00000000, 0x80000000), - toHashString(0xacd05f15, 0x01b69b4b)], false); - assertEquals(3, result.length); - assertEquals('18446744073709551615', result[0]); - assertEquals('9223372036854775808', result[1]); - assertEquals('123456789123456789', result[2]); - }); - - /* - * Going from decimal strings to hash strings should be lossless. - */ - it('testDecimalToHashConversion', function() { - var result; - var convert = jspb.utils.decimalStringToHash64; - - result = convert('0'); - assertEquals(String.fromCharCode.apply(null, - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result); - - result = convert('-1'); - assertEquals(String.fromCharCode.apply(null, - [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); - - result = convert('18446744073709551615'); - assertEquals(String.fromCharCode.apply(null, - [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); - - result = convert('9223372036854775808'); - assertEquals(String.fromCharCode.apply(null, - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result); - - result = convert('-9223372036854775808'); - assertEquals(String.fromCharCode.apply(null, - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result); - - result = convert('123456789123456789'); - assertEquals(String.fromCharCode.apply(null, - [0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01]), result); - - result = convert('-123456789123456789'); - assertEquals(String.fromCharCode.apply(null, - [0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE]), result); - }); - - /** - * Going from hash strings to hex strings should be lossless. - */ - it('testHashToHexConversion', function() { - var result; - var convert = jspb.utils.hash64ToHexString; - - result = convert(toHashString(0x00000000, 0x00000000)); - assertEquals('0x0000000000000000', result); - - result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF)); - assertEquals('0xffffffffffffffff', result); - - result = convert(toHashString(0x12345678, 0x9ABCDEF0)); - assertEquals('0x9abcdef012345678', result); - }); - - - /** - * Going from hex strings to hash strings should be lossless. - */ - it('testHexToHashConversion', function() { - var result; - var convert = jspb.utils.hexStringToHash64; - - result = convert('0x0000000000000000'); - assertEquals(String.fromCharCode.apply(null, - [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result); - - result = convert('0xffffffffffffffff'); - assertEquals(String.fromCharCode.apply(null, - [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); - - // Hex string is big-endian, hash string is little-endian. - result = convert('0x123456789ABCDEF0'); - assertEquals(String.fromCharCode.apply(null, - [0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]), result); - - // Capitalization should not matter. - result = convert('0x0000abcdefABCDEF'); - assertEquals(String.fromCharCode.apply(null, - [0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]), result); - }); - - - /** - * Going from numbers to hash strings should be lossless for up to 53 bits of - * precision. - */ - it('testNumberToHashConversion', function() { - var result; - var convert = jspb.utils.numberToHash64; - - result = convert(0x0000000000000); - assertEquals('0x0000000000000000', jspb.utils.hash64ToHexString(result)); - - result = convert(0xFFFFFFFFFFFFF); - assertEquals('0x000fffffffffffff', jspb.utils.hash64ToHexString(result)); - - result = convert(0x123456789ABCD); - assertEquals('0x000123456789abcd', jspb.utils.hash64ToHexString(result)); - - result = convert(0xDCBA987654321); - assertEquals('0x000dcba987654321', jspb.utils.hash64ToHexString(result)); - - // 53 bits of precision should not be truncated. - result = convert(0x10000000000001); - assertEquals('0x0010000000000001', jspb.utils.hash64ToHexString(result)); - - // 54 bits of precision should be truncated. - result = convert(0x20000000000001); - assertNotEquals( - '0x0020000000000001', jspb.utils.hash64ToHexString(result)); - }); - - - /** - * Sanity check the behavior of Javascript's strings when doing funny things - * with unicode characters. - */ - it('sanityCheckUnicodeStrings', function() { - var strings = new Array(65536); - - // All possible unsigned 16-bit values should be storable in a string, they - // shouldn't do weird things with the length of the string, and they should - // come back out of the string unchanged. - for (var i = 0; i < 65536; i++) { - strings[i] = 'a' + String.fromCharCode(i) + 'a'; - if (3 != strings[i].length) throw 'fail!'; - if (i != strings[i].charCodeAt(1)) throw 'fail!'; - } - - // Each unicode character should compare equal to itself and not equal to a - // different unicode character. - for (var i = 0; i < 65536; i++) { - if (strings[i] != strings[i]) throw 'fail!'; - if (strings[i] == strings[(i + 1) % 65536]) throw 'fail!'; - } - }); - - - /** - * Tests conversion from 32-bit floating point numbers to split64 numbers. - */ - it('testFloat32ToSplit64', function() { - var f32_eps = jspb.BinaryConstants.FLOAT32_EPS; - var f32_min = jspb.BinaryConstants.FLOAT32_MIN; - var f32_max = jspb.BinaryConstants.FLOAT32_MAX; - - // NaN. - jspb.utils.splitFloat32(NaN); - if (!isNaN(jspb.utils.joinFloat32(jspb.utils.split64Low, - jspb.utils.split64High))) { - throw 'fail!'; - } - - /** - * @param {number} x - * @param {number=} opt_bits - */ - function test(x, opt_bits) { - jspb.utils.splitFloat32(x); - if (opt_bits !== undefined) { - if (opt_bits != jspb.utils.split64Low) throw 'fail!'; - } - if (truncate(x) != jspb.utils.joinFloat32(jspb.utils.split64Low, - jspb.utils.split64High)) { - throw 'fail!'; - } - } - - // Positive and negative infinity. - test(Infinity, 0x7f800000); - test(-Infinity, 0xff800000); - - // Positive and negative zero. - test(0, 0x00000000); - test(-0, 0x80000000); - - // Positive and negative epsilon. - test(f32_eps, 0x00000001); - test(-f32_eps, 0x80000001); - - // Positive and negative min. - test(f32_min, 0x00800000); - test(-f32_min, 0x80800000); - - // Positive and negative max. - test(f32_max, 0x7F7FFFFF); - test(-f32_max, 0xFF7FFFFF); - - // Various positive values. - var cursor = f32_eps * 10; - while (cursor != Infinity) { - test(cursor); - cursor *= 1.1; - } - - // Various negative values. - cursor = -f32_eps * 10; - while (cursor != -Infinity) { - test(cursor); - cursor *= 1.1; - } - }); - - - /** - * Tests conversion from 64-bit floating point numbers to split64 numbers. - */ - it('testFloat64ToSplit64', function() { - var f64_eps = jspb.BinaryConstants.FLOAT64_EPS; - var f64_min = jspb.BinaryConstants.FLOAT64_MIN; - var f64_max = jspb.BinaryConstants.FLOAT64_MAX; - - // NaN. - jspb.utils.splitFloat64(NaN); - if (!isNaN(jspb.utils.joinFloat64(jspb.utils.split64Low, - jspb.utils.split64High))) { - throw 'fail!'; - } - - /** - * @param {number} x - * @param {number=} opt_highBits - * @param {number=} opt_lowBits - */ - function test(x, opt_highBits, opt_lowBits) { - jspb.utils.splitFloat64(x); - if (opt_highBits !== undefined) { - if (opt_highBits != jspb.utils.split64High) throw 'fail!'; - } - if (opt_lowBits !== undefined) { - if (opt_lowBits != jspb.utils.split64Low) throw 'fail!'; - } - if (x != jspb.utils.joinFloat64(jspb.utils.split64Low, - jspb.utils.split64High)) { - throw 'fail!'; - } - } - - // Positive and negative infinity. - test(Infinity, 0x7ff00000, 0x00000000); - test(-Infinity, 0xfff00000, 0x00000000); - - // Positive and negative zero. - test(0, 0x00000000, 0x00000000); - test(-0, 0x80000000, 0x00000000); - - // Positive and negative epsilon. - test(f64_eps, 0x00000000, 0x00000001); - test(-f64_eps, 0x80000000, 0x00000001); - - // Positive and negative min. - test(f64_min, 0x00100000, 0x00000000); - test(-f64_min, 0x80100000, 0x00000000); - - // Positive and negative max. - test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF); - test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF); - - // Various positive values. - var cursor = f64_eps * 10; - while (cursor != Infinity) { - test(cursor); - cursor *= 1.1; - } - - // Various negative values. - cursor = -f64_eps * 10; - while (cursor != -Infinity) { - test(cursor); - cursor *= 1.1; - } - }); - - - /** - * Tests counting packed varints. - */ - it('testCountVarints', function() { - var values = []; - for (var i = 1; i < 1000000000; i *= 1.1) { - values.push(Math.floor(i)); - } - - var writer = new jspb.BinaryWriter(); - writer.writePackedUint64(1, values); - - var buffer = new Uint8Array(writer.getResultBuffer()); - - // We should have two more varints than we started with - one for the field - // tag, one for the packed length. - assertEquals(values.length + 2, - jspb.utils.countVarints(buffer, 0, buffer.length)); - }); - - - /** - * Tests counting matching varint fields. - */ - it('testCountVarintFields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeUint64(1, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countVarintFields(buffer, 0, buffer.length, 1)); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeUint64(123456789, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789)); - }); - - - /** - * Tests counting matching fixed32 fields. - */ - it('testCountFixed32Fields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeFixed32(1, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1)); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeFixed32(123456789, Math.floor(i)); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789)); - }); - - - /** - * Tests counting matching fixed64 fields. - */ - it('testCountFixed64Fields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeDouble(1, i); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1)); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000000000; i *= 1.1) { - writer.writeDouble(123456789, i); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789)); - }); - - - /** - * Tests counting matching delimited fields. - */ - it('testCountDelimitedFields', function() { - var writer = new jspb.BinaryWriter(); - - var count = 0; - for (var i = 1; i < 1000; i *= 1.1) { - writer.writeBytes(1, [Math.floor(i)]); - count++; - } - writer.writeString(2, 'terminator'); - - var buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1)); - - writer = new jspb.BinaryWriter(); - - count = 0; - for (var i = 1; i < 1000; i *= 1.1) { - writer.writeBytes(123456789, [Math.floor(i)]); - count++; - } - writer.writeString(2, 'terminator'); - - buffer = new Uint8Array(writer.getResultBuffer()); - assertEquals(count, - jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789)); - }); - - - /** - * Tests byte format for debug strings. - */ - it('testDebugBytesToTextFormat', function() { - assertEquals('""', jspb.utils.debugBytesToTextFormat(null)); - assertEquals('"\\x00\\x10\\xff"', - jspb.utils.debugBytesToTextFormat([0, 16, 255])); - }); - - - /** - * Tests converting byte blob sources into byte blobs. - */ - it('testByteSourceToUint8Array', function() { - var convert = jspb.utils.byteSourceToUint8Array; - - var sourceData = []; - for (var i = 0; i < 256; i++) { - sourceData.push(i); - } - - var sourceBytes = new Uint8Array(sourceData); - var sourceBuffer = sourceBytes.buffer; - var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData); - var sourceString = String.fromCharCode.apply(null, sourceData); - - function check(result) { - assertEquals(Uint8Array, result.constructor); - assertEquals(sourceData.length, result.length); - for (var i = 0; i < result.length; i++) { - assertEquals(sourceData[i], result[i]); - } - } - - // Converting Uint8Arrays into Uint8Arrays should be a no-op. - assertEquals(sourceBytes, convert(sourceBytes)); - - // Converting Array. into Uint8Arrays should work. - check(convert(sourceData)); - - // Converting ArrayBuffers into Uint8Arrays should work. - check(convert(sourceBuffer)); - - // Converting base64-encoded strings into Uint8Arrays should work. - check(convert(sourceBase64)); - }); -}); diff --git a/js/compatibility_tests/v3.1.0/binary/writer_test.js b/js/compatibility_tests/v3.1.0/binary/writer_test.js deleted file mode 100644 index 5779cc5c2..000000000 --- a/js/compatibility_tests/v3.1.0/binary/writer_test.js +++ /dev/null @@ -1,164 +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. - -/** - * @fileoverview Test cases for jspb's binary protocol buffer writer. In - * practice BinaryWriter is used to drive the Decoder and Reader test cases, - * so only writer-specific tests are here. - * - * Test suite is written using Jasmine -- see http://jasmine.github.io/ - * - * @author aappleby@google.com (Austin Appleby) - */ - -goog.require('goog.crypt'); -goog.require('goog.testing.asserts'); -goog.require('jspb.BinaryWriter'); -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/)); -} - - -describe('binaryWriterTest', function() { - /** - * Verifies that misuse of the writer class triggers assertions. - */ - it('testWriteErrors', function() { - // Submessages with invalid field indices should assert. - var writer = new jspb.BinaryWriter(); - var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({}); - - assertFails(function() { - writer.writeMessage(-1, dummyMessage, () => {}); - }); - - // Writing invalid field indices should assert. - writer = new jspb.BinaryWriter(); - assertFails(function() { - writer.writeUint64(-1, 1); - }); - - // Writing out-of-range field values should assert. - writer = new jspb.BinaryWriter(); - - assertFails(function() { - writer.writeInt32(1, -Infinity); - }); - assertFails(function() { - writer.writeInt32(1, Infinity); - }); - - assertFails(function() { - writer.writeInt64(1, -Infinity); - }); - assertFails(function() { - writer.writeInt64(1, Infinity); - }); - - assertFails(function() { - writer.writeUint32(1, -1); - }); - assertFails(function() { - writer.writeUint32(1, Infinity); - }); - - assertFails(function() { - writer.writeUint64(1, -1); - }); - assertFails(function() { - writer.writeUint64(1, Infinity); - }); - - assertFails(function() { - writer.writeSint32(1, -Infinity); - }); - assertFails(function() { - writer.writeSint32(1, Infinity); - }); - - assertFails(function() { - writer.writeSint64(1, -Infinity); - }); - assertFails(function() { - writer.writeSint64(1, Infinity); - }); - - assertFails(function() { - writer.writeFixed32(1, -1); - }); - assertFails(function() { - writer.writeFixed32(1, Infinity); - }); - - assertFails(function() { - writer.writeFixed64(1, -1); - }); - assertFails(function() { - writer.writeFixed64(1, Infinity); - }); - - assertFails(function() { - writer.writeSfixed32(1, -Infinity); - }); - assertFails(function() { - writer.writeSfixed32(1, Infinity); - }); - - assertFails(function() { - writer.writeSfixed64(1, -Infinity); - }); - assertFails(function() { - writer.writeSfixed64(1, Infinity); - }); - }); - - - /** - * Basic test of retrieving the result as a Uint8Array buffer - */ - it('testGetResultBuffer', function() { - var expected = '0864120b48656c6c6f20776f726c641a0301020320c801'; - - var writer = new jspb.BinaryWriter(); - writer.writeUint32(1, 100); - writer.writeString(2, 'Hello world'); - writer.writeBytes(3, new Uint8Array([1, 2, 3])); - writer.writeUint32(4, 200); - - var buffer = writer.getResultBuffer(); - assertEquals(expected, goog.crypt.byteArrayToHex(buffer)); - }); -}); diff --git a/js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto b/js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto deleted file mode 100644 index a060925f2..000000000 --- a/js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto +++ /dev/null @@ -1,40 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2016 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test.importing; - -message ImportedMessage { - string string_value = 1; -} diff --git a/js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto b/js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto deleted file mode 100644 index f5574a3dd..000000000 --- a/js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto +++ /dev/null @@ -1,42 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2016 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test.framing; - -import "test6/test6.proto"; - -message FramingMessage { - jspb.test.importing.ImportedMessage imported_message = 1; -} diff --git a/js/compatibility_tests/v3.1.0/data.proto b/js/compatibility_tests/v3.1.0/data.proto deleted file mode 100644 index 74a8a994c..000000000 --- a/js/compatibility_tests/v3.1.0/data.proto +++ /dev/null @@ -1,51 +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: mwr@google.com (Mark Rawling) - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test; - -// legacy data, must be nested -message data { - message NestedData { - required string str = 1; - } -} - -// new data, does not require nesting -message UnnestedData { - required string str = 1; -} - diff --git a/js/compatibility_tests/v3.1.0/debug_test.js b/js/compatibility_tests/v3.1.0/debug_test.js deleted file mode 100644 index 702cc76e9..000000000 --- a/js/compatibility_tests/v3.1.0/debug_test.js +++ /dev/null @@ -1,105 +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. - -goog.setTestOnly(); - -goog.require('goog.testing.asserts'); - -// CommonJS-LoadFromFile: google-protobuf -goog.require('jspb.debug'); - -// CommonJS-LoadFromFile: test_pb -goog.require('proto.jspb.test.HasExtensions'); -goog.require('proto.jspb.test.IsExtension'); -goog.require('proto.jspb.test.Simple1'); - - - -describe('debugTest', function() { - it('testSimple1', function() { - if (COMPILED) { - return; - } - var message = new proto.jspb.test.Simple1(); - message.setAString('foo'); - assertObjectEquals({ - $name: 'proto.jspb.test.Simple1', - 'aString': 'foo', - 'aRepeatedStringList': [] - }, jspb.debug.dump(message)); - - message.setABoolean(true); - message.setARepeatedStringList(['1', '2']); - - assertObjectEquals({ - $name: 'proto.jspb.test.Simple1', - 'aString': 'foo', - 'aRepeatedStringList': ['1', '2'], - 'aBoolean': true - }, jspb.debug.dump(message)); - - message.clearAString(); - - assertObjectEquals({ - $name: 'proto.jspb.test.Simple1', - 'aRepeatedStringList': ['1', '2'], - 'aBoolean': true - }, jspb.debug.dump(message)); - }); - - - it('testExtensions', function() { - if (COMPILED) { - return; - } - var extension = new proto.jspb.test.IsExtension(); - extension.setExt1('ext1field'); - var extendable = new proto.jspb.test.HasExtensions(); - extendable.setStr1('v1'); - extendable.setStr2('v2'); - extendable.setStr3('v3'); - extendable.setExtension(proto.jspb.test.IsExtension.extField, extension); - - assertObjectEquals({ - '$name': 'proto.jspb.test.HasExtensions', - 'str1': 'v1', - 'str2': 'v2', - 'str3': 'v3', - '$extensions': { - 'extField': { - '$name': 'proto.jspb.test.IsExtension', - 'ext1': 'ext1field' - }, - 'repeatedSimpleList': [] - } - }, jspb.debug.dump(extendable)); - }); - -}); diff --git a/js/compatibility_tests/v3.1.0/maps_test.js b/js/compatibility_tests/v3.1.0/maps_test.js deleted file mode 100644 index 452dfe59d..000000000 --- a/js/compatibility_tests/v3.1.0/maps_test.js +++ /dev/null @@ -1,284 +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. - -goog.require('goog.testing.asserts'); -goog.require('goog.userAgent'); - -// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test -goog.require('proto.jspb.test.MapValueEnum'); -goog.require('proto.jspb.test.MapValueMessage'); -goog.require('proto.jspb.test.TestMapFields'); - -// CommonJS-LoadFromFile: test_pb proto.jspb.test -goog.require('proto.jspb.test.MapValueMessageNoBinary'); -goog.require('proto.jspb.test.TestMapFieldsNoBinary'); - -goog.requireType('jspb.Map'); - -/** - * Helper: check that the given map has exactly this set of (sorted) entries. - * @param {!jspb.Map} map - * @param {!Array>} entries - */ -function checkMapEquals(map, entries) { - var arr = map.toArray(); - assertEquals(arr.length, entries.length); - for (var i = 0; i < arr.length; i++) { - assertElementsEquals(arr[i], entries[i]); - } -} - -/** - * Converts an ES6 iterator to an array. - * @template T - * @param {!Iterator} iter an iterator - * @return {!Array} - */ -function toArray(iter) { - var arr = []; - while (true) { - var val = iter.next(); - if (val.done) { - break; - } - arr.push(val.value); - } - return arr; -} - - -/** - * Helper: generate test methods for this TestMapFields class. - * @param {?} msgInfo - * @param {?} submessageCtor - * @param {!string} suffix - */ -function makeTests(msgInfo, submessageCtor, suffix) { - /** - * Helper: fill all maps on a TestMapFields. - * @param {?} msg - */ - var fillMapFields = function(msg) { - msg.getMapStringStringMap().set('asdf', 'jkl;').set('key 2', 'hello world'); - msg.getMapStringInt32Map().set('a', 1).set('b', -2); - msg.getMapStringInt64Map().set('c', 0x100000000).set('d', 0x200000000); - msg.getMapStringBoolMap().set('e', true).set('f', false); - msg.getMapStringDoubleMap().set('g', 3.14159).set('h', 2.71828); - msg.getMapStringEnumMap() - .set('i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR) - .set('j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ); - msg.getMapStringMsgMap() - .set('k', new submessageCtor()) - .set('l', new submessageCtor()); - msg.getMapStringMsgMap().get('k').setFoo(42); - msg.getMapStringMsgMap().get('l').setFoo(84); - msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b'); - msg.getMapInt64StringMap() - .set(0x123456789abc, 'c') - .set(0xcba987654321, 'd'); - msg.getMapBoolStringMap().set(false, 'e').set(true, 'f'); - }; - - /** - * Helper: check all maps on a TestMapFields. - * @param {?} msg - */ - var checkMapFields = function(msg) { - checkMapEquals( - msg.getMapStringStringMap(), - [['asdf', 'jkl;'], ['key 2', 'hello world']]); - checkMapEquals(msg.getMapStringInt32Map(), [['a', 1], ['b', -2]]); - checkMapEquals( - msg.getMapStringInt64Map(), [['c', 0x100000000], ['d', 0x200000000]]); - checkMapEquals(msg.getMapStringBoolMap(), [['e', true], ['f', false]]); - checkMapEquals( - msg.getMapStringDoubleMap(), [['g', 3.14159], ['h', 2.71828]]); - checkMapEquals(msg.getMapStringEnumMap(), [ - ['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR], - ['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ] - ]); - checkMapEquals(msg.getMapInt32StringMap(), [[-1, 'a'], [42, 'b']]); - checkMapEquals( - msg.getMapInt64StringMap(), - [[0x123456789abc, 'c'], [0xcba987654321, 'd']]); - checkMapEquals(msg.getMapBoolStringMap(), [[false, 'e'], [true, 'f']]); - - assertEquals(msg.getMapStringMsgMap().getLength(), 2); - assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42); - assertEquals(msg.getMapStringMsgMap().get('l').getFoo(), 84); - - var entries = toArray(msg.getMapStringMsgMap().entries()); - assertEquals(entries.length, 2); - entries.forEach(function(entry) { - var key = entry[0]; - var val = entry[1]; - assert(val === msg.getMapStringMsgMap().get(key)); - }); - - msg.getMapStringMsgMap().forEach(function(val, key) { - assert(val === msg.getMapStringMsgMap().get(key)); - }); - }; - - it('testMapStringStringField' + suffix, function() { - var msg = new msgInfo.constructor(); - assertEquals(msg.getMapStringStringMap().getLength(), 0); - assertEquals(msg.getMapStringInt32Map().getLength(), 0); - assertEquals(msg.getMapStringInt64Map().getLength(), 0); - assertEquals(msg.getMapStringBoolMap().getLength(), 0); - assertEquals(msg.getMapStringDoubleMap().getLength(), 0); - assertEquals(msg.getMapStringEnumMap().getLength(), 0); - assertEquals(msg.getMapStringMsgMap().getLength(), 0); - - // Re-create to clear out any internally-cached wrappers, etc. - msg = new msgInfo.constructor(); - var m = msg.getMapStringStringMap(); - assertEquals(m.has('asdf'), false); - assertEquals(m.get('asdf'), undefined); - m.set('asdf', 'hello world'); - assertEquals(m.has('asdf'), true); - assertEquals(m.get('asdf'), 'hello world'); - m.set('jkl;', 'key 2'); - assertEquals(m.has('jkl;'), true); - assertEquals(m.get('jkl;'), 'key 2'); - assertEquals(m.getLength(), 2); - var it = m.entries(); - assertElementsEquals(it.next().value, ['asdf', 'hello world']); - assertElementsEquals(it.next().value, ['jkl;', 'key 2']); - assertEquals(it.next().done, true); - checkMapEquals(m, [['asdf', 'hello world'], ['jkl;', 'key 2']]); - m.del('jkl;'); - assertEquals(m.has('jkl;'), false); - assertEquals(m.get('jkl;'), undefined); - assertEquals(m.getLength(), 1); - it = m.keys(); - assertEquals(it.next().value, 'asdf'); - assertEquals(it.next().done, true); - it = m.values(); - assertEquals(it.next().value, 'hello world'); - assertEquals(it.next().done, true); - - var count = 0; - m.forEach(function(value, key, map) { - assertEquals(map, m); - assertEquals(key, 'asdf'); - assertEquals(value, 'hello world'); - count++; - }); - assertEquals(count, 1); - - m.clear(); - assertEquals(m.getLength(), 0); - }); - - - /** - * Tests operations on maps with all key and value types. - */ - it('testAllMapTypes' + suffix, function() { - var msg = new msgInfo.constructor(); - fillMapFields(msg); - checkMapFields(msg); - }); - - - if (msgInfo.deserializeBinary) { - /** - * Tests serialization and deserialization in binary format. - */ - it('testBinaryFormat' + suffix, function() { - if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) { - // IE8/9 currently doesn't support binary format because they lack - // TypedArray. - return; - } - - // Check that the format is correct. - var msg = new msgInfo.constructor(); - msg.getMapStringStringMap().set('A', 'a'); - var serialized = msg.serializeBinary(); - var expectedSerialized = [ - 0x0a, 0x6, // field 1 (map_string_string), delimited, length 6 - 0x0a, 0x1, // field 1 in submessage (key), delimited, length 1 - 0x41, // ASCII 'A' - 0x12, 0x1, // field 2 in submessage (value), delimited, length 1 - 0x61 // ASCII 'a' - ]; - assertEquals(serialized.length, expectedSerialized.length); - for (var i = 0; i < serialized.length; i++) { - assertEquals(serialized[i], expectedSerialized[i]); - } - - // Check that all map fields successfully round-trip. - msg = new msgInfo.constructor(); - fillMapFields(msg); - serialized = msg.serializeBinary(); - var decoded = msgInfo.deserializeBinary(serialized); - checkMapFields(decoded); - }); - } - - /** - * Exercises the lazy map<->underlying array sync. - */ - it('testLazyMapSync' + suffix, function() { - // Start with a JSPB array containing a few map entries. - var entries = [['a', 'entry 1'], ['c', 'entry 2'], ['b', 'entry 3']]; - var msg = new msgInfo.constructor([entries]); - assertEquals(entries.length, 3); - assertEquals(entries[0][0], 'a'); - assertEquals(entries[1][0], 'c'); - assertEquals(entries[2][0], 'b'); - msg.getMapStringStringMap().del('a'); - assertEquals(entries.length, 3); // not yet sync'd - msg.toArray(); // force a sync - assertEquals(entries.length, 2); - assertEquals(entries[0][0], 'b'); // now in sorted order - assertEquals(entries[1][0], 'c'); - - var a = msg.toArray(); - assertEquals(a[0], entries); // retains original reference - }); -} - -describe('mapsTest', function() { - makeTests( - { - constructor: proto.jspb.test.TestMapFields, - deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary - }, - proto.jspb.test.MapValueMessage, '_Binary'); - makeTests( - { - constructor: proto.jspb.test.TestMapFieldsNoBinary, - deserializeBinary: null - }, - proto.jspb.test.MapValueMessageNoBinary, '_NoBinary'); -}); diff --git a/js/compatibility_tests/v3.1.0/message_test.js b/js/compatibility_tests/v3.1.0/message_test.js deleted file mode 100644 index 9830a02df..000000000 --- a/js/compatibility_tests/v3.1.0/message_test.js +++ /dev/null @@ -1,1060 +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. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - -goog.setTestOnly(); - -goog.require('goog.json'); -goog.require('goog.testing.asserts'); -goog.require('goog.userAgent'); - -// CommonJS-LoadFromFile: google-protobuf jspb -goog.require('jspb.Message'); - -// CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta -goog.require('proto.jspb.exttest.beta.floatingStrField'); - -// CommonJS-LoadFromFile: test3_pb proto.jspb.exttest -goog.require('proto.jspb.exttest.floatingMsgField'); - -// CommonJS-LoadFromFile: test4_pb proto.jspb.exttest -goog.require('proto.jspb.exttest.floatingMsgFieldTwo'); - -// CommonJS-LoadFromFile: test_pb proto.jspb.test -goog.require('proto.jspb.test.CloneExtension'); -goog.require('proto.jspb.test.Complex'); -goog.require('proto.jspb.test.DefaultValues'); -goog.require('proto.jspb.test.Empty'); -goog.require('proto.jspb.test.EnumContainer'); -goog.require('proto.jspb.test.floatingMsgField'); -goog.require('proto.jspb.test.FloatingPointFields'); -goog.require('proto.jspb.test.floatingStrField'); -goog.require('proto.jspb.test.HasExtensions'); -goog.require('proto.jspb.test.IndirectExtension'); -goog.require('proto.jspb.test.IsExtension'); -goog.require('proto.jspb.test.OptionalFields'); -goog.require('proto.jspb.test.OuterEnum'); -goog.require('proto.jspb.test.OuterMessage.Complex'); -goog.require('proto.jspb.test.Simple1'); -goog.require('proto.jspb.test.Simple2'); -goog.require('proto.jspb.test.SpecialCases'); -goog.require('proto.jspb.test.TestClone'); -goog.require('proto.jspb.test.TestGroup'); -goog.require('proto.jspb.test.TestGroup1'); -goog.require('proto.jspb.test.TestMessageWithOneof'); -goog.require('proto.jspb.test.TestReservedNames'); -goog.require('proto.jspb.test.TestReservedNamesExtension'); - -// CommonJS-LoadFromFile: test2_pb proto.jspb.test -goog.require('proto.jspb.test.ExtensionMessage'); -goog.require('proto.jspb.test.TestExtensionsMessage'); -goog.require('proto.jspb.test.simple1'); - - - -describe('Message test suite', function() { - it('testEmptyProto', function() { - var empty1 = new proto.jspb.test.Empty([]); - var empty2 = new proto.jspb.test.Empty([]); - assertObjectEquals({}, empty1.toObject()); - assertObjectEquals('Message should not be corrupted:', empty2, empty1); - }); - - it('testTopLevelEnum', function() { - var response = new proto.jspb.test.EnumContainer([]); - response.setOuterEnum(proto.jspb.test.OuterEnum.FOO); - assertEquals(proto.jspb.test.OuterEnum.FOO, response.getOuterEnum()); - }); - - it('testByteStrings', function() { - var data = new proto.jspb.test.DefaultValues([]); - data.setBytesField('some_bytes'); - assertEquals('some_bytes', data.getBytesField()); - }); - - it('testComplexConversion', function() { - var data1 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , 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); - - // 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); - }); - - it('testMissingFields', function() { - var foo = new proto.jspb.test.Complex([ - undefined, undefined, undefined, [], undefined, undefined, undefined, - undefined - ]); - var bar = new proto.jspb.test.Complex([ - undefined, undefined, undefined, [], undefined, undefined, undefined, - undefined - ]); - var result = foo.toObject(); - assertObjectEquals( - { - aString: undefined, - anOutOfOrderBool: undefined, - aNestedMessage: {anInt: undefined}, - // Note: JsPb converts undefined repeated fields to empty arrays. - aRepeatedMessageList: [], - aRepeatedStringList: [] - }, - result); - }); - - it('testNestedComplexMessage', function() { - // Instantiate the message and set a unique field, just to ensure that we - // are not getting jspb.test.Complex instead. - var msg = new proto.jspb.test.OuterMessage.Complex(); - msg.setInnerComplexField(5); - }); - - it('testSpecialCases', function() { - // Note: Some property names are reserved in JavaScript. - // These names are converted to the Js property named pb_. - var special = new proto.jspb.test.SpecialCases( - ['normal', 'default', 'function', 'var']); - var result = special.toObject(); - assertObjectEquals( - { - normal: 'normal', - pb_default: 'default', - pb_function: 'function', - pb_var: 'var' - }, - result); - }); - - it('testDefaultValues', function() { - var defaultString = 'default<>\'"abc'; - var response = new proto.jspb.test.DefaultValues(); - - // Test toObject - var expectedObject = { - stringField: defaultString, - boolField: true, - intField: 11, - enumField: 13, - emptyField: '', - bytesField: 'bW9v' - }; - assertObjectEquals(expectedObject, response.toObject()); - - - // Test getters - response = new proto.jspb.test.DefaultValues(); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertEquals('', response.getEmptyField()); - assertEquals('bW9v', response.getBytesField()); - - function makeDefault(values) { - return new proto.jspb.test.DefaultValues(values); - } - - // Test with undefined values, - // Use push to workaround IE treating undefined array elements as holes. - response = makeDefault([undefined, undefined, undefined, undefined]); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - - // Test with null values, as would be returned by a JSON serializer. - response = makeDefault([null, null, null, null]); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - - // Test with false-like values. - response = makeDefault(['', false, 0, 0]); - assertEquals('', response.getStringField()); - assertEquals(false, response.getBoolField()); - assertEquals(true, response.getIntField() == 0); - assertEquals(true, response.getEnumField() == 0); - assertTrue(response.hasStringField()); - assertTrue(response.hasBoolField()); - assertTrue(response.hasIntField()); - assertTrue(response.hasEnumField()); - - // Test that clearing the values reverts them to the default state. - response = makeDefault(['blah', false, 111, 77]); - response.clearStringField(); - response.clearBoolField(); - response.clearIntField(); - response.clearEnumField(); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - - // Test that setFoo(null) clears the values. - response = makeDefault(['blah', false, 111, 77]); - response.setStringField(null); - response.setBoolField(null); - response.setIntField(undefined); - response.setEnumField(undefined); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - }); - - it('testClearFields', function() { - var data = ['str', true, [11], [[22], [33]], ['s1', 's2']]; - var foo = new proto.jspb.test.OptionalFields(data); - foo.clearAString(); - foo.clearABool(); - foo.clearANestedMessage(); - foo.clearARepeatedMessageList(); - foo.clearARepeatedStringList(); - assertEquals('', foo.getAString()); - assertEquals(false, foo.getABool()); - assertUndefined(foo.getANestedMessage()); - assertFalse(foo.hasAString()); - assertFalse(foo.hasABool()); - assertObjectEquals([], foo.getARepeatedMessageList()); - assertObjectEquals([], foo.getARepeatedStringList()); - // NOTE: We want the missing fields in 'expected' to be undefined, - // but we actually get a sparse array instead. We could use something - // like [1,undefined,2] to avoid this, except that this is still - // sparse on IE. No comment... - var expected = [, , , [], []]; - expected[0] = expected[1] = expected[2] = undefined; - assertObjectEquals(expected, foo.toArray()); - }); - - it('testDifferenceRawObject', /** @suppress {visibility} */ function() { - var p1 = new proto.jspb.test.HasExtensions(['hi', 'diff', {}]); - var p2 = - new proto.jspb.test.HasExtensions(['hi', 'what', {1000: 'unique'}]); - var diff = /** @type {proto.jspb.test.HasExtensions} */ - (jspb.Message.difference(p1, p2)); - assertEquals('', diff.getStr1()); - assertEquals('what', diff.getStr2()); - assertEquals('', diff.getStr3()); - assertEquals('unique', diff.extensionObject_[1000]); - }); - - it('testEqualsSimple', function() { - var s1 = new proto.jspb.test.Simple1(['hi']); - assertTrue(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi']))); - assertFalse(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['bye']))); - var s1b = new proto.jspb.test.Simple1(['hi', ['hello']]); - assertTrue(jspb.Message.equals( - s1b, new proto.jspb.test.Simple1(['hi', ['hello']]))); - assertTrue(jspb.Message.equals(s1b, new proto.jspb.test.Simple1([ - 'hi', ['hello', undefined, undefined, undefined] - ]))); - assertFalse(jspb.Message.equals( - s1b, new proto.jspb.test.Simple1(['no', ['hello']]))); - // Test with messages of different types - var s2 = new proto.jspb.test.Simple2(['hi']); - assertFalse(jspb.Message.equals(s1, s2)); - }); - - it('testEquals_softComparison', function() { - var s1 = new proto.jspb.test.Simple1(['hi', [], null]); - assertTrue( - jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi', []]))); - - var s1b = new proto.jspb.test.Simple1(['hi', [], true]); - assertTrue( - jspb.Message.equals(s1b, new proto.jspb.test.Simple1(['hi', [], 1]))); - }); - - it('testEqualsComplex', function() { - var data1 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , 1]; - var data2 = ['a', , , [, 11], [[, 22], [, 34]], , ['s1', 's2'], , 1]; - var data3 = ['a', , , [, 11], [[, 22]], , ['s1', 's2'], , 1]; - var data4 = ['hi']; - var c1a = new proto.jspb.test.Complex(data1); - var c1b = new proto.jspb.test.Complex(data1); - var c2 = new proto.jspb.test.Complex(data2); - var c3 = new proto.jspb.test.Complex(data3); - var s1 = new proto.jspb.test.Simple1(data4); - - assertTrue(jspb.Message.equals(c1a, c1b)); - assertFalse(jspb.Message.equals(c1a, c2)); - assertFalse(jspb.Message.equals(c2, c3)); - assertFalse(jspb.Message.equals(c1a, s1)); - }); - - it('testEqualsExtensionsConstructed', function() { - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([]), - new proto.jspb.test.HasExtensions([{}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]))); - assertFalse(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions([, , , {100: [{200: 'a'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([, , , {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', , , {100: [{200: 'a'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', , , {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]))); - }); - - it('testEqualsExtensionsUnconstructed', function() { - assertTrue(jspb.Message.compareFields([], [{}])); - assertTrue(jspb.Message.compareFields([, , , {}], [])); - assertTrue(jspb.Message.compareFields([, , , {}], [, , {}])); - assertTrue(jspb.Message.compareFields( - ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}])); - assertFalse(jspb.Message.compareFields( - ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'b'}]}])); - assertTrue(jspb.Message.compareFields( - [{100: [{200: 'a'}]}], [{100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - [{100: [{200: 'a'}]}], [, , , {100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - [, , , {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - ['hi', {100: [{200: 'a'}]}], ['hi', , , {100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - ['hi', , , {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}])); - }); - - it('testToMap', function() { - var p1 = new proto.jspb.test.Simple1(['k', ['v']]); - var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]); - var soymap = jspb.Message.toMap( - [p1, p2], proto.jspb.test.Simple1.prototype.getAString, - proto.jspb.test.Simple1.prototype.toObject); - assertEquals('k', soymap['k'].aString); - assertArrayEquals(['v'], soymap['k'].aRepeatedStringList); - var protomap = jspb.Message.toMap( - [p1, p2], proto.jspb.test.Simple1.prototype.getAString); - assertEquals('k', protomap['k'].getAString()); - assertArrayEquals(['v'], protomap['k'].getARepeatedStringList()); - }); - - it('testClone', function() { - var supportsUint8Array = - !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'); - var original = new proto.jspb.test.TestClone(); - original.setStr('v1'); - var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]); - var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]); - var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]); - original.setSimple1(simple1); - original.setSimple2List([simple2, simple3]); - var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123'; - original.setBytesField(bytes1); - var extension = new proto.jspb.test.CloneExtension(); - extension.setExt('e1'); - original.setExtension(proto.jspb.test.IsExtension.extField, extension); - var clone = original.clone(); - assertArrayEquals( - [ - 'v1', , ['x1', ['y1', 'z1']], , - [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1, , - {100: [, 'e1']} - ], - clone.toArray()); - clone.setStr('v2'); - var simple4 = new proto.jspb.test.Simple1(['a1', ['b1', 'c1']]); - var simple5 = new proto.jspb.test.Simple1(['a2', ['b2', 'c2']]); - var simple6 = new proto.jspb.test.Simple1(['a3', ['b3', 'c3']]); - clone.setSimple1(simple4); - clone.setSimple2List([simple5, simple6]); - if (supportsUint8Array) { - clone.getBytesField()[0] = 4; - assertObjectEquals(bytes1, original.getBytesField()); - } - var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456'; - clone.setBytesField(bytes2); - var newExtension = new proto.jspb.test.CloneExtension(); - newExtension.setExt('e2'); - clone.setExtension(proto.jspb.test.CloneExtension.extField, newExtension); - assertArrayEquals( - [ - 'v2', , ['a1', ['b1', 'c1']], , - [['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]], bytes2, , - {100: [, 'e2']} - ], - clone.toArray()); - assertArrayEquals( - [ - 'v1', , ['x1', ['y1', 'z1']], , - [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1, , - {100: [, 'e1']} - ], - original.toArray()); - }); - - it('testCopyInto', function() { - var supportsUint8Array = - !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'); - var original = new proto.jspb.test.TestClone(); - original.setStr('v1'); - var dest = new proto.jspb.test.TestClone(); - dest.setStr('override'); - var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]); - var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]); - var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]); - var destSimple1 = new proto.jspb.test.Simple1(['ox1', ['oy1', 'oz1']]); - var destSimple2 = new proto.jspb.test.Simple1(['ox2', ['oy2', 'oz2']]); - var destSimple3 = new proto.jspb.test.Simple1(['ox3', ['oy3', 'oz3']]); - original.setSimple1(simple1); - original.setSimple2List([simple2, simple3]); - dest.setSimple1(destSimple1); - dest.setSimple2List([destSimple2, destSimple3]); - var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123'; - var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456'; - original.setBytesField(bytes1); - dest.setBytesField(bytes2); - var extension = new proto.jspb.test.CloneExtension(); - extension.setExt('e1'); - original.setExtension(proto.jspb.test.CloneExtension.extField, extension); - - jspb.Message.copyInto(original, dest); - assertArrayEquals(original.toArray(), dest.toArray()); - assertEquals('x1', dest.getSimple1().getAString()); - assertEquals( - 'e1', - dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt()); - dest.getSimple1().setAString('new value'); - assertNotEquals( - dest.getSimple1().getAString(), original.getSimple1().getAString()); - if (supportsUint8Array) { - dest.getBytesField()[0] = 7; - assertObjectEquals(bytes1, original.getBytesField()); - assertObjectEquals(new Uint8Array([7, 2, 3]), dest.getBytesField()); - } else { - dest.setBytesField('789'); - assertObjectEquals(bytes1, original.getBytesField()); - assertObjectEquals('789', dest.getBytesField()); - } - dest.getExtension(proto.jspb.test.CloneExtension.extField) - .setExt('new value'); - assertNotEquals( - dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt(), - original.getExtension(proto.jspb.test.CloneExtension.extField) - .getExt()); - }); - - it('testCopyInto_notSameType', function() { - var a = new proto.jspb.test.TestClone(); - var b = new proto.jspb.test.Simple1(['str', ['s1', 's2']]); - - var e = assertThrows(function() { - jspb.Message.copyInto(a, b); - }); - assertContains('should have the same type', e.message); - }); - - it('testExtensions', function() { - var extension1 = new proto.jspb.test.IsExtension(['ext1field']); - var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2']]); - var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); - extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1); - extendable.setExtension( - proto.jspb.test.IndirectExtension.simple, extension2); - extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy'); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedStrList, ['a', 'b']); - var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]); - var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2']]); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedSimpleList, [s1, s2]); - assertObjectEquals( - extension1, - extendable.getExtension(proto.jspb.test.IsExtension.extField)); - assertObjectEquals( - extension2, - extendable.getExtension(proto.jspb.test.IndirectExtension.simple)); - assertObjectEquals( - 'xyzzy', - extendable.getExtension(proto.jspb.test.IndirectExtension.str)); - assertObjectEquals( - ['a', 'b'], - extendable.getExtension( - proto.jspb.test.IndirectExtension.repeatedStrList)); - assertObjectEquals( - [s1, s2], - extendable.getExtension( - proto.jspb.test.IndirectExtension.repeatedSimpleList)); - // Not supported yet, but it should work... - extendable.setExtension(proto.jspb.test.IndirectExtension.simple, null); - assertNull( - extendable.getExtension(proto.jspb.test.IndirectExtension.simple)); - extendable.setExtension(proto.jspb.test.IndirectExtension.str, null); - assertNull(extendable.getExtension(proto.jspb.test.IndirectExtension.str)); - - - // Extension fields with jspb.ignore = true are ignored. - assertUndefined(proto.jspb.test.IndirectExtension['ignored']); - assertUndefined(proto.jspb.test.HasExtensions['ignoredFloating']); - }); - - it('testFloatingExtensions', function() { - // From an autogenerated container. - var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); - var extension = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]); - extendable.setExtension(proto.jspb.test.simple1, extension); - assertObjectEquals( - extension, extendable.getExtension(proto.jspb.test.simple1)); - - // From _lib mode. - extension = new proto.jspb.test.ExtensionMessage(['s1']); - extendable = new proto.jspb.test.TestExtensionsMessage([16]); - extendable.setExtension(proto.jspb.test.floatingMsgField, extension); - extendable.setExtension(proto.jspb.test.floatingStrField, 's2'); - assertObjectEquals( - extension, extendable.getExtension(proto.jspb.test.floatingMsgField)); - assertObjectEquals( - 's2', extendable.getExtension(proto.jspb.test.floatingStrField)); - assertNotUndefined(proto.jspb.exttest.floatingMsgField); - assertNotUndefined(proto.jspb.exttest.floatingMsgFieldTwo); - assertNotUndefined(proto.jspb.exttest.beta.floatingStrField); - }); - - it('testToObject_extendedObject', function() { - var extension1 = new proto.jspb.test.IsExtension(['ext1field']); - var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2'], true]); - var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); - extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1); - extendable.setExtension( - proto.jspb.test.IndirectExtension.simple, extension2); - extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy'); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedStrList, ['a', 'b']); - var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2'], true]); - var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2'], false]); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedSimpleList, [s1, s2]); - assertObjectEquals( - { - str1: 'v1', - str2: 'v2', - str3: 'v3', - extField: {ext1: 'ext1field'}, - simple: { - aString: 'str', - aRepeatedStringList: ['s1', 's2'], - aBoolean: true - }, - str: 'xyzzy', - repeatedStrList: ['a', 'b'], - repeatedSimpleList: [ - {aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true}, - {aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false} - ] - }, - extendable.toObject()); - - // Now, with instances included. - assertObjectEquals( - { - str1: 'v1', - str2: 'v2', - str3: 'v3', - extField: { - ext1: 'ext1field', - $jspbMessageInstance: - extendable.getExtension(proto.jspb.test.IsExtension.extField) - }, - simple: { - aString: 'str', - aRepeatedStringList: ['s1', 's2'], - aBoolean: true, - $jspbMessageInstance: extendable.getExtension( - proto.jspb.test.IndirectExtension.simple) - }, - str: 'xyzzy', - repeatedStrList: ['a', 'b'], - repeatedSimpleList: [ - { - aString: 'foo', - aRepeatedStringList: ['s1', 's2'], - aBoolean: true, - $jspbMessageInstance: s1 - }, - { - aString: 'bar', - aRepeatedStringList: ['t1', 't2'], - aBoolean: false, - $jspbMessageInstance: s2 - } - ], - $jspbMessageInstance: extendable - }, - extendable.toObject(true /* opt_includeInstance */)); - }); - - it('testInitialization_emptyArray', function() { - var msg = new proto.jspb.test.HasExtensions([]); - assertArrayEquals([], msg.toArray()); - }); - - it('testInitialization_justExtensionObject', function() { - var msg = new proto.jspb.test.Empty([{1: 'hi'}]); - // The extensionObject is not moved from its original location. - assertArrayEquals([{1: 'hi'}], msg.toArray()); - }); - - it('testInitialization_incompleteList', function() { - var msg = new proto.jspb.test.Empty([1, {4: 'hi'}]); - // The extensionObject is not moved from its original location. - assertArrayEquals([1, {4: 'hi'}], msg.toArray()); - }); - - it('testInitialization_forwardCompatible', function() { - var msg = new proto.jspb.test.Empty([1, 2, 3, {1: 'hi'}]); - assertArrayEquals([1, 2, 3, {1: 'hi'}], msg.toArray()); - }); - - it('testExtendedMessageEnsureObject', - /** @suppress {visibility} */ function() { - var data = - new proto.jspb.test.HasExtensions(['str1', {'a_key': 'an_object'}]); - assertEquals('an_object', data.extensionObject_['a_key']); - }); - - it('testToObject_hasExtensionField', function() { - var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]); - var obj = data.toObject(); - assertEquals('str1', obj.str1); - assertEquals('ext1', obj.extField.ext1); - }); - - it('testGetExtension', function() { - var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]); - assertEquals('str1', data.getStr1()); - var extension = data.getExtension(proto.jspb.test.IsExtension.extField); - assertNotNull(extension); - assertEquals('ext1', extension.getExt1()); - }); - - it('testSetExtension', function() { - var data = new proto.jspb.test.HasExtensions(); - var extensionMessage = new proto.jspb.test.IsExtension(['is_extension']); - data.setExtension(proto.jspb.test.IsExtension.extField, extensionMessage); - var obj = data.toObject(); - assertNotNull(data.getExtension(proto.jspb.test.IsExtension.extField)); - assertEquals('is_extension', obj.extField.ext1); - }); - - /** - * Note that group is long deprecated, we only support it because JsPb has - * a goal of being able to generate JS classes for all proto descriptors. - */ - it('testGroups', function() { - var group = new proto.jspb.test.TestGroup(); - var someGroup = new proto.jspb.test.TestGroup.RepeatedGroup(); - someGroup.setId('g1'); - someGroup.setSomeBoolList([true, false]); - group.setRepeatedGroupList([someGroup]); - var groups = group.getRepeatedGroupList(); - assertEquals('g1', groups[0].getId()); - assertObjectEquals([true, false], groups[0].getSomeBoolList()); - assertObjectEquals( - {id: 'g1', someBoolList: [true, false]}, groups[0].toObject()); - assertObjectEquals( - { - repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}], - requiredGroup: {id: undefined}, - optionalGroup: undefined, - requiredSimple: {aRepeatedStringList: [], aString: undefined}, - optionalSimple: undefined, - id: undefined - }, - group.toObject()); - var group1 = new proto.jspb.test.TestGroup1(); - group1.setGroup(someGroup); - assertEquals(someGroup, group1.getGroup()); - }); - - it('testNonExtensionFieldsAfterExtensionRange', function() { - var data = [{'1': 'a_string'}]; - var message = new proto.jspb.test.Complex(data); - assertArrayEquals([], message.getARepeatedStringList()); - }); - - it('testReservedGetterNames', function() { - var message = new proto.jspb.test.TestReservedNames(); - message.setExtension$(11); - message.setExtension(proto.jspb.test.TestReservedNamesExtension.foo, 12); - assertEquals(11, message.getExtension$()); - assertEquals( - 12, - message.getExtension(proto.jspb.test.TestReservedNamesExtension.foo)); - assertObjectEquals({extension: 11, foo: 12}, message.toObject()); - }); - - it('testInitializeMessageWithUnsetOneof', function() { - var message = new proto.jspb.test.TestMessageWithOneof([]); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase - .PARTIAL_ONEOF_NOT_SET, - message.getPartialOneofCase()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase - .RECURSIVE_ONEOF_NOT_SET, - message.getRecursiveOneofCase()); - }); - - it('testInitializeMessageWithSingleValueSetInOneof', function() { - var message = new proto.jspb.test.TestMessageWithOneof([, , 'x']); - - assertEquals('x', message.getPone()); - assertEquals('', message.getPthree()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, - message.getPartialOneofCase()); - }); - - it('testKeepsLastWireValueSetInUnion_multipleValues', function() { - var message = new proto.jspb.test.TestMessageWithOneof([, , 'x', , 'y']); - - assertEquals('', message.getPone()); - assertEquals('y', message.getPthree()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE, - message.getPartialOneofCase()); - }); - - it('testSettingOneofFieldClearsOthers', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals('', message.getPone()); - assertEquals('', message.getPthree()); - assertFalse(message.hasPone()); - assertFalse(message.hasPthree()); - - message.setPone('hi'); - assertEquals('hi', message.getPone()); - assertEquals('', message.getPthree()); - assertTrue(message.hasPone()); - assertFalse(message.hasPthree()); - - message.setPthree('bye'); - assertEquals('', message.getPone()); - assertEquals('bye', message.getPthree()); - assertFalse(message.hasPone()); - assertTrue(message.hasPthree()); - }); - - it('testSettingOneofFieldDoesNotClearFieldsFromOtherUnions', function() { - var other = new proto.jspb.test.TestMessageWithOneof; - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals('', message.getPone()); - assertEquals('', message.getPthree()); - assertUndefined(message.getRone()); - assertFalse(message.hasPone()); - assertFalse(message.hasPthree()); - - message.setPone('hi'); - message.setRone(other); - assertEquals('hi', message.getPone()); - assertEquals('', message.getPthree()); - assertEquals(other, message.getRone()); - assertTrue(message.hasPone()); - assertFalse(message.hasPthree()); - - message.setPthree('bye'); - assertEquals('', message.getPone()); - assertEquals('bye', message.getPthree()); - assertEquals(other, message.getRone()); - assertFalse(message.hasPone()); - assertTrue(message.hasPthree()); - }); - - it('testUnsetsOneofCaseWhenFieldIsCleared', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase - .PARTIAL_ONEOF_NOT_SET, - message.getPartialOneofCase()); - - message.setPone('hi'); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, - message.getPartialOneofCase()); - - message.clearPone(); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase - .PARTIAL_ONEOF_NOT_SET, - message.getPartialOneofCase()); - }); - - it('testMessageWithDefaultOneofValues', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals(1234, message.getAone()); - assertEquals(0, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase - .DEFAULT_ONEOF_A_NOT_SET, - message.getDefaultOneofACase()); - - message.setAone(567); - assertEquals(567, message.getAone()); - assertEquals(0, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE, - message.getDefaultOneofACase()); - - message.setAtwo(890); - assertEquals(1234, message.getAone()); - assertEquals(890, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO, - message.getDefaultOneofACase()); - - message.clearAtwo(); - assertEquals(1234, message.getAone()); - assertEquals(0, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase - .DEFAULT_ONEOF_A_NOT_SET, - message.getDefaultOneofACase()); - }); - - it('testMessageWithDefaultOneofValues_defaultNotOnFirstField', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals(0, message.getBone()); - assertEquals(1234, message.getBtwo()); - assertFalse(message.hasBone()); - assertFalse(message.hasBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase - .DEFAULT_ONEOF_B_NOT_SET, - message.getDefaultOneofBCase()); - - message.setBone(2); - assertEquals(2, message.getBone()); - assertEquals(1234, message.getBtwo()); - assertTrue(message.hasBone()); - assertFalse(message.hasBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE, - message.getDefaultOneofBCase()); - - message.setBtwo(3); - assertEquals(0, message.getBone()); - assertFalse(message.hasBone()); - assertTrue(message.hasBtwo()); - assertEquals(3, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, - message.getDefaultOneofBCase()); - - message.clearBtwo(); - assertEquals(0, message.getBone()); - assertFalse(message.hasBone()); - assertFalse(message.hasBtwo()); - assertEquals(1234, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase - .DEFAULT_ONEOF_B_NOT_SET, - message.getDefaultOneofBCase()); - }); - - it('testInitializeMessageWithOneofDefaults', function() { - var message = - new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567)); - assertEquals(567, message.getAone()); - assertEquals(0, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE, - message.getDefaultOneofACase()); - - message = - new proto.jspb.test.TestMessageWithOneof(new Array(10).concat(890)); - assertEquals(1234, message.getAone()); - assertEquals(890, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO, - message.getDefaultOneofACase()); - - message = - new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567, 890)); - assertEquals(1234, message.getAone()); - assertEquals(890, message.getAtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO, - message.getDefaultOneofACase()); - }); - - it('testInitializeMessageWithOneofDefaults_defaultNotSetOnFirstField', - function() { - var message; - - message = - new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567)); - assertEquals(567, message.getBone()); - assertEquals(1234, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE, - message.getDefaultOneofBCase()); - - message = - new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890)); - assertEquals(0, message.getBone()); - assertEquals(890, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, - message.getDefaultOneofBCase()); - - message = new proto.jspb.test.TestMessageWithOneof( - new Array(11).concat(567, 890)); - assertEquals(0, message.getBone()); - assertEquals(890, message.getBtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, - message.getDefaultOneofBCase()); - }); - - it('testOneofContainingAnotherMessage', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals( - proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase - .RECURSIVE_ONEOF_NOT_SET, - message.getRecursiveOneofCase()); - - var other = new proto.jspb.test.TestMessageWithOneof; - message.setRone(other); - assertEquals(other, message.getRone()); - assertEquals('', message.getRtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RONE, - message.getRecursiveOneofCase()); - - message.setRtwo('hi'); - assertUndefined(message.getRone()); - assertEquals('hi', message.getRtwo()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RTWO, - message.getRecursiveOneofCase()); - }); - - it('testQueryingOneofCaseEnsuresOnlyOneFieldIsSetInUnderlyingArray', - function() { - var message = new proto.jspb.test.TestMessageWithOneof; - message.setPone('x'); - assertEquals('x', message.getPone()); - assertEquals('', message.getPthree()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, - message.getPartialOneofCase()); - - var array = message.toArray(); - assertEquals('x', array[2]); - assertUndefined(array[4]); - array[4] = 'y'; - - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE, - message.getPartialOneofCase()); - assertUndefined(array[2]); - assertEquals('y', array[4]); - }); - - it('testFloatingPointFieldsSupportNan', function() { - var assertNan = function(x) { - assertTrue( - 'Expected ' + x + ' (' + goog.typeOf(x) + ') to be NaN.', - typeof x === 'number' && isNaN(x)); - }; - - var message = new proto.jspb.test.FloatingPointFields([ - 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN', 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN' - ]); - assertNan(message.getOptionalFloatField()); - assertNan(message.getRequiredFloatField()); - assertNan(message.getRepeatedFloatFieldList()[0]); - assertNan(message.getRepeatedFloatFieldList()[1]); - assertNan(message.getDefaultFloatField()); - assertNan(message.getOptionalDoubleField()); - assertNan(message.getRequiredDoubleField()); - assertNan(message.getRepeatedDoubleFieldList()[0]); - assertNan(message.getRepeatedDoubleFieldList()[1]); - assertNan(message.getDefaultDoubleField()); - }); -}); diff --git a/js/compatibility_tests/v3.1.0/proto3_test.js b/js/compatibility_tests/v3.1.0/proto3_test.js deleted file mode 100644 index 696af3397..000000000 --- a/js/compatibility_tests/v3.1.0/proto3_test.js +++ /dev/null @@ -1,329 +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. - -goog.require('goog.crypt.base64'); -goog.require('goog.testing.asserts'); - -// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test -goog.require('proto.jspb.test.ForeignMessage'); - -// CommonJS-LoadFromFile: proto3_test_pb proto.jspb.test -goog.require('proto.jspb.test.Proto3Enum'); -goog.require('proto.jspb.test.TestProto3'); - - -var BYTES = new Uint8Array([1, 2, 8, 9]); -var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES); - - -/** - * Helper: compare a bytes field to an expected value - * @param {Uint8Array|string} arr - * @param {Uint8Array} expected - * @return {boolean} - */ -function bytesCompare(arr, expected) { - if (typeof arr === 'string') { - arr = goog.crypt.base64.decodeStringToUint8Array(arr); - } - if (arr.length != expected.length) { - return false; - } - for (var i = 0; i < arr.length; i++) { - if (arr[i] != expected[i]) { - return false; - } - } - return true; -} - - -describe('proto3Test', function() { - /** - * Test defaults for proto3 message fields. - */ - it('testProto3FieldDefaults', function() { - var msg = new proto.jspb.test.TestProto3(); - - assertEquals(msg.getOptionalInt32(), 0); - assertEquals(msg.getOptionalInt64(), 0); - assertEquals(msg.getOptionalUint32(), 0); - assertEquals(msg.getOptionalUint64(), 0); - assertEquals(msg.getOptionalSint32(), 0); - assertEquals(msg.getOptionalSint64(), 0); - assertEquals(msg.getOptionalFixed32(), 0); - assertEquals(msg.getOptionalFixed64(), 0); - assertEquals(msg.getOptionalSfixed32(), 0); - assertEquals(msg.getOptionalSfixed64(), 0); - assertEquals(msg.getOptionalFloat(), 0); - assertEquals(msg.getOptionalDouble(), 0); - assertEquals(msg.getOptionalString(), ''); - - // TODO(b/26173701): when we change bytes fields default getter to return - // Uint8Array, we'll want to switch this assertion to match the u8 case. - assertEquals(typeof msg.getOptionalBytes(), 'string'); - assertEquals(msg.getOptionalBytes_asU8() instanceof Uint8Array, true); - assertEquals(typeof msg.getOptionalBytes_asB64(), 'string'); - assertEquals(msg.getOptionalBytes().length, 0); - assertEquals(msg.getOptionalBytes_asU8().length, 0); - assertEquals(msg.getOptionalBytes_asB64(), ''); - - assertEquals(msg.getOptionalForeignEnum(), - proto.jspb.test.Proto3Enum.PROTO3_FOO); - assertEquals(msg.getOptionalForeignMessage(), undefined); - assertEquals(msg.getOptionalForeignMessage(), undefined); - - assertEquals(msg.getRepeatedInt32List().length, 0); - assertEquals(msg.getRepeatedInt64List().length, 0); - assertEquals(msg.getRepeatedUint32List().length, 0); - assertEquals(msg.getRepeatedUint64List().length, 0); - assertEquals(msg.getRepeatedSint32List().length, 0); - assertEquals(msg.getRepeatedSint64List().length, 0); - assertEquals(msg.getRepeatedFixed32List().length, 0); - assertEquals(msg.getRepeatedFixed64List().length, 0); - assertEquals(msg.getRepeatedSfixed32List().length, 0); - assertEquals(msg.getRepeatedSfixed64List().length, 0); - assertEquals(msg.getRepeatedFloatList().length, 0); - assertEquals(msg.getRepeatedDoubleList().length, 0); - assertEquals(msg.getRepeatedStringList().length, 0); - assertEquals(msg.getRepeatedBytesList().length, 0); - assertEquals(msg.getRepeatedForeignEnumList().length, 0); - assertEquals(msg.getRepeatedForeignMessageList().length, 0); - - }); - - - /** - * Test that all fields can be set and read via a serialization roundtrip. - */ - it('testProto3FieldSetGet', function() { - var msg = new proto.jspb.test.TestProto3(); - - msg.setOptionalInt32(-42); - msg.setOptionalInt64(-0x7fffffff00000000); - msg.setOptionalUint32(0x80000000); - msg.setOptionalUint64(0xf000000000000000); - msg.setOptionalSint32(-100); - msg.setOptionalSint64(-0x8000000000000000); - msg.setOptionalFixed32(1234); - msg.setOptionalFixed64(0x1234567800000000); - msg.setOptionalSfixed32(-1234); - msg.setOptionalSfixed64(-0x1234567800000000); - msg.setOptionalFloat(1.5); - msg.setOptionalDouble(-1.5); - msg.setOptionalBool(true); - msg.setOptionalString('hello world'); - msg.setOptionalBytes(BYTES); - var submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(16); - msg.setOptionalForeignMessage(submsg); - msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); - - msg.setRepeatedInt32List([-42]); - msg.setRepeatedInt64List([-0x7fffffff00000000]); - msg.setRepeatedUint32List([0x80000000]); - msg.setRepeatedUint64List([0xf000000000000000]); - msg.setRepeatedSint32List([-100]); - msg.setRepeatedSint64List([-0x8000000000000000]); - msg.setRepeatedFixed32List([1234]); - msg.setRepeatedFixed64List([0x1234567800000000]); - msg.setRepeatedSfixed32List([-1234]); - msg.setRepeatedSfixed64List([-0x1234567800000000]); - msg.setRepeatedFloatList([1.5]); - msg.setRepeatedDoubleList([-1.5]); - msg.setRepeatedBoolList([true]); - msg.setRepeatedStringList(['hello world']); - msg.setRepeatedBytesList([BYTES]); - submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(1000); - msg.setRepeatedForeignMessageList([submsg]); - msg.setRepeatedForeignEnumList([proto.jspb.test.Proto3Enum.PROTO3_BAR]); - - msg.setOneofString('asdf'); - - var serialized = msg.serializeBinary(); - msg = proto.jspb.test.TestProto3.deserializeBinary(serialized); - - assertEquals(msg.getOptionalInt32(), -42); - assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000); - assertEquals(msg.getOptionalUint32(), 0x80000000); - assertEquals(msg.getOptionalUint64(), 0xf000000000000000); - assertEquals(msg.getOptionalSint32(), -100); - assertEquals(msg.getOptionalSint64(), -0x8000000000000000); - assertEquals(msg.getOptionalFixed32(), 1234); - assertEquals(msg.getOptionalFixed64(), 0x1234567800000000); - assertEquals(msg.getOptionalSfixed32(), -1234); - assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000); - assertEquals(msg.getOptionalFloat(), 1.5); - assertEquals(msg.getOptionalDouble(), -1.5); - assertEquals(msg.getOptionalBool(), true); - assertEquals(msg.getOptionalString(), 'hello world'); - assertEquals(true, bytesCompare(msg.getOptionalBytes(), BYTES)); - assertEquals(msg.getOptionalForeignMessage().getC(), 16); - assertEquals(msg.getOptionalForeignEnum(), - proto.jspb.test.Proto3Enum.PROTO3_BAR); - - assertElementsEquals(msg.getRepeatedInt32List(), [-42]); - assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]); - assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]); - assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]); - assertElementsEquals(msg.getRepeatedSint32List(), [-100]); - assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]); - assertElementsEquals(msg.getRepeatedFixed32List(), [1234]); - assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]); - assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]); - assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]); - assertElementsEquals(msg.getRepeatedFloatList(), [1.5]); - assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]); - assertElementsEquals(msg.getRepeatedBoolList(), [true]); - assertElementsEquals(msg.getRepeatedStringList(), ['hello world']); - assertEquals(msg.getRepeatedBytesList().length, 1); - assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES)); - assertEquals(msg.getRepeatedForeignMessageList().length, 1); - assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000); - assertElementsEquals(msg.getRepeatedForeignEnumList(), - [proto.jspb.test.Proto3Enum.PROTO3_BAR]); - - assertEquals(msg.getOneofString(), 'asdf'); - }); - - - /** - * Test that oneofs continue to have a notion of field presence. - */ - it('testOneofs', function() { - var msg = new proto.jspb.test.TestProto3(); - - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes(), ''); - assertFalse(msg.hasOneofUint32()); - assertFalse(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - msg.setOneofUint32(42); - assertEquals(msg.getOneofUint32(), 42); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes(), ''); - assertTrue(msg.hasOneofUint32()); - assertFalse(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - - var submsg = new proto.jspb.test.ForeignMessage(); - msg.setOneofForeignMessage(submsg); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), submsg); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes(), ''); - assertFalse(msg.hasOneofUint32()); - assertFalse(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - msg.setOneofString('hello'); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), 'hello'); - assertEquals(msg.getOneofBytes(), ''); - assertFalse(msg.hasOneofUint32()); - assertTrue(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes_asB64(), - goog.crypt.base64.encodeString('\u00FF\u00FF')); - assertFalse(msg.hasOneofUint32()); - assertFalse(msg.hasOneofString()); - assertTrue(msg.hasOneofBytes()); - }); - - - /** - * Test that "default"-valued primitive fields are not emitted on the wire. - */ - it('testNoSerializeDefaults', function() { - var msg = new proto.jspb.test.TestProto3(); - - // Set each primitive to a non-default value, then back to its default, to - // ensure that the serialization is actually checking the value and not just - // whether it has ever been set. - msg.setOptionalInt32(42); - msg.setOptionalInt32(0); - msg.setOptionalDouble(3.14); - msg.setOptionalDouble(0.0); - msg.setOptionalBool(true); - msg.setOptionalBool(false); - msg.setOptionalString('hello world'); - msg.setOptionalString(''); - msg.setOptionalBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); - msg.setOptionalBytes(''); - msg.setOptionalForeignMessage(new proto.jspb.test.ForeignMessage()); - msg.setOptionalForeignMessage(null); - msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); - msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO); - msg.setOneofUint32(32); - msg.clearOneofUint32(); - - - var serialized = msg.serializeBinary(); - assertEquals(0, serialized.length); - }); - - /** - * Test that base64 string and Uint8Array are interchangeable in bytes fields. - */ - it('testBytesFieldsInterop', function() { - var msg = new proto.jspb.test.TestProto3(); - // Set as a base64 string and check all the getters work. - msg.setOptionalBytes(BYTES_B64); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - // Test binary serialize round trip doesn't break it. - msg = proto.jspb.test.TestProto3.deserializeBinary(msg.serializeBinary()); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - msg = new proto.jspb.test.TestProto3(); - // Set as a Uint8Array and check all the getters work. - msg.setOptionalBytes(BYTES); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - - }); -}); diff --git a/js/compatibility_tests/v3.1.0/proto3_test.proto b/js/compatibility_tests/v3.1.0/proto3_test.proto deleted file mode 100644 index acb671649..000000000 --- a/js/compatibility_tests/v3.1.0/proto3_test.proto +++ /dev/null @@ -1,89 +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. - -syntax = "proto3"; - -import "testbinary.proto"; - -package jspb.test; - -message TestProto3 { - int32 optional_int32 = 1; - int64 optional_int64 = 2; - uint32 optional_uint32 = 3; - uint64 optional_uint64 = 4; - sint32 optional_sint32 = 5; - sint64 optional_sint64 = 6; - fixed32 optional_fixed32 = 7; - fixed64 optional_fixed64 = 8; - sfixed32 optional_sfixed32 = 9; - sfixed64 optional_sfixed64 = 10; - float optional_float = 11; - double optional_double = 12; - bool optional_bool = 13; - string optional_string = 14; - bytes optional_bytes = 15; - - ForeignMessage optional_foreign_message = 19; - Proto3Enum optional_foreign_enum = 22; - - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated ForeignMessage repeated_foreign_message = 49; - repeated Proto3Enum repeated_foreign_enum = 52; - - - oneof oneof_field { - uint32 oneof_uint32 = 111; - ForeignMessage oneof_foreign_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } -} - -enum Proto3Enum { - PROTO3_FOO = 0; - PROTO3_BAR = 1; - PROTO3_BAZ = 2; -} diff --git a/js/compatibility_tests/v3.1.0/test.proto b/js/compatibility_tests/v3.1.0/test.proto deleted file mode 100644 index 48cb37e11..000000000 --- a/js/compatibility_tests/v3.1.0/test.proto +++ /dev/null @@ -1,262 +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: mwr@google.com (Mark Rawling) - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -import "google/protobuf/descriptor.proto"; - -package jspb.test; - -message Empty { -} - -enum OuterEnum { - FOO = 1; - BAR = 2; -} - -message EnumContainer { - optional OuterEnum outer_enum = 1; -} - -message Simple1 { - required string a_string = 1; - repeated string a_repeated_string = 2; - optional bool a_boolean = 3; -} - -// A message that differs from Simple1 only by name -message Simple2 { - required string a_string = 1; - repeated string a_repeated_string = 2; -} - -message SpecialCases { - required string normal = 1; - // Examples of Js reserved names that are converted to pb_. - required string default = 2; - required string function = 3; - required string var = 4; -} - -message OptionalFields { - message Nested { - optional int32 an_int = 1; - } - optional string a_string = 1; - required bool a_bool = 2; - optional Nested a_nested_message = 3; - repeated Nested a_repeated_message = 4; - repeated string a_repeated_string = 5; -} - -message HasExtensions { - optional string str1 = 1; - optional string str2 = 2; - optional string str3 = 3; - extensions 10 to max; -} - -message Complex { - message Nested { - required int32 an_int = 2; - } - required string a_string = 1; - required bool an_out_of_order_bool = 9; - optional Nested a_nested_message = 4; - repeated Nested a_repeated_message = 5; - repeated string a_repeated_string = 7; -} - -message OuterMessage { - // Make sure this doesn't conflict with the other Complex message. - message Complex { - optional int32 inner_complex_field = 1; - } -} - -message IsExtension { - extend HasExtensions { - optional IsExtension ext_field = 100; - } - optional string ext1 = 1; - - // Extensions of proto2 Descriptor messages will be ignored. - extend google.protobuf.EnumOptions { - optional string simple_option = 42113038; - } -} - -message IndirectExtension { - extend HasExtensions { - optional Simple1 simple = 101; - optional string str = 102; - repeated string repeated_str = 103; - repeated Simple1 repeated_simple = 104; - } -} - -extend HasExtensions { - optional Simple1 simple1 = 105; -} - -message DefaultValues { - enum Enum { - E1 = 13; - E2 = 77; - } - optional string string_field = 1 [default="default<>\'\"abc"]; - optional bool bool_field = 2 [default=true]; - optional int64 int_field = 3 [default=11]; - optional Enum enum_field = 4 [default=E1]; - optional string empty_field = 6 [default=""]; - optional bytes bytes_field = 8 [default="moo"]; // Base64 encoding is "bW9v" -} - -message FloatingPointFields { - optional float optional_float_field = 1; - required float required_float_field = 2; - repeated float repeated_float_field = 3; - optional float default_float_field = 4 [default = 2.0]; - optional double optional_double_field = 5; - required double required_double_field = 6; - repeated double repeated_double_field = 7; - optional double default_double_field = 8 [default = 2.0]; -} - -message TestClone { - optional string str = 1; - optional Simple1 simple1 = 3; - repeated Simple1 simple2 = 5; - optional bytes bytes_field = 6; - optional string unused = 7; - extensions 10 to max; -} - -message CloneExtension { - extend TestClone { - optional CloneExtension ext_field = 100; - } - optional string ext = 2; -} - -message TestGroup { - repeated group RepeatedGroup = 1 { - required string id = 1; - repeated bool some_bool = 2; - } - required group RequiredGroup = 2 { - required string id = 1; - } - optional group OptionalGroup = 3 { - required string id = 1; - } - optional string id = 4; - required Simple2 required_simple = 5; - optional Simple2 optional_simple = 6; -} - -message TestGroup1 { - optional TestGroup.RepeatedGroup group = 1; -} - -message TestReservedNames { - optional int32 extension = 1; - extensions 10 to max; -} - -message TestReservedNamesExtension { - extend TestReservedNames { - optional int32 foo = 10; - } -} - -message TestMessageWithOneof { - - oneof partial_oneof { - string pone = 3; - string pthree = 5; - } - - oneof recursive_oneof { - TestMessageWithOneof rone = 6; - string rtwo = 7; - } - - optional bool normal_field = 8; - repeated string repeated_field = 9; - - oneof default_oneof_a { - int32 aone = 10 [default = 1234]; - int32 atwo = 11; - } - - oneof default_oneof_b { - int32 bone = 12; - int32 btwo = 13 [default = 1234]; - } -} - -message TestEndsWithBytes { - optional int32 value = 1; - optional bytes data = 2; -} - -message TestMapFieldsNoBinary { - map map_string_string = 1; - map map_string_int32 = 2; - map map_string_int64 = 3; - map map_string_bool = 4; - map map_string_double = 5; - map map_string_enum = 6; - map map_string_msg = 7; - - map map_int32_string = 8; - map map_int64_string = 9; - map map_bool_string = 10; - - optional TestMapFieldsNoBinary test_map_fields = 11; - map map_string_testmapfields = 12; -} - -enum MapValueEnumNoBinary { - MAP_VALUE_FOO_NOBINARY = 0; - MAP_VALUE_BAR_NOBINARY = 1; - MAP_VALUE_BAZ_NOBINARY = 2; -} - -message MapValueMessageNoBinary { - optional int32 foo = 1; -} diff --git a/js/compatibility_tests/v3.1.0/test2.proto b/js/compatibility_tests/v3.1.0/test2.proto deleted file mode 100644 index 44e55effc..000000000 --- a/js/compatibility_tests/v3.1.0/test2.proto +++ /dev/null @@ -1,54 +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. - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.test; - -message TestExtensionsMessage { - optional int32 intfield = 1; - extensions 100 to max; -} - -message ExtensionMessage { - extend TestExtensionsMessage { - optional ExtensionMessage ext_field = 100; - } - optional string ext1 = 1; -} - -// Floating extensions are only supported when generating a _lib.js library. -extend TestExtensionsMessage { - optional ExtensionMessage floating_msg_field = 101; - optional string floating_str_field = 102; -} diff --git a/js/compatibility_tests/v3.1.0/test3.proto b/js/compatibility_tests/v3.1.0/test3.proto deleted file mode 100644 index 940a552ed..000000000 --- a/js/compatibility_tests/v3.1.0/test3.proto +++ /dev/null @@ -1,53 +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. - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.exttest; - -message TestExtensionsMessage { - optional int32 intfield = 1; - extensions 100 to max; -} - -message ExtensionMessage { - extend TestExtensionsMessage { - optional ExtensionMessage ext_field = 100; - } - optional string ext1 = 1; -} - -extend TestExtensionsMessage { - optional ExtensionMessage floating_msg_field = 101; - optional string floating_str_field = 102; -} diff --git a/js/compatibility_tests/v3.1.0/test4.proto b/js/compatibility_tests/v3.1.0/test4.proto deleted file mode 100644 index cf2451e9c..000000000 --- a/js/compatibility_tests/v3.1.0/test4.proto +++ /dev/null @@ -1,42 +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. - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.exttest; - -import "test3.proto"; - -extend TestExtensionsMessage { - optional ExtensionMessage floating_msg_field_two = 103; -} diff --git a/js/compatibility_tests/v3.1.0/test5.proto b/js/compatibility_tests/v3.1.0/test5.proto deleted file mode 100644 index 34979517e..000000000 --- a/js/compatibility_tests/v3.1.0/test5.proto +++ /dev/null @@ -1,44 +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. - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -package jspb.exttest.beta; - -message TestBetaExtensionsMessage { - extensions 100 to max; -} - -extend TestBetaExtensionsMessage { - optional string floating_str_field = 101; -} diff --git a/js/compatibility_tests/v3.1.0/testbinary.proto b/js/compatibility_tests/v3.1.0/testbinary.proto deleted file mode 100644 index 116f17fb5..000000000 --- a/js/compatibility_tests/v3.1.0/testbinary.proto +++ /dev/null @@ -1,212 +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. - -// LINT: ALLOW_GROUPS - -syntax = "proto2"; - - -package jspb.test; - -// These types are borrowed from `unittest.proto` in the protobuf tree. We want -// to ensure that the binary-format support will handle all field types -// properly. -message TestAllTypes { - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - optional group OptionalGroup = 16 { - optional int32 a = 17; - } - - optional ForeignMessage optional_foreign_message = 19; - optional ForeignEnum optional_foreign_enum = 22; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } - - repeated ForeignMessage repeated_foreign_message = 49; - repeated ForeignEnum repeated_foreign_enum = 52; - - // Packed repeated - repeated int32 packed_repeated_int32 = 61 [packed=true]; - repeated int64 packed_repeated_int64 = 62 [packed=true]; - repeated uint32 packed_repeated_uint32 = 63 [packed=true]; - repeated uint64 packed_repeated_uint64 = 64 [packed=true]; - repeated sint32 packed_repeated_sint32 = 65 [packed=true]; - repeated sint64 packed_repeated_sint64 = 66 [packed=true]; - repeated fixed32 packed_repeated_fixed32 = 67 [packed=true]; - repeated fixed64 packed_repeated_fixed64 = 68 [packed=true]; - repeated sfixed32 packed_repeated_sfixed32 = 69 [packed=true]; - repeated sfixed64 packed_repeated_sfixed64 = 70 [packed=true]; - repeated float packed_repeated_float = 71 [packed=true]; - repeated double packed_repeated_double = 72 [packed=true]; - repeated bool packed_repeated_bool = 73 [packed=true]; - - oneof oneof_field { - uint32 oneof_uint32 = 111; - ForeignMessage oneof_foreign_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } - -} - -message ForeignMessage { - optional int32 c = 1; -} - -enum ForeignEnum { - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -message TestExtendable { - extensions 1 to max; -} - -message ExtendsWithMessage { - extend TestExtendable { - optional ExtendsWithMessage optional_extension = 19; - repeated ExtendsWithMessage repeated_extension = 49; - } - optional int32 foo = 1; -} - -extend TestExtendable { - optional int32 extend_optional_int32 = 1; - optional int64 extend_optional_int64 = 2; - optional uint32 extend_optional_uint32 = 3; - optional uint64 extend_optional_uint64 = 4; - optional sint32 extend_optional_sint32 = 5; - optional sint64 extend_optional_sint64 = 6; - optional fixed32 extend_optional_fixed32 = 7; - optional fixed64 extend_optional_fixed64 = 8; - optional sfixed32 extend_optional_sfixed32 = 9; - optional sfixed64 extend_optional_sfixed64 = 10; - optional float extend_optional_float = 11; - optional double extend_optional_double = 12; - optional bool extend_optional_bool = 13; - optional string extend_optional_string = 14; - optional bytes extend_optional_bytes = 15; - optional ForeignEnum extend_optional_foreign_enum = 22; - - repeated int32 extend_repeated_int32 = 31; - repeated int64 extend_repeated_int64 = 32; - repeated uint32 extend_repeated_uint32 = 33; - repeated uint64 extend_repeated_uint64 = 34; - repeated sint32 extend_repeated_sint32 = 35; - repeated sint64 extend_repeated_sint64 = 36; - repeated fixed32 extend_repeated_fixed32 = 37; - repeated fixed64 extend_repeated_fixed64 = 38; - repeated sfixed32 extend_repeated_sfixed32 = 39; - repeated sfixed64 extend_repeated_sfixed64 = 40; - repeated float extend_repeated_float = 41; - repeated double extend_repeated_double = 42; - repeated bool extend_repeated_bool = 43; - repeated string extend_repeated_string = 44; - repeated bytes extend_repeated_bytes = 45; - repeated ForeignEnum extend_repeated_foreign_enum = 52; - - repeated int32 extend_packed_repeated_int32 = 61 [packed=true]; - repeated int64 extend_packed_repeated_int64 = 62 [packed=true]; - repeated uint32 extend_packed_repeated_uint32 = 63 [packed=true]; - repeated uint64 extend_packed_repeated_uint64 = 64 [packed=true]; - repeated sint32 extend_packed_repeated_sint32 = 65 [packed=true]; - repeated sint64 extend_packed_repeated_sint64 = 66 [packed=true]; - repeated fixed32 extend_packed_repeated_fixed32 = 67 [packed=true]; - repeated fixed64 extend_packed_repeated_fixed64 = 68 [packed=true]; - repeated sfixed32 extend_packed_repeated_sfixed32 = 69 [packed=true]; - repeated sfixed64 extend_packed_repeated_sfixed64 = 70 [packed=true]; - repeated float extend_packed_repeated_float = 71 [packed=true]; - repeated double extend_packed_repeated_double = 72 [packed=true]; - repeated bool extend_packed_repeated_bool = 73 [packed=true]; - repeated ForeignEnum extend_packed_repeated_foreign_enum = 82 - [packed=true]; - -} - -message TestMapFields { - map map_string_string = 1; - map map_string_int32 = 2; - map map_string_int64 = 3; - map map_string_bool = 4; - map map_string_double = 5; - map map_string_enum = 6; - map map_string_msg = 7; - - map map_int32_string = 8; - map map_int64_string = 9; - map map_bool_string = 10; - - optional TestMapFields test_map_fields = 11; - map map_string_testmapfields = 12; -} - -enum MapValueEnum { - MAP_VALUE_FOO = 0; - MAP_VALUE_BAR = 1; - MAP_VALUE_BAZ = 2; -} - -message MapValueMessage { - optional int32 foo = 1; -} diff --git a/js/compatibility_tests/v3.1.0/testempty.proto b/js/compatibility_tests/v3.1.0/testempty.proto deleted file mode 100644 index 960bce4e5..000000000 --- a/js/compatibility_tests/v3.1.0/testempty.proto +++ /dev/null @@ -1,34 +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. - -syntax = "proto2"; - -package javatests.com.google.apps.jspb; - diff --git a/js/data.proto b/js/data.proto deleted file mode 100644 index ca815caf6..000000000 --- a/js/data.proto +++ /dev/null @@ -1,50 +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: mwr@google.com (Mark Rawling) - -syntax = "proto2"; - -package jspb.test; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -// legacy data, must be nested -message data { - message NestedData { - required string str = 1; - } -} - -// new data, does not require nesting -message UnnestedData { - required string str = 1; -} diff --git a/js/debug.js b/js/debug.js deleted file mode 100644 index 9655b2e34..000000000 --- a/js/debug.js +++ /dev/null @@ -1,159 +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. - -/** - * @fileoverview Utilities to debug JSPB based proto objects. - */ - -goog.provide('jspb.debug'); - -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.object'); -goog.require('jspb.Map'); -goog.require('jspb.Message'); - - -/** - * Turns a proto into a human readable object that can i.e. be written to the - * console: `console.log(jspb.debug.dump(myProto))`. - * This function makes a best effort and may not work in all cases. It will not - * work in obfuscated and or optimized code. - * Use this in environments where {@see jspb.Message.prototype.toObject} is - * not available for code size reasons. - * @param {jspb.Message} message A jspb.Message. - * @return {Object} - */ -jspb.debug.dump = function(message) { - if (!goog.DEBUG) { - return null; - } - goog.asserts.assert(message instanceof jspb.Message, - 'jspb.Message instance expected'); - /** @type {Object} */ - var object = message; - goog.asserts.assert(object['getExtension'], - 'Only unobfuscated and unoptimized compilation modes supported.'); - return /** @type {Object} */ (jspb.debug.dump_(message)); -}; - - -/** - * Recursively introspects a message and the values its getters return to - * make a best effort in creating a human readable representation of the - * message. - * @param {?} thing A jspb.Message, Array or primitive type to dump. - * @return {*} - * @private - */ -jspb.debug.dump_ = function(thing) { - var type = goog.typeOf(thing); - var message = thing; // Copy because we don't want type inference on thing. - if (type == 'number' || type == 'string' || type == 'boolean' || - type == 'null' || type == 'undefined') { - return thing; - } - if (typeof Uint8Array !== 'undefined') { - // Will fail on IE9, where Uint8Array doesn't exist. - if (message instanceof Uint8Array) { - return thing; - } - } - - if (type == 'array') { - goog.asserts.assertArray(thing); - return goog.array.map(thing, jspb.debug.dump_); - } - - if (message instanceof jspb.Map) { - var mapObject = {}; - var entries = message.entries(); - for (var entry = entries.next(); !entry.done; entry = entries.next()) { - mapObject[entry.value[0]] = jspb.debug.dump_(entry.value[1]); - } - return mapObject; - } - - goog.asserts.assert(message instanceof jspb.Message, - 'Only messages expected: ' + thing); - var ctor = message.constructor; - var messageName = ctor.name || ctor.displayName; - var object = { - '$name': messageName - }; - for (var name in ctor.prototype) { - var match = /^get([A-Z]\w*)/.exec(name); - if (match && name != 'getExtension' && - name != 'getJsPbMessageId') { - var has = 'has' + match[1]; - if (!thing[has] || thing[has]()) { - var val = thing[name](); - object[jspb.debug.formatFieldName_(match[1])] = jspb.debug.dump_(val); - } - } - } - if (COMPILED && thing['extensionObject_']) { - object['$extensions'] = 'Recursive dumping of extensions not supported ' + - 'in compiled code. Switch to uncompiled or dump extension object ' + - 'directly'; - return object; - } - var extensionsObject; - for (var id in ctor['extensions']) { - if (/^\d+$/.test(id)) { - var ext = ctor['extensions'][id]; - var extVal = thing.getExtension(ext); - var fieldName = goog.object.getKeys(ext.fieldName)[0]; - if (extVal != null) { - if (!extensionsObject) { - extensionsObject = object['$extensions'] = {}; - } - extensionsObject[jspb.debug.formatFieldName_(fieldName)] = - jspb.debug.dump_(extVal); - } - } - } - return object; -}; - - -/** - * Formats a field name for output as camelCase. - * - * @param {string} name Name of the field. - * @return {string} - * @private - */ -jspb.debug.formatFieldName_ = function(name) { - // Name may be in TitleCase. - return name.replace(/^[A-Z]/, function(c) { - return c.toLowerCase(); - }); -}; diff --git a/js/debug_test.js b/js/debug_test.js deleted file mode 100644 index 509686996..000000000 --- a/js/debug_test.js +++ /dev/null @@ -1,188 +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. - -goog.setTestOnly(); - -goog.require('goog.testing.asserts'); - -// CommonJS-LoadFromFile: google-protobuf -goog.require('jspb.debug'); - -// CommonJS-LoadFromFile: test_pb -goog.require('proto.jspb.test.HasExtensions'); -goog.require('proto.jspb.test.IsExtension'); -goog.require('proto.jspb.test.MapValueMessageNoBinary'); -goog.require('proto.jspb.test.Simple1'); -goog.require('proto.jspb.test.TestMapFieldsNoBinary'); - - -// CommonJS-LoadFromFile: testbinary_pb -goog.require('proto.jspb.test.TestAllTypes'); - -describe('debugTest', function() { - it('testSimple1', function() { - if (COMPILED) { - return; - } - var message = new proto.jspb.test.Simple1(); - message.setAString('foo'); - assertObjectEquals({ - $name: 'proto.jspb.test.Simple1', - 'aString': 'foo', - 'aRepeatedStringList': [] - }, jspb.debug.dump(message)); - - message.setABoolean(true); - message.setARepeatedStringList(['1', '2']); - - assertObjectEquals({ - $name: 'proto.jspb.test.Simple1', - 'aString': 'foo', - 'aRepeatedStringList': ['1', '2'], - 'aBoolean': true - }, jspb.debug.dump(message)); - - message.clearAString(); - - assertObjectEquals({ - $name: 'proto.jspb.test.Simple1', - 'aRepeatedStringList': ['1', '2'], - 'aBoolean': true - }, jspb.debug.dump(message)); - }); - - it('testBytes', function() { - if (COMPILED || typeof Uint8Array == 'undefined') { - return; - } - var message = new proto.jspb.test.TestAllTypes(); - var bytes = new Uint8Array(4); - message.setOptionalBytes(bytes); - assertEquals(jspb.debug.dump(message)['optionalBytes'], bytes); - }); - - it('testExtensions', function() { - if (COMPILED) { - return; - } - var extension = new proto.jspb.test.IsExtension(); - extension.setExt1('ext1field'); - var extendable = new proto.jspb.test.HasExtensions(); - extendable.setStr1('v1'); - extendable.setStr2('v2'); - extendable.setStr3('v3'); - extendable.setExtension(proto.jspb.test.IsExtension.extField, extension); - - assertObjectEquals({ - '$name': 'proto.jspb.test.HasExtensions', - 'str1': 'v1', - 'str2': 'v2', - 'str3': 'v3', - '$extensions': { - 'extField': { - '$name': 'proto.jspb.test.IsExtension', - 'ext1': 'ext1field' - }, - 'repeatedSimpleList': [] - } - }, jspb.debug.dump(extendable)); - }); - - it('testMapsBasicTypes', function() { - if (COMPILED) { - return; - } - - var message = new proto.jspb.test.TestMapFieldsNoBinary(); - message.getMapBoolStringMap().set(true, 'bool_string_value1'); - message.getMapBoolStringMap().set(false, 'bool_string_value2'); - message.getMapStringInt32Map().set('key', 111); - - assertObjectEquals({ - '$name': 'proto.jspb.test.TestMapFieldsNoBinary', - 'mapBoolStringMap': { - true: 'bool_string_value1', - false: 'bool_string_value2' - }, - 'mapInt32StringMap': {}, - 'mapInt64StringMap': {}, - 'mapStringBoolMap': {}, - 'mapStringDoubleMap': {}, - 'mapStringEnumMap': {}, - 'mapStringInt32Map': { - 'key': 111 - }, - 'mapStringInt64Map': {}, - 'mapStringMsgMap': {}, - 'mapStringStringMap': {}, - 'mapStringTestmapfieldsMap': {} - }, jspb.debug.dump(message)); - }); - - it('testMapsMessageValues', function() { - if (COMPILED) { - return; - } - - var value1 = new proto.jspb.test.MapValueMessageNoBinary(); - value1.setFoo(1111); - var value2 = new proto.jspb.test.MapValueMessageNoBinary(); - value2.setFoo(2222); - - var message = new proto.jspb.test.TestMapFieldsNoBinary(); - message.getMapStringMsgMap().set('key1', value1); - message.getMapStringMsgMap().set('key2', value2); - - assertObjectEquals({ - '$name': 'proto.jspb.test.TestMapFieldsNoBinary', - 'mapBoolStringMap': {}, - 'mapInt32StringMap': {}, - 'mapInt64StringMap': {}, - 'mapStringBoolMap': {}, - 'mapStringDoubleMap': {}, - 'mapStringEnumMap': {}, - 'mapStringInt32Map': {}, - 'mapStringInt64Map': {}, - 'mapStringMsgMap': { - 'key1': { - '$name': 'proto.jspb.test.MapValueMessageNoBinary', - 'foo': 1111 - }, - 'key2': { - '$name': 'proto.jspb.test.MapValueMessageNoBinary', - 'foo': 2222 - } - }, - 'mapStringStringMap': {}, - 'mapStringTestmapfieldsMap': {} - }, jspb.debug.dump(message)); - }); - -}); diff --git a/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js b/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js deleted file mode 100644 index 94c2598a8..000000000 --- a/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js +++ /dev/null @@ -1,312 +0,0 @@ -/** - * @fileoverview The code size benchmark of apps JSPB for proto2 all types - */ -goog.module('protobuf.benchmark.code_size.apps_jspb.AllTypesProto2'); - -// const ForeignEnum = goog.require('proto.proto2_unittest.ForeignEnum'); -const ForeignMessage = goog.require('proto.proto2_unittest.ForeignMessage'); -const TestAllTypes = goog.require('proto.proto2_unittest.TestAllTypes'); -const TestPackedTypes = goog.require('proto.proto2_unittest.TestPackedTypes'); -const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase'); - -ensureCommonBaseLine(); - -/** - * The testing scenario is the same as kernel one. - * We have - * 1) add element to repeated fields - * 2) add element list to repeated fields - * 3) set fields - * 4) set repeated fields element - * 5) get fields - * 6) get repeated fields element - * 7) get repeated fields length - * @return {string} - */ -function accessAllTypes() { - const msgAllTypes = TestAllTypes.deserialize(''); - const msgPackedTypes = TestPackedTypes.deserialize(''); - - msgPackedTypes.addPackedBool(true); - [true].forEach((e) => msgPackedTypes.addPackedBool(e)); - msgAllTypes.addRepeatedBool(true, 1); - [true].forEach((e) => msgAllTypes.addRepeatedBool(e)); - msgAllTypes.addRepeatedBytes('1', 1); - ['1'].forEach((e) => msgAllTypes.addRepeatedBytes(e)); - msgPackedTypes.addPackedDouble(1.0); - [1.0].forEach((e) => msgPackedTypes.addPackedDouble(e)); - msgAllTypes.addRepeatedDouble(1.0, 1); - [1.0].forEach((e) => msgAllTypes.addRepeatedDouble(e)); - msgPackedTypes.addPackedFixed32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedFixed32(e)); - msgAllTypes.addRepeatedFixed32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedFixed32(e)); - msgPackedTypes.addPackedFixed64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedFixed64(e)); - msgAllTypes.addRepeatedFixed64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedFixed64(e)); - msgPackedTypes.addPackedFloat(1.0, 1); - [1.0].forEach((e) => msgPackedTypes.addPackedFloat(e)); - msgAllTypes.addRepeatedFloat(1.0, 1); - [1.0].forEach((e) => msgAllTypes.addRepeatedFloat(e)); - msgPackedTypes.addPackedInt32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedInt32(e)); - msgAllTypes.addRepeatedInt32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedInt32(e)); - msgPackedTypes.addPackedInt64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedInt64(e)); - msgAllTypes.addRepeatedInt64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedInt64(e)); - // msgPackedTypes.addPackedEnum(ForeignEnum.FOREIGN_BAR); - // [ForeignEnum.FOREIGN_BAR].forEach((e) => msgPackedTypes.addPackedEnum(e)); - // msgAllTypes.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR); - // [ForeignEnum.FOREIGN_BAR].forEach( - // (e) => msgAllTypes.addRepeatedForeignEnum(e)); - msgAllTypes.addRepeatedForeignMessage(ForeignMessage.deserialize(''), 1); - [ForeignMessage.deserialize('')].forEach( - (e) => msgAllTypes.addRepeatedForeignMessage(e)); - msgPackedTypes.addPackedSfixed32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedSfixed32(e)); - msgAllTypes.addRepeatedSfixed32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedSfixed32(e)); - msgPackedTypes.addPackedSfixed64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedSfixed64(e)); - msgAllTypes.addRepeatedSfixed64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedSfixed64(e)); - msgPackedTypes.addPackedSint32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedSint32(e)); - msgAllTypes.addRepeatedSint32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedSint32(e)); - msgPackedTypes.addPackedSint64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedSint64(e)); - msgAllTypes.addRepeatedSint64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedSint64(e)); - msgAllTypes.addRepeatedString('', 1); - [''].forEach((e) => msgAllTypes.addRepeatedString(e)); - msgPackedTypes.addPackedUint32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedUint32(e)); - msgAllTypes.addRepeatedUint32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedUint32(e)); - msgPackedTypes.addPackedUint64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedUint64(e)); - msgAllTypes.addRepeatedUint64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedUint64(e)); - - msgAllTypes.setOptionalBool(true); - msgAllTypes.setOptionalBytes(''); - msgAllTypes.setOptionalDouble(1.0); - msgAllTypes.setOptionalFixed32(1); - msgAllTypes.setOptionalFixed64(1); - msgAllTypes.setOptionalFloat(1.0); - msgAllTypes.setOptionalInt32(1); - msgAllTypes.setOptionalInt64(1); - // msgAllTypes.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAR); - msgAllTypes.setOptionalForeignMessage(ForeignMessage.deserialize('')); - msgAllTypes.setOptionalSfixed32(1); - msgAllTypes.setOptionalSfixed64(1); - msgAllTypes.setOptionalSint32(1); - msgAllTypes.setOptionalSint64(1); - msgAllTypes.setOptionalString(''); - msgAllTypes.setOptionalUint32(1); - msgAllTypes.setOptionalUint64(1); - msgPackedTypes.setPackedBoolList([true]); - let arrayVal; - arrayVal = msgPackedTypes.getPackedBoolList(); - arrayVal[0] = true; - msgPackedTypes.setPackedBoolList(arrayVal); - msgAllTypes.setRepeatedBoolList([true]); - arrayVal = msgAllTypes.getRepeatedBoolList(); - arrayVal[0] = true; - msgAllTypes.setRepeatedBoolList(arrayVal); - msgAllTypes.setRepeatedBytesList(['']); - arrayVal = msgAllTypes.getRepeatedBytesList_asB64(); - arrayVal[0] = ''; - msgAllTypes.setRepeatedBytesList(arrayVal); - msgPackedTypes.setPackedDoubleList([1.0]); - arrayVal = msgPackedTypes.getPackedDoubleList(); - arrayVal[0] = 1.0; - msgPackedTypes.setPackedDoubleList(arrayVal); - msgAllTypes.setRepeatedDoubleList([1.0]); - arrayVal = msgAllTypes.getRepeatedDoubleList(); - arrayVal[0] = 1.0; - msgAllTypes.setRepeatedDoubleList(arrayVal); - msgPackedTypes.setPackedFixed32List([1]); - arrayVal = msgPackedTypes.getPackedFixed32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedFixed32List(arrayVal); - msgAllTypes.setRepeatedFixed32List([1]); - arrayVal = msgAllTypes.getRepeatedFixed32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedFixed32List(arrayVal); - msgPackedTypes.setPackedFixed64List([1]); - arrayVal = msgPackedTypes.getPackedFixed64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedFixed64List(arrayVal); - msgAllTypes.setRepeatedFixed64List([1]); - arrayVal = msgAllTypes.getRepeatedFixed64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedFixed64List(arrayVal); - msgPackedTypes.setPackedFloatList([1.0]); - arrayVal = msgPackedTypes.getPackedFloatList(); - arrayVal[0] = 1.0; - msgPackedTypes.setPackedFloatList(arrayVal); - msgAllTypes.setRepeatedFloatList([1.0]); - arrayVal = msgAllTypes.getRepeatedFloatList(); - arrayVal[0] = 1.0; - msgAllTypes.setRepeatedFloatList(arrayVal); - msgPackedTypes.setPackedInt32List([1]); - arrayVal = msgPackedTypes.getPackedInt32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedInt32List(arrayVal); - msgAllTypes.setRepeatedInt32List([1]); - arrayVal = msgAllTypes.getRepeatedInt32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedInt32List(arrayVal); - msgPackedTypes.setPackedInt64List([1]); - arrayVal = msgPackedTypes.getPackedInt64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedInt64List(arrayVal); - msgAllTypes.setRepeatedInt64List([1]); - arrayVal = msgAllTypes.getRepeatedInt64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedInt64List(arrayVal); - // msgPackedTypes.setPackedEnumList([ForeignEnum.FOREIGN_BAR]); - // arrayVal = msgPackedTypes.getPackedEnumList(); - // arrayVal[0] = ForeignEnum.FOREIGN_BAR; - // msgPackedTypes.setPackedEnumList(arrayVal); - // msgAllTypes.setRepeatedForeignEnumList([ForeignEnum.FOREIGN_BAR]); - // arrayVal = msgAllTypes.getRepeatedForeignEnumList(); - // arrayVal[0] = ForeignEnum.FOREIGN_BAR; - // msgAllTypes.setRepeatedForeignEnumList(arrayVal); - msgAllTypes.setRepeatedForeignMessageList([ForeignMessage.deserialize('')]); - arrayVal = msgAllTypes.getRepeatedForeignMessageList(); - arrayVal[0] = ForeignMessage.deserialize(''); - msgAllTypes.setRepeatedForeignMessageList(arrayVal); - msgPackedTypes.setPackedSfixed32List([1]); - arrayVal = msgPackedTypes.getPackedSfixed32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedSfixed32List(arrayVal); - msgAllTypes.setRepeatedSfixed32List([1]); - arrayVal = msgAllTypes.getRepeatedSfixed32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedSfixed32List(arrayVal); - msgPackedTypes.setPackedSfixed64List([1]); - arrayVal = msgPackedTypes.getPackedSfixed64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedSfixed64List(arrayVal); - msgAllTypes.setRepeatedSfixed64List([1]); - arrayVal = msgAllTypes.getRepeatedSfixed64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedSfixed64List(arrayVal); - msgPackedTypes.setPackedSint32List([1]); - arrayVal = msgPackedTypes.getPackedSint32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedSint32List(arrayVal); - msgAllTypes.setRepeatedSint32List([1]); - arrayVal = msgAllTypes.getRepeatedSint32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedSint32List(arrayVal); - msgPackedTypes.setPackedSint64List([1]); - arrayVal = msgPackedTypes.getPackedSint64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedSint64List(arrayVal); - msgAllTypes.setRepeatedSint64List([1]); - arrayVal = msgAllTypes.getRepeatedSint64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedSint64List(arrayVal); - msgPackedTypes.setPackedUint32List([1]); - arrayVal = msgPackedTypes.getPackedUint32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedUint32List(arrayVal); - msgAllTypes.setRepeatedUint32List([1]); - arrayVal = msgAllTypes.getRepeatedUint32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedUint32List(arrayVal); - msgPackedTypes.setPackedUint64List([1]); - arrayVal = msgPackedTypes.getPackedUint64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedUint64List(arrayVal); - msgAllTypes.setRepeatedUint64List([1]); - arrayVal = msgAllTypes.getRepeatedUint64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedUint64List(arrayVal); - - let s = ''; - s += msgAllTypes.getOptionalBool() || false; - s += msgAllTypes.getOptionalBytes_asB64() || ''; - // s += msgAllTypes.getOptionalBytes_asU8() || new Uint8Array([]); - s += msgAllTypes.getOptionalDouble() || 0.0; - s += msgAllTypes.getOptionalFixed32() || 0; - s += msgAllTypes.getOptionalFixed64() || 0; - s += msgAllTypes.getOptionalFloat() || 0.0; - s += msgAllTypes.getOptionalInt32() || 0; - s += msgAllTypes.getOptionalInt64() || 0; - // s += msgAllTypes.getOptionalForeignEnum() || ForeignEnum.FOREIGN_BAR; - s += msgAllTypes.getOptionalForeignMessage(); - s += msgAllTypes.getOptionalSfixed32() || 0; - s += msgAllTypes.getOptionalSfixed64() || 0; - s += msgAllTypes.getOptionalSint32() || 0; - s += msgAllTypes.getOptionalSint64() || 0; - s += msgAllTypes.getOptionalString() || ''; - s += msgAllTypes.getOptionalUint32() || 0; - s += msgAllTypes.getOptionalUint64() || 0; - s += msgAllTypes.getRepeatedBoolList(); - s += msgAllTypes.getRepeatedBoolList()[0]; - s += msgAllTypes.getRepeatedBoolList().length; - s += msgAllTypes.getRepeatedBytesList_asB64(); - s += msgAllTypes.getRepeatedBytesList_asB64()[0]; - s += msgAllTypes.getRepeatedBytesList_asB64().length; - s += msgAllTypes.getRepeatedBytesList_asU8(); - s += msgAllTypes.getRepeatedDoubleList(); - s += msgAllTypes.getRepeatedDoubleList()[0]; - s += msgAllTypes.getRepeatedDoubleList().length; - s += msgAllTypes.getRepeatedFixed32List(); - s += msgAllTypes.getRepeatedFixed32List()[0]; - s += msgAllTypes.getRepeatedFixed32List().length; - s += msgAllTypes.getRepeatedFixed64List(); - s += msgAllTypes.getRepeatedFixed64List()[0]; - s += msgAllTypes.getRepeatedFixed64List().length; - s += msgAllTypes.getRepeatedFloatList(); - s += msgAllTypes.getRepeatedFloatList()[0]; - s += msgAllTypes.getRepeatedFloatList().length; - s += msgAllTypes.getRepeatedInt32List(); - s += msgAllTypes.getRepeatedInt32List()[0]; - s += msgAllTypes.getRepeatedInt32List().length; - s += msgAllTypes.getRepeatedInt64List(); - s += msgAllTypes.getRepeatedInt64List()[0]; - s += msgAllTypes.getRepeatedInt64List().length; - // s += msgAllTypes.getRepeatedForeignEnumList(); - // s += msgAllTypes.getRepeatedForeignEnumList()[0]; - // s += msgAllTypes.getRepeatedForeignEnumList().length; - s += msgAllTypes.getRepeatedForeignMessageList(); - s += msgAllTypes.getRepeatedForeignMessageList()[0]; - s += msgAllTypes.getRepeatedForeignMessageList().length; - s += msgAllTypes.getRepeatedSfixed32List(); - s += msgAllTypes.getRepeatedSfixed32List()[0]; - s += msgAllTypes.getRepeatedSfixed32List().length; - s += msgAllTypes.getRepeatedSfixed64List(); - s += msgAllTypes.getRepeatedSfixed64List()[0]; - s += msgAllTypes.getRepeatedSfixed64List().length; - s += msgAllTypes.getRepeatedSint32List(); - s += msgAllTypes.getRepeatedSint32List()[0]; - s += msgAllTypes.getRepeatedSint32List().length; - s += msgAllTypes.getRepeatedSint64List(); - s += msgAllTypes.getRepeatedSint64List()[0]; - s += msgAllTypes.getRepeatedSint64List().length; - s += msgAllTypes.getRepeatedStringList(); - s += msgAllTypes.getRepeatedStringList()[0]; - s += msgAllTypes.getRepeatedStringList().length; - s += msgAllTypes.getRepeatedUint32List(); - s += msgAllTypes.getRepeatedUint32List()[0]; - s += msgAllTypes.getRepeatedUint32List().length; - s += msgAllTypes.getRepeatedUint64List(); - s += msgAllTypes.getRepeatedUint64List()[0]; - s += msgAllTypes.getRepeatedUint64List().length; - - s += msgAllTypes.serialize(); - s += msgPackedTypes.serialize(); - - return s; -} - -goog.global['__hiddenTest'] += accessAllTypes(); diff --git a/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js b/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js deleted file mode 100644 index 9eb8126a8..000000000 --- a/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js +++ /dev/null @@ -1,312 +0,0 @@ -/** - * @fileoverview The code size benchmark of apps JSPB for proto3 all types - */ -goog.module('protobuf.benchmark.code_size.apps_jspb.AllTypesProto3'); - -// const ForeignEnum = goog.require('proto.proto3_unittest.ForeignEnum'); -const ForeignMessage = goog.require('proto.proto3_unittest.ForeignMessage'); -const TestAllTypes = goog.require('proto.proto3_unittest.TestAllTypes'); -const TestPackedTypes = goog.require('proto.proto3_unittest.TestPackedTypes'); -const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase'); - -ensureCommonBaseLine(); - -/** - * The testing scenario is the same as kernel one. - * We have - * 1) add element to repeated fields - * 2) add element list to repeated fields - * 3) set fields - * 4) set repeated fields element - * 5) get fields - * 6) get repeated fields element - * 7) get repeated fields length - * @return {string} - */ -function accessAllTypes() { - const msgAllTypes = TestAllTypes.deserialize(''); - const msgPackedTypes = TestPackedTypes.deserialize(''); - - msgPackedTypes.addPackedBool(true); - [true].forEach((e) => msgPackedTypes.addPackedBool(e)); - msgAllTypes.addRepeatedBool(true, 1); - [true].forEach((e) => msgAllTypes.addRepeatedBool(e)); - msgAllTypes.addRepeatedBytes('1', 1); - ['1'].forEach((e) => msgAllTypes.addRepeatedBytes(e)); - msgPackedTypes.addPackedDouble(1.0); - [1.0].forEach((e) => msgPackedTypes.addPackedDouble(e)); - msgAllTypes.addRepeatedDouble(1.0, 1); - [1.0].forEach((e) => msgAllTypes.addRepeatedDouble(e)); - msgPackedTypes.addPackedFixed32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedFixed32(e)); - msgAllTypes.addRepeatedFixed32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedFixed32(e)); - msgPackedTypes.addPackedFixed64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedFixed64(e)); - msgAllTypes.addRepeatedFixed64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedFixed64(e)); - msgPackedTypes.addPackedFloat(1.0, 1); - [1.0].forEach((e) => msgPackedTypes.addPackedFloat(e)); - msgAllTypes.addRepeatedFloat(1.0, 1); - [1.0].forEach((e) => msgAllTypes.addRepeatedFloat(e)); - msgPackedTypes.addPackedInt32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedInt32(e)); - msgAllTypes.addRepeatedInt32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedInt32(e)); - msgPackedTypes.addPackedInt64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedInt64(e)); - msgAllTypes.addRepeatedInt64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedInt64(e)); - // msgPackedTypes.addPackedEnum(ForeignEnum.FOREIGN_BAR); - // [ForeignEnum.FOREIGN_BAR].forEach((e) => msgPackedTypes.addPackedEnum(e)); - // msgAllTypes.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR); - // [ForeignEnum.FOREIGN_BAR].forEach( - // (e) => msgAllTypes.addRepeatedForeignEnum(e)); - msgAllTypes.addRepeatedForeignMessage(ForeignMessage.deserialize(''), 1); - [ForeignMessage.deserialize('')].forEach( - (e) => msgAllTypes.addRepeatedForeignMessage(e)); - msgPackedTypes.addPackedSfixed32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedSfixed32(e)); - msgAllTypes.addRepeatedSfixed32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedSfixed32(e)); - msgPackedTypes.addPackedSfixed64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedSfixed64(e)); - msgAllTypes.addRepeatedSfixed64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedSfixed64(e)); - msgPackedTypes.addPackedSint32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedSint32(e)); - msgAllTypes.addRepeatedSint32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedSint32(e)); - msgPackedTypes.addPackedSint64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedSint64(e)); - msgAllTypes.addRepeatedSint64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedSint64(e)); - msgAllTypes.addRepeatedString('', 1); - [''].forEach((e) => msgAllTypes.addRepeatedString(e)); - msgPackedTypes.addPackedUint32(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedUint32(e)); - msgAllTypes.addRepeatedUint32(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedUint32(e)); - msgPackedTypes.addPackedUint64(1, 1); - [1].forEach((e) => msgPackedTypes.addPackedUint64(e)); - msgAllTypes.addRepeatedUint64(1, 1); - [1].forEach((e) => msgAllTypes.addRepeatedUint64(e)); - - msgAllTypes.setOptionalBool(true); - msgAllTypes.setOptionalBytes(''); - msgAllTypes.setOptionalDouble(1.0); - msgAllTypes.setOptionalFixed32(1); - msgAllTypes.setOptionalFixed64(1); - msgAllTypes.setOptionalFloat(1.0); - msgAllTypes.setOptionalInt32(1); - msgAllTypes.setOptionalInt64(1); - // msgAllTypes.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAR); - msgAllTypes.setOptionalForeignMessage(ForeignMessage.deserialize('')); - msgAllTypes.setOptionalSfixed32(1); - msgAllTypes.setOptionalSfixed64(1); - msgAllTypes.setOptionalSint32(1); - msgAllTypes.setOptionalSint64(1); - msgAllTypes.setOptionalString(''); - msgAllTypes.setOptionalUint32(1); - msgAllTypes.setOptionalUint64(1); - msgPackedTypes.setPackedBoolList([true]); - let arrayVal; - arrayVal = msgPackedTypes.getPackedBoolList(); - arrayVal[0] = true; - msgPackedTypes.setPackedBoolList(arrayVal); - msgAllTypes.setRepeatedBoolList([true]); - arrayVal = msgAllTypes.getRepeatedBoolList(); - arrayVal[0] = true; - msgAllTypes.setRepeatedBoolList(arrayVal); - msgAllTypes.setRepeatedBytesList(['']); - arrayVal = msgAllTypes.getRepeatedBytesList_asB64(); - arrayVal[0] = ''; - msgAllTypes.setRepeatedBytesList(arrayVal); - msgPackedTypes.setPackedDoubleList([1.0]); - arrayVal = msgPackedTypes.getPackedDoubleList(); - arrayVal[0] = 1.0; - msgPackedTypes.setPackedDoubleList(arrayVal); - msgAllTypes.setRepeatedDoubleList([1.0]); - arrayVal = msgAllTypes.getRepeatedDoubleList(); - arrayVal[0] = 1.0; - msgAllTypes.setRepeatedDoubleList(arrayVal); - msgPackedTypes.setPackedFixed32List([1]); - arrayVal = msgPackedTypes.getPackedFixed32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedFixed32List(arrayVal); - msgAllTypes.setRepeatedFixed32List([1]); - arrayVal = msgAllTypes.getRepeatedFixed32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedFixed32List(arrayVal); - msgPackedTypes.setPackedFixed64List([1]); - arrayVal = msgPackedTypes.getPackedFixed64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedFixed64List(arrayVal); - msgAllTypes.setRepeatedFixed64List([1]); - arrayVal = msgAllTypes.getRepeatedFixed64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedFixed64List(arrayVal); - msgPackedTypes.setPackedFloatList([1.0]); - arrayVal = msgPackedTypes.getPackedFloatList(); - arrayVal[0] = 1.0; - msgPackedTypes.setPackedFloatList(arrayVal); - msgAllTypes.setRepeatedFloatList([1.0]); - arrayVal = msgAllTypes.getRepeatedFloatList(); - arrayVal[0] = 1.0; - msgAllTypes.setRepeatedFloatList(arrayVal); - msgPackedTypes.setPackedInt32List([1]); - arrayVal = msgPackedTypes.getPackedInt32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedInt32List(arrayVal); - msgAllTypes.setRepeatedInt32List([1]); - arrayVal = msgAllTypes.getRepeatedInt32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedInt32List(arrayVal); - msgPackedTypes.setPackedInt64List([1]); - arrayVal = msgPackedTypes.getPackedInt64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedInt64List(arrayVal); - msgAllTypes.setRepeatedInt64List([1]); - arrayVal = msgAllTypes.getRepeatedInt64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedInt64List(arrayVal); - // msgPackedTypes.setPackedEnumList([ForeignEnum.FOREIGN_BAR]); - // arrayVal = msgPackedTypes.getPackedEnumList(); - // arrayVal[0] = ForeignEnum.FOREIGN_BAR; - // msgPackedTypes.setPackedEnumList(arrayVal); - // msgAllTypes.setRepeatedForeignEnumList([ForeignEnum.FOREIGN_BAR]); - // arrayVal = msgAllTypes.getRepeatedForeignEnumList(); - // arrayVal[0] = ForeignEnum.FOREIGN_BAR; - // msgAllTypes.setRepeatedForeignEnumList(arrayVal); - msgAllTypes.setRepeatedForeignMessageList([ForeignMessage.deserialize('')]); - arrayVal = msgAllTypes.getRepeatedForeignMessageList(); - arrayVal[0] = ForeignMessage.deserialize(''); - msgAllTypes.setRepeatedForeignMessageList(arrayVal); - msgPackedTypes.setPackedSfixed32List([1]); - arrayVal = msgPackedTypes.getPackedSfixed32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedSfixed32List(arrayVal); - msgAllTypes.setRepeatedSfixed32List([1]); - arrayVal = msgAllTypes.getRepeatedSfixed32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedSfixed32List(arrayVal); - msgPackedTypes.setPackedSfixed64List([1]); - arrayVal = msgPackedTypes.getPackedSfixed64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedSfixed64List(arrayVal); - msgAllTypes.setRepeatedSfixed64List([1]); - arrayVal = msgAllTypes.getRepeatedSfixed64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedSfixed64List(arrayVal); - msgPackedTypes.setPackedSint32List([1]); - arrayVal = msgPackedTypes.getPackedSint32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedSint32List(arrayVal); - msgAllTypes.setRepeatedSint32List([1]); - arrayVal = msgAllTypes.getRepeatedSint32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedSint32List(arrayVal); - msgPackedTypes.setPackedSint64List([1]); - arrayVal = msgPackedTypes.getPackedSint64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedSint64List(arrayVal); - msgAllTypes.setRepeatedSint64List([1]); - arrayVal = msgAllTypes.getRepeatedSint64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedSint64List(arrayVal); - msgPackedTypes.setPackedUint32List([1]); - arrayVal = msgPackedTypes.getPackedUint32List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedUint32List(arrayVal); - msgAllTypes.setRepeatedUint32List([1]); - arrayVal = msgAllTypes.getRepeatedUint32List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedUint32List(arrayVal); - msgPackedTypes.setPackedUint64List([1]); - arrayVal = msgPackedTypes.getPackedUint64List(); - arrayVal[0] = 1; - msgPackedTypes.setPackedUint64List(arrayVal); - msgAllTypes.setRepeatedUint64List([1]); - arrayVal = msgAllTypes.getRepeatedUint64List(); - arrayVal[0] = 1; - msgAllTypes.setRepeatedUint64List(arrayVal); - - let s = ''; - s += msgAllTypes.getOptionalBool() || false; - s += msgAllTypes.getOptionalBytes_asB64() || ''; - // s += msgAllTypes.getOptionalBytes_asU8() || new Uint8Array([]); - s += msgAllTypes.getOptionalDouble() || 0.0; - s += msgAllTypes.getOptionalFixed32() || 0; - s += msgAllTypes.getOptionalFixed64() || 0; - s += msgAllTypes.getOptionalFloat() || 0.0; - s += msgAllTypes.getOptionalInt32() || 0; - s += msgAllTypes.getOptionalInt64() || 0; - // s += msgAllTypes.getOptionalForeignEnum() || ForeignEnum.FOREIGN_BAR; - s += msgAllTypes.getOptionalForeignMessage(); - s += msgAllTypes.getOptionalSfixed32() || 0; - s += msgAllTypes.getOptionalSfixed64() || 0; - s += msgAllTypes.getOptionalSint32() || 0; - s += msgAllTypes.getOptionalSint64() || 0; - s += msgAllTypes.getOptionalString() || ''; - s += msgAllTypes.getOptionalUint32() || 0; - s += msgAllTypes.getOptionalUint64() || 0; - s += msgAllTypes.getRepeatedBoolList(); - s += msgAllTypes.getRepeatedBoolList()[0]; - s += msgAllTypes.getRepeatedBoolList().length; - s += msgAllTypes.getRepeatedBytesList_asB64(); - s += msgAllTypes.getRepeatedBytesList_asB64()[0]; - s += msgAllTypes.getRepeatedBytesList_asB64().length; - s += msgAllTypes.getRepeatedBytesList_asU8(); - s += msgAllTypes.getRepeatedDoubleList(); - s += msgAllTypes.getRepeatedDoubleList()[0]; - s += msgAllTypes.getRepeatedDoubleList().length; - s += msgAllTypes.getRepeatedFixed32List(); - s += msgAllTypes.getRepeatedFixed32List()[0]; - s += msgAllTypes.getRepeatedFixed32List().length; - s += msgAllTypes.getRepeatedFixed64List(); - s += msgAllTypes.getRepeatedFixed64List()[0]; - s += msgAllTypes.getRepeatedFixed64List().length; - s += msgAllTypes.getRepeatedFloatList(); - s += msgAllTypes.getRepeatedFloatList()[0]; - s += msgAllTypes.getRepeatedFloatList().length; - s += msgAllTypes.getRepeatedInt32List(); - s += msgAllTypes.getRepeatedInt32List()[0]; - s += msgAllTypes.getRepeatedInt32List().length; - s += msgAllTypes.getRepeatedInt64List(); - s += msgAllTypes.getRepeatedInt64List()[0]; - s += msgAllTypes.getRepeatedInt64List().length; - // s += msgAllTypes.getRepeatedForeignEnumList(); - // s += msgAllTypes.getRepeatedForeignEnumList()[0]; - // s += msgAllTypes.getRepeatedForeignEnumList().length; - s += msgAllTypes.getRepeatedForeignMessageList(); - s += msgAllTypes.getRepeatedForeignMessageList()[0]; - s += msgAllTypes.getRepeatedForeignMessageList().length; - s += msgAllTypes.getRepeatedSfixed32List(); - s += msgAllTypes.getRepeatedSfixed32List()[0]; - s += msgAllTypes.getRepeatedSfixed32List().length; - s += msgAllTypes.getRepeatedSfixed64List(); - s += msgAllTypes.getRepeatedSfixed64List()[0]; - s += msgAllTypes.getRepeatedSfixed64List().length; - s += msgAllTypes.getRepeatedSint32List(); - s += msgAllTypes.getRepeatedSint32List()[0]; - s += msgAllTypes.getRepeatedSint32List().length; - s += msgAllTypes.getRepeatedSint64List(); - s += msgAllTypes.getRepeatedSint64List()[0]; - s += msgAllTypes.getRepeatedSint64List().length; - s += msgAllTypes.getRepeatedStringList(); - s += msgAllTypes.getRepeatedStringList()[0]; - s += msgAllTypes.getRepeatedStringList().length; - s += msgAllTypes.getRepeatedUint32List(); - s += msgAllTypes.getRepeatedUint32List()[0]; - s += msgAllTypes.getRepeatedUint32List().length; - s += msgAllTypes.getRepeatedUint64List(); - s += msgAllTypes.getRepeatedUint64List()[0]; - s += msgAllTypes.getRepeatedUint64List().length; - - s += msgAllTypes.serialize(); - s += msgPackedTypes.serialize(); - - return s; -} - -goog.global['__hiddenTest'] += accessAllTypes(); diff --git a/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js b/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js deleted file mode 100644 index 7bea88a27..000000000 --- a/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @fileoverview The code size benchmark of apps JSPB for proto2 popular types. - */ -goog.module('protobuf.benchmark.code_size.apps_jspb.PopularTypesProto2'); - -// const ForeignEnum = goog.require('proto.proto2_unittest.ForeignEnum'); -const ForeignMessage = goog.require('proto.proto2_unittest.ForeignMessage'); -const TestAllTypes = goog.require('proto.proto2_unittest.TestAllTypes'); -const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase'); - -ensureCommonBaseLine(); - -/** - * @return {string} - */ -function accessPopularTypes() { - const msgAllTypes = TestAllTypes.deserialize(''); - msgAllTypes.addRepeatedForeignMessage(ForeignMessage.deserialize(''), 1); - [ForeignMessage.deserialize('')].forEach( - (e) => msgAllTypes.addRepeatedForeignMessage(e)); - - msgAllTypes.setOptionalString(''); - msgAllTypes.setOptionalInt32(1); - msgAllTypes.setOptionalForeignMessage(ForeignMessage.deserialize('')); - msgAllTypes.setOptionalBool(true); - // msgAllTypes.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAR); - msgAllTypes.setOptionalInt64(1); - msgAllTypes.setOptionalDouble(1.0); - msgAllTypes.setRepeatedForeignMessageList([ForeignMessage.deserialize('')]); - let arrayVal = msgAllTypes.getRepeatedForeignMessageList(); - arrayVal[0] = ForeignMessage.deserialize(''); - msgAllTypes.setRepeatedForeignMessageList(arrayVal); - msgAllTypes.setOptionalUint64(1); - - let s = ''; - s += msgAllTypes.getOptionalString(); - s += msgAllTypes.getOptionalInt32(); - s += msgAllTypes.getOptionalForeignMessage(); - s += msgAllTypes.getOptionalBool(); - // s += msgAllTypes.getOptionalForeignEnum(); - s += msgAllTypes.getOptionalInt64(); - s += msgAllTypes.getOptionalDouble(); - s += msgAllTypes.getRepeatedForeignMessageList(); - s += msgAllTypes.getRepeatedForeignMessageList()[0]; - s += msgAllTypes.getRepeatedForeignMessageList().length; - s += msgAllTypes.getOptionalUint64(); - - s += msgAllTypes.serialize(); - - return s; -} - -goog.global['__hiddenTest'] += accessPopularTypes(); diff --git a/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js b/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js deleted file mode 100644 index 9b804283d..000000000 --- a/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @fileoverview The code size benchmark of apps JSPB for proto3 popular types. - */ -goog.module('protobuf.benchmark.code_size.apps_jspb.PopularTypesProto3'); - -// const ForeignEnum = goog.require('proto.proto3_unittest.ForeignEnum'); -const ForeignMessage = goog.require('proto.proto3_unittest.ForeignMessage'); -const TestAllTypes = goog.require('proto.proto3_unittest.TestAllTypes'); -const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase'); - -ensureCommonBaseLine(); - -/** - * @return {string} - */ -function accessPopularTypes() { - const msgAllTypes = TestAllTypes.deserialize(''); - msgAllTypes.addRepeatedForeignMessage(ForeignMessage.deserialize(''), 1); - [ForeignMessage.deserialize('')].forEach( - (e) => msgAllTypes.addRepeatedForeignMessage(e)); - - msgAllTypes.setOptionalString(''); - msgAllTypes.setOptionalInt32(1); - msgAllTypes.setOptionalForeignMessage(ForeignMessage.deserialize('')); - msgAllTypes.setOptionalBool(true); - // msgAllTypes.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAR); - msgAllTypes.setOptionalInt64(1); - msgAllTypes.setOptionalDouble(1.0); - msgAllTypes.setRepeatedForeignMessageList([ForeignMessage.deserialize('')]); - let arrayVal = msgAllTypes.getRepeatedForeignMessageList(); - arrayVal[0] = ForeignMessage.deserialize(''); - msgAllTypes.setRepeatedForeignMessageList(arrayVal); - msgAllTypes.setOptionalUint64(1); - - let s = ''; - s += msgAllTypes.getOptionalString(); - s += msgAllTypes.getOptionalInt32(); - s += msgAllTypes.getOptionalForeignMessage(); - s += msgAllTypes.getOptionalBool(); - // s += msgAllTypes.getOptionalForeignEnum(); - s += msgAllTypes.getOptionalInt64(); - s += msgAllTypes.getOptionalDouble(); - s += msgAllTypes.getRepeatedForeignMessageList(); - s += msgAllTypes.getRepeatedForeignMessageList()[0]; - s += msgAllTypes.getRepeatedForeignMessageList().length; - s += msgAllTypes.getOptionalUint64(); - - s += msgAllTypes.serialize(); - - return s; -} - -goog.global['__hiddenTest'] += accessPopularTypes(); diff --git a/js/experimental/benchmarks/code_size/code_size_base.js b/js/experimental/benchmarks/code_size/code_size_base.js deleted file mode 100644 index 04f6a4734..000000000 --- a/js/experimental/benchmarks/code_size/code_size_base.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @fileoverview Ensures types are live that would be live in a typical g3 - * JS program. - * - * Making certain constructs live ensures that we compare against the same - * baseline for all code size benchmarks. This increases the size - * of our benchmarks, but note that this size in a regular app would be - * attributes to other places. - */ -goog.module('protobuf.benchmark.codeSize.codeSizeBase'); - - -/** - * Ensures that the array iterator polyfill is live. - * @return {string} - */ -function useArrayIterator() { - let a = []; - let s = ''; - for (let value of a) { - s += value; - } - return s; -} - -/** - * Ensures that the symbol iterator polyfill is live. - * @return {string} - */ -function useSymbolIterator() { - /** - * @implements {Iterable} - */ - class Foo { - /** @return {!Iterator} */ - [Symbol.iterator]() {} - } - - let foo = new Foo(); - let s = ''; - for (let value of foo) { - s += value; - } - return s; -} - -/** - * Ensures certain base libs are live so we can have an apples to apples - * comparison for code size of different implementations - */ -function ensureCommonBaseLine() { - goog.global['__hiddenTest'] += useArrayIterator(); - goog.global['__hiddenTest'] += useSymbolIterator(); -} - - -exports = {ensureCommonBaseLine}; diff --git a/js/experimental/benchmarks/code_size/kernel/all_types.js b/js/experimental/benchmarks/code_size/kernel/all_types.js deleted file mode 100644 index 17cc7a6ef..000000000 --- a/js/experimental/benchmarks/code_size/kernel/all_types.js +++ /dev/null @@ -1,227 +0,0 @@ -/** - * @fileoverview The code size benchmark of binary kernel for accessing all - * types setter and getter. - */ -goog.module('protobuf.benchmark.KernelCodeSizeBenchmarkAllTypes'); - -const ByteString = goog.require('protobuf.ByteString'); -const Int64 = goog.require('protobuf.Int64'); -const Kernel = goog.require('protobuf.runtime.Kernel'); -const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); -const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase'); - -ensureCommonBaseLine(); - - -/** - * @return {string} - */ -function accessAllTypes() { - const message = new TestMessage(Kernel.createEmpty()); - - message.addPackedBoolElement(1, true); - message.addPackedBoolIterable(1, [true]); - message.addUnpackedBoolElement(1, true); - message.addUnpackedBoolIterable(1, [true]); - message.addRepeatedBytesElement(1, ByteString.EMPTY); - message.addRepeatedBytesIterable(1, [ByteString.EMPTY]); - message.addPackedDoubleElement(1, 1.0); - message.addPackedDoubleIterable(1, [1.0]); - message.addUnpackedDoubleElement(1, 1.0); - message.addUnpackedDoubleIterable(1, [1.0]); - message.addPackedFixed32Element(1, 1); - message.addPackedFixed32Iterable(1, [1]); - message.addUnpackedFixed32Element(1, 1); - message.addUnpackedFixed32Iterable(1, [1]); - message.addPackedFixed64Element(1, Int64.fromBits(0, 1)); - message.addPackedFixed64Iterable(1, [Int64.fromBits(0, 1)]); - message.addUnpackedFixed64Element(1, Int64.fromBits(0, 1)); - message.addUnpackedFixed64Iterable(1, [Int64.fromBits(0, 1)]); - message.addPackedFloatElement(1, 1.0); - message.addPackedFloatIterable(1, [1.0]); - message.addUnpackedFloatElement(1, 1.0); - message.addUnpackedFloatIterable(1, [1.0]); - message.addPackedInt32Element(1, 1); - message.addPackedInt32Iterable(1, [1]); - message.addUnpackedInt32Element(1, 1); - message.addUnpackedInt32Iterable(1, [1]); - message.addPackedInt64Element(1, Int64.fromBits(0, 1)); - message.addPackedInt64Iterable(1, [Int64.fromBits(0, 1)]); - message.addUnpackedInt64Element(1, Int64.fromBits(0, 1)); - message.addUnpackedInt64Iterable(1, [Int64.fromBits(0, 1)]); - message.addRepeatedMessageElement(1, message, TestMessage.instanceCreator); - message.addRepeatedMessageIterable(1, [message], TestMessage.instanceCreator); - message.addPackedSfixed32Element(1, 1); - message.addPackedSfixed32Iterable(1, [1]); - message.addUnpackedSfixed32Element(1, 1); - message.addUnpackedSfixed32Iterable(1, [1]); - message.addPackedSfixed64Element(1, Int64.fromBits(0, 1)); - message.addPackedSfixed64Iterable(1, [Int64.fromBits(0, 1)]); - message.addUnpackedSfixed64Element(1, Int64.fromBits(0, 1)); - message.addUnpackedSfixed64Iterable(1, [Int64.fromBits(0, 1)]); - message.addPackedSint32Element(1, 1); - message.addPackedSint32Iterable(1, [1]); - message.addUnpackedSint32Element(1, 1); - message.addUnpackedSint32Iterable(1, [1]); - message.addPackedSint64Element(1, Int64.fromBits(0, 1)); - message.addPackedSint64Iterable(1, [Int64.fromBits(0, 1)]); - message.addUnpackedSint64Element(1, Int64.fromBits(0, 1)); - message.addUnpackedSint64Iterable(1, [Int64.fromBits(0, 1)]); - message.addRepeatedStringElement(1, ''); - message.addRepeatedStringIterable(1, ['']); - message.addPackedUint32Element(1, 1); - message.addPackedUint32Iterable(1, [1]); - message.addUnpackedUint32Element(1, 1); - message.addUnpackedUint32Iterable(1, [1]); - message.addPackedUint64Element(1, Int64.fromBits(0, 1)); - message.addPackedUint64Iterable(1, [Int64.fromBits(0, 1)]); - message.addUnpackedUint64Element(1, Int64.fromBits(0, 1)); - message.addUnpackedUint64Iterable(1, [Int64.fromBits(0, 1)]); - - message.setBool(1, true); - message.setBytes(1, ByteString.EMPTY); - message.setDouble(1, 1.0); - message.setFixed32(1, 1); - message.setFixed64(1, Int64.fromBits(0, 1)); - message.setFloat(1, 1.0); - message.setInt32(1, 1); - message.setInt64(1, Int64.fromBits(0, 1)); - message.setMessage(1, message); - message.setSfixed32(1, 1); - message.setSfixed64(1, Int64.fromBits(0, 1)); - message.setSint32(1, 1); - message.setSint64(1, Int64.fromBits(0, 1)); - message.setString(1, 'abc'); - message.setUint32(1, 1); - message.setUint64(1, Int64.fromBits(0, 1)); - message.setPackedBoolElement(1, 0, true); - message.setPackedBoolIterable(1, [true]); - message.setUnpackedBoolElement(1, 0, true); - message.setUnpackedBoolIterable(1, [true]); - message.setRepeatedBytesElement(1, 0, ByteString.EMPTY); - message.setRepeatedBytesIterable(1, [ByteString.EMPTY]); - message.setPackedDoubleElement(1, 0, 1.0); - message.setPackedDoubleIterable(1, [1.0]); - message.setUnpackedDoubleElement(1, 0, 1.0); - message.setUnpackedDoubleIterable(1, [1.0]); - message.setPackedFixed32Element(1, 0, 1); - message.setPackedFixed32Iterable(1, [1]); - message.setUnpackedFixed32Element(1, 0, 1); - message.setUnpackedFixed32Iterable(1, [1]); - message.setPackedFixed64Element(1, 0, Int64.fromBits(0, 1)); - message.setPackedFixed64Iterable(1, [Int64.fromBits(0, 1)]); - message.setUnpackedFixed64Element(1, 0, Int64.fromBits(0, 1)); - message.setUnpackedFixed64Iterable(1, [Int64.fromBits(0, 1)]); - message.setPackedFloatElement(1, 0, 1.0); - message.setPackedFloatIterable(1, [1.0]); - message.setUnpackedFloatElement(1, 0, 1.0); - message.setUnpackedFloatIterable(1, [1.0]); - message.setPackedInt32Element(1, 0, 1); - message.setPackedInt32Iterable(1, [1]); - message.setUnpackedInt32Element(1, 0, 1); - message.setUnpackedInt32Iterable(1, [1]); - message.setPackedInt64Element(1, 0, Int64.fromBits(0, 1)); - message.setPackedInt64Iterable(1, [Int64.fromBits(0, 1)]); - message.setUnpackedInt64Element(1, 0, Int64.fromBits(0, 1)); - message.setUnpackedInt64Iterable(1, [Int64.fromBits(0, 1)]); - message.setRepeatedMessageElement(1, message, TestMessage.instanceCreator, 0); - message.setRepeatedMessageIterable(1, [message]); - message.setPackedSfixed32Element(1, 0, 1); - message.setPackedSfixed32Iterable(1, [1]); - message.setUnpackedSfixed32Element(1, 0, 1); - message.setUnpackedSfixed32Iterable(1, [1]); - message.setPackedSfixed64Element(1, 0, Int64.fromBits(0, 1)); - message.setPackedSfixed64Iterable(1, [Int64.fromBits(0, 1)]); - message.setUnpackedSfixed64Element(1, 0, Int64.fromBits(0, 1)); - message.setUnpackedSfixed64Iterable(1, [Int64.fromBits(0, 1)]); - message.setRepeatedStringElement(1, 0, ''); - message.setRepeatedStringIterable(1, ['']); - message.setPackedSint32Element(1, 0, 1); - message.setPackedSint32Iterable(1, [1]); - message.setUnpackedSint32Element(1, 0, 1); - message.setUnpackedSint32Iterable(1, [1]); - message.setPackedSint64Element(1, 0, Int64.fromBits(0, 1)); - message.setPackedSint64Iterable(1, [Int64.fromBits(0, 1)]); - message.setUnpackedSint64Element(1, 0, Int64.fromBits(0, 1)); - message.setUnpackedSint64Iterable(1, [Int64.fromBits(0, 1)]); - message.setPackedUint32Element(1, 0, 1); - message.setPackedUint32Iterable(1, [1]); - message.setUnpackedUint32Element(1, 0, 1); - message.setUnpackedUint32Iterable(1, [1]); - message.setPackedUint64Element(1, 0, Int64.fromBits(0, 1)); - message.setPackedUint64Iterable(1, [Int64.fromBits(0, 1)]); - message.setUnpackedUint64Element(1, 0, Int64.fromBits(0, 1)); - message.setUnpackedUint64Iterable(1, [Int64.fromBits(0, 1)]); - - let s = ''; - s += message.getBoolWithDefault(1); - s += message.getBytesWithDefault(1); - s += message.getDoubleWithDefault(1); - s += message.getFixed32WithDefault(1); - s += message.getFixed64WithDefault(1); - s += message.getFloatWithDefault(1); - s += message.getInt32WithDefault(1); - s += message.getInt64WithDefault(1); - s += message.getMessage(1, TestMessage.instanceCreator); - s += message.getSfixed32WithDefault(1); - s += message.getSfixed64WithDefault(1); - s += message.getSint32WithDefault(1); - s += message.getSint64WithDefault(1); - s += message.getStringWithDefault(1); - s += message.getUint32WithDefault(1); - s += message.getUint64WithDefault(1); - s += message.getRepeatedBoolElement(1, 0); - s += message.getRepeatedBoolIterable(1); - s += message.getRepeatedBoolSize(1); - s += message.getRepeatedBytesElement(1, 0); - s += message.getRepeatedBytesIterable(1); - s += message.getRepeatedBytesSize(1); - s += message.getRepeatedDoubleElement(1, 0); - s += message.getRepeatedDoubleIterable(1); - s += message.getRepeatedDoubleSize(1); - s += message.getRepeatedFixed32Element(1, 0); - s += message.getRepeatedFixed32Iterable(1); - s += message.getRepeatedFixed32Size(1); - s += message.getRepeatedFixed64Element(1, 0); - s += message.getRepeatedFixed64Iterable(1); - s += message.getRepeatedFixed64Size(1); - s += message.getRepeatedFloatElement(1, 0); - s += message.getRepeatedFloatIterable(1); - s += message.getRepeatedFloatSize(1); - s += message.getRepeatedInt32Element(1, 0); - s += message.getRepeatedInt32Iterable(1); - s += message.getRepeatedInt32Size(1); - s += message.getRepeatedInt64Element(1, 0); - s += message.getRepeatedInt64Iterable(1); - s += message.getRepeatedInt64Size(1); - s += message.getRepeatedMessageElement(1, TestMessage.instanceCreator, 0); - s += message.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - s += message.getRepeatedMessageSize(1, TestMessage.instanceCreator); - s += message.getRepeatedSfixed32Element(1, 0); - s += message.getRepeatedSfixed32Iterable(1); - s += message.getRepeatedSfixed32Size(1); - s += message.getRepeatedSfixed64Element(1, 0); - s += message.getRepeatedSfixed64Iterable(1); - s += message.getRepeatedSfixed64Size(1); - s += message.getRepeatedSint32Element(1, 0); - s += message.getRepeatedSint32Iterable(1); - s += message.getRepeatedSint32Size(1); - s += message.getRepeatedSint64Element(1, 0); - s += message.getRepeatedSint64Iterable(1); - s += message.getRepeatedSint64Size(1); - s += message.getRepeatedStringElement(1, 0); - s += message.getRepeatedStringIterable(1); - s += message.getRepeatedStringSize(1); - s += message.getRepeatedUint32Element(1, 0); - s += message.getRepeatedUint32Iterable(1); - s += message.getRepeatedUint32Size(1); - s += message.getRepeatedUint64Element(1, 0); - s += message.getRepeatedUint64Iterable(1); - s += message.getRepeatedUint64Size(1); - - s += message.serialize(); - - return s; -} - -goog.global['__hiddenTest'] += accessAllTypes(); diff --git a/js/experimental/benchmarks/code_size/kernel/popular_types.js b/js/experimental/benchmarks/code_size/kernel/popular_types.js deleted file mode 100644 index 90e1792f6..000000000 --- a/js/experimental/benchmarks/code_size/kernel/popular_types.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @fileoverview The code size benchmark of binary kernel for accessing all - * popular types setter and getter. - * - * The types are those whose usage are more than 1%: - * - * ('STRING__LABEL_OPTIONAL', '29.7214%') - * ('INT32__LABEL_OPTIONAL', '17.7277%') - * ('MESSAGE__LABEL_OPTIONAL', '15.6462%') - * ('BOOL__LABEL_OPTIONAL', '13.0038%') - * ('ENUM__LABEL_OPTIONAL', '11.4466%') - * ('INT64__LABEL_OPTIONAL', '3.2198%') - * ('DOUBLE__LABEL_OPTIONAL', '1.357%') - * ('MESSAGE__LABEL_REPEATED', '1.2775%') - * ('FIXED32__LABEL_REQUIRED', '1.2%') - * ('UINT64__LABEL_OPTIONAL', '1.1771%') - * ('STRING__LABEL_REQUIRED', '1.0785%') - * - */ -goog.module('protobuf.benchmark.KernelCodeSizeBenchmarkPopularTypes'); - -const Int64 = goog.require('protobuf.Int64'); -const Kernel = goog.require('protobuf.runtime.Kernel'); -const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); -const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase'); - -ensureCommonBaseLine(); - - -/** - * @return {string} - */ -function accessAllTypes() { - const message = new TestMessage(Kernel.createEmpty()); - - message.addRepeatedMessageElement(1, message, TestMessage.instanceCreator); - message.addRepeatedMessageIterable(1, [message], TestMessage.instanceCreator); - - message.setString(1, 'abc'); - message.setInt32(1, 1); - message.setMessage(1, message); - message.setBool(1, true); - message.setInt64(1, Int64.fromBits(0, 1)); - message.setDouble(1, 1.0); - message.setRepeatedMessageElement(1, message, TestMessage.instanceCreator, 0); - message.setRepeatedMessageIterable(1, [message]); - message.setUint64(1, Int64.fromBits(0, 1)); - - - let s = ''; - s += message.getStringWithDefault(1); - s += message.getInt32WithDefault(1); - s += message.getMessage(1, TestMessage.instanceCreator); - s += message.getMessageOrNull(1, TestMessage.instanceCreator); - s += message.getBoolWithDefault(1); - s += message.getInt64WithDefault(1); - s += message.getDoubleWithDefault(1); - s += message.getRepeatedMessageElement(1, TestMessage.instanceCreator, 0); - s += message.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - s += message.getRepeatedMessageSize(1, TestMessage.instanceCreator); - s += message.getUint64WithDefault(1); - - s += message.serialize(); - - return s; -} - -goog.global['__hiddenTest'] += accessAllTypes(); diff --git a/js/experimental/runtime/bytestring.js b/js/experimental/runtime/bytestring.js deleted file mode 100644 index d6af5f148..000000000 --- a/js/experimental/runtime/bytestring.js +++ /dev/null @@ -1,183 +0,0 @@ -/** - * @fileoverview Provides ByteString as a basic data type for protos. - */ -goog.module('protobuf.ByteString'); - -const base64 = goog.require('goog.crypt.base64'); -const {arrayBufferSlice, cloneArrayBufferView, hashUint8Array, uint8ArrayEqual} = goog.require('protobuf.binary.typedArrays'); - -/** - * Immutable sequence of bytes. - * - * Bytes can be obtained as an ArrayBuffer or a base64 encoded string. - * @final - */ -class ByteString { - /** - * @param {?Uint8Array} bytes - * @param {?string} base64 - * @private - */ - constructor(bytes, base64) { - /** @private {?Uint8Array}*/ - this.bytes_ = bytes; - /** @private {?string} */ - this.base64_ = base64; - /** @private {number} */ - this.hashCode_ = 0; - } - - /** - * Constructs a ByteString instance from a base64 string. - * @param {string} value - * @return {!ByteString} - */ - static fromBase64String(value) { - if (value == null) { - throw new Error('value must not be null'); - } - return new ByteString(/* bytes */ null, value); - } - - /** - * Constructs a ByteString from an array buffer. - * @param {!ArrayBuffer} bytes - * @param {number=} start - * @param {number=} end - * @return {!ByteString} - */ - static fromArrayBuffer(bytes, start = 0, end = undefined) { - return new ByteString( - new Uint8Array(arrayBufferSlice(bytes, start, end)), /* base64 */ null); - } - - /** - * Constructs a ByteString from any ArrayBufferView (e.g. DataView, - * TypedArray, Uint8Array, etc.). - * @param {!ArrayBufferView} bytes - * @return {!ByteString} - */ - static fromArrayBufferView(bytes) { - return new ByteString(cloneArrayBufferView(bytes), /* base64 */ null); - } - - /** - * Constructs a ByteString from an Uint8Array. DON'T MODIFY the underlying - * ArrayBuffer, since the ByteString directly uses it without making a copy. - * - * This method exists so that internal APIs can construct a ByteString without - * paying the penalty of copying an ArrayBuffer when that ArrayBuffer is not - * supposed to change. It is exposed to a limited number of internal classes - * through bytestring_internal.js. - * - * @param {!Uint8Array} bytes - * @return {!ByteString} - * @package - */ - static fromUint8ArrayUnsafe(bytes) { - return new ByteString(bytes, /* base64 */ null); - } - - /** - * Returns this ByteString as an ArrayBuffer. - * @return {!ArrayBuffer} - */ - toArrayBuffer() { - const bytes = this.ensureBytes_(); - return arrayBufferSlice( - bytes.buffer, bytes.byteOffset, bytes.byteOffset + bytes.byteLength); - } - - /** - * Returns this ByteString as an Uint8Array. DON'T MODIFY the returned array, - * since the ByteString holds the reference to the same array. - * - * This method exists so that internal APIs can get contents of a ByteString - * without paying the penalty of copying an ArrayBuffer. It is exposed to a - * limited number of internal classes through bytestring_internal.js. - * @return {!Uint8Array} - * @package - */ - toUint8ArrayUnsafe() { - return this.ensureBytes_(); - } - - /** - * Returns this ByteString as a base64 encoded string. - * @return {string} - */ - toBase64String() { - return this.ensureBase64String_(); - } - - /** - * Returns true for Bytestrings that contain identical values. - * @param {*} other - * @return {boolean} - */ - equals(other) { - if (this === other) { - return true; - } - - if (!(other instanceof ByteString)) { - return false; - } - - const otherByteString = /** @type {!ByteString} */ (other); - return uint8ArrayEqual(this.ensureBytes_(), otherByteString.ensureBytes_()); - } - - /** - * Returns a number (int32) that is suitable for using in hashed structures. - * @return {number} - */ - hashCode() { - if (this.hashCode_ == 0) { - this.hashCode_ = hashUint8Array(this.ensureBytes_()); - } - return this.hashCode_; - } - - /** - * Returns true if the bytestring is empty. - * @return {boolean} - */ - isEmpty() { - if (this.bytes_ != null && this.bytes_.byteLength == 0) { - return true; - } - if (this.base64_ != null && this.base64_.length == 0) { - return true; - } - return false; - } - - /** - * @return {!Uint8Array} - * @private - */ - ensureBytes_() { - if (this.bytes_) { - return this.bytes_; - } - return this.bytes_ = base64.decodeStringToUint8Array( - /** @type {string} */ (this.base64_)); - } - - /** - * @return {string} - * @private - */ - ensureBase64String_() { - if (this.base64_ == null) { - this.base64_ = base64.encodeByteArray(this.bytes_); - } - return this.base64_; - } -} - -/** @const {!ByteString} */ -ByteString.EMPTY = new ByteString(new Uint8Array(0), null); - -exports = ByteString; diff --git a/js/experimental/runtime/bytestring_internal.js b/js/experimental/runtime/bytestring_internal.js deleted file mode 100644 index 2ea3f609b..000000000 --- a/js/experimental/runtime/bytestring_internal.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @fileoverview Exposes internal only functions for ByteString. The - * corresponding BUILD rule restricts access to this file to only the binary - * kernel and APIs directly using the binary kernel. - */ -goog.module('protobuf.byteStringInternal'); - -const ByteString = goog.require('protobuf.ByteString'); - -/** - * Constructs a ByteString from an Uint8Array. DON'T MODIFY the underlying - * ArrayBuffer, since the ByteString directly uses it without making a copy. - * @param {!Uint8Array} bytes - * @return {!ByteString} - */ -function byteStringFromUint8ArrayUnsafe(bytes) { - return ByteString.fromUint8ArrayUnsafe(bytes); -} - -/** - * Returns this ByteString as an Uint8Array. DON'T MODIFY the returned array, - * since the ByteString holds the reference to the same array. - * @param {!ByteString} bytes - * @return {!Uint8Array} - */ -function byteStringToUint8ArrayUnsafe(bytes) { - return bytes.toUint8ArrayUnsafe(); -} - -exports = { - byteStringFromUint8ArrayUnsafe, - byteStringToUint8ArrayUnsafe, -}; diff --git a/js/experimental/runtime/bytestring_test.js b/js/experimental/runtime/bytestring_test.js deleted file mode 100644 index b9928b6e7..000000000 --- a/js/experimental/runtime/bytestring_test.js +++ /dev/null @@ -1,277 +0,0 @@ -goog.module('proto.im.integration.ByteStringFieldsTest'); -goog.setTestOnly(); - -const ByteString = goog.require('protobuf.ByteString'); -const {arrayBufferSlice} = goog.require('protobuf.binary.typedArrays'); - -const /** !ArrayBuffer */ TEST_BYTES = new Uint8Array([1, 2, 3, 4]).buffer; -const /** !ByteString */ TEST_STRING = ByteString.fromArrayBuffer(TEST_BYTES); -const /** !ArrayBuffer */ PREFIXED_TEST_BYTES = - new Uint8Array([0, 1, 2, 3, 4]).buffer; -const /** string */ HALLO_IN_BASE64 = 'aGFsbG8='; -const /** string */ HALLO_IN_BASE64_WITH_SPACES = 'a G F s b G 8='; -const /** !ArrayBufferView */ BYTES_WITH_HALLO = new Uint8Array([ - 'h'.charCodeAt(0), - 'a'.charCodeAt(0), - 'l'.charCodeAt(0), - 'l'.charCodeAt(0), - 'o'.charCodeAt(0), -]); - -describe('ByteString does', () => { - it('create bytestring from buffer', () => { - const byteString = - ByteString.fromArrayBuffer(arrayBufferSlice(TEST_BYTES, 0)); - expect(byteString.toArrayBuffer()).toEqual(TEST_BYTES); - expect(byteString.toUint8ArrayUnsafe()).toEqual(new Uint8Array(TEST_BYTES)); - }); - - it('create bytestring from ArrayBufferView', () => { - const byteString = - ByteString.fromArrayBufferView(new Uint8Array(TEST_BYTES)); - expect(byteString.toArrayBuffer()).toEqual(TEST_BYTES); - expect(byteString.toUint8ArrayUnsafe()).toEqual(new Uint8Array(TEST_BYTES)); - }); - - it('create bytestring from subarray', () => { - const byteString = ByteString.fromArrayBufferView( - new Uint8Array(TEST_BYTES, /* offset */ 1, /* length */ 2)); - const expected = new Uint8Array([2, 3]); - expect(new Uint8Array(byteString.toArrayBuffer())).toEqual(expected); - expect(byteString.toUint8ArrayUnsafe()).toEqual(expected); - }); - - it('create bytestring from Uint8Array (unsafe)', () => { - const array = new Uint8Array(TEST_BYTES); - const byteString = ByteString.fromUint8ArrayUnsafe(array); - expect(byteString.toArrayBuffer()).toEqual(array.buffer); - expect(byteString.toUint8ArrayUnsafe()).toBe(array); - }); - - it('create bytestring from base64 string', () => { - const byteString = ByteString.fromBase64String(HALLO_IN_BASE64); - expect(byteString.toBase64String()).toEqual(HALLO_IN_BASE64); - expect(byteString.toArrayBuffer()).toEqual(BYTES_WITH_HALLO.buffer); - expect(byteString.toUint8ArrayUnsafe()).toEqual(BYTES_WITH_HALLO); - }); - - it('preserve immutability if underlying buffer changes: from buffer', () => { - const buffer = new ArrayBuffer(4); - const array = new Uint8Array(buffer); - array[0] = 1; - array[1] = 2; - array[2] = 3; - array[3] = 4; - - const byteString = ByteString.fromArrayBuffer(buffer); - const otherBuffer = byteString.toArrayBuffer(); - - expect(otherBuffer).not.toBe(buffer); - expect(new Uint8Array(otherBuffer)).toEqual(array); - - // modify the original buffer - array[0] = 5; - // Are we still returning the original bytes? - expect(new Uint8Array(byteString.toArrayBuffer())).toEqual(new Uint8Array([ - 1, 2, 3, 4 - ])); - }); - - it('preserve immutability if underlying buffer changes: from ArrayBufferView', - () => { - const buffer = new ArrayBuffer(4); - const array = new Uint8Array(buffer); - array[0] = 1; - array[1] = 2; - array[2] = 3; - array[3] = 4; - - const byteString = ByteString.fromArrayBufferView(array); - const otherBuffer = byteString.toArrayBuffer(); - - expect(otherBuffer).not.toBe(buffer); - expect(new Uint8Array(otherBuffer)).toEqual(array); - - // modify the original buffer - array[0] = 5; - // Are we still returning the original bytes? - expect(new Uint8Array(byteString.toArrayBuffer())) - .toEqual(new Uint8Array([1, 2, 3, 4])); - }); - - it('mutate if underlying buffer changes: from Uint8Array (unsafe)', () => { - const buffer = new ArrayBuffer(4); - const array = new Uint8Array(buffer); - array[0] = 1; - array[1] = 2; - array[2] = 3; - array[3] = 4; - - const byteString = ByteString.fromUint8ArrayUnsafe(array); - const otherBuffer = byteString.toArrayBuffer(); - - expect(otherBuffer).not.toBe(buffer); - expect(new Uint8Array(otherBuffer)).toEqual(array); - - // modify the original buffer - array[0] = 5; - // We are no longer returning the original bytes - expect(new Uint8Array(byteString.toArrayBuffer())).toEqual(new Uint8Array([ - 5, 2, 3, 4 - ])); - }); - - it('preserve immutability for returned buffers: toArrayBuffer', () => { - const byteString = ByteString.fromArrayBufferView(new Uint8Array(4)); - const buffer1 = byteString.toArrayBuffer(); - const buffer2 = byteString.toArrayBuffer(); - - expect(buffer1).toEqual(buffer2); - - const array1 = new Uint8Array(buffer1); - array1[0] = 1; - - expect(buffer1).not.toEqual(buffer2); - }); - - it('does not preserve immutability for returned buffers: toUint8ArrayUnsafe', - () => { - const byteString = ByteString.fromUint8ArrayUnsafe(new Uint8Array(4)); - const array1 = byteString.toUint8ArrayUnsafe(); - const array2 = byteString.toUint8ArrayUnsafe(); - - expect(array1).toEqual(array2); - array1[0] = 1; - - expect(array1).toEqual(array2); - }); - - it('throws when created with null ArrayBufferView', () => { - expect( - () => ByteString.fromArrayBufferView( - /** @type {!ArrayBufferView} */ (/** @type{*} */ (null)))) - .toThrow(); - }); - - it('throws when created with null buffer', () => { - expect( - () => ByteString.fromBase64String( - /** @type {string} */ (/** @type{*} */ (null)))) - .toThrow(); - }); - - it('convert base64 to ArrayBuffer', () => { - const other = ByteString.fromBase64String(HALLO_IN_BASE64); - expect(BYTES_WITH_HALLO).toEqual(new Uint8Array(other.toArrayBuffer())); - }); - - it('convert base64 with spaces to ArrayBuffer', () => { - const other = ByteString.fromBase64String(HALLO_IN_BASE64_WITH_SPACES); - expect(new Uint8Array(other.toArrayBuffer())).toEqual(BYTES_WITH_HALLO); - }); - - it('convert bytes to base64', () => { - const other = ByteString.fromArrayBufferView(BYTES_WITH_HALLO); - expect(HALLO_IN_BASE64).toEqual(other.toBase64String()); - }); - - it('equal empty bytetring', () => { - const empty = ByteString.fromArrayBuffer(new ArrayBuffer(0)); - expect(ByteString.EMPTY.equals(empty)).toEqual(true); - }); - - it('equal empty bytestring constructed from ArrayBufferView', () => { - const empty = ByteString.fromArrayBufferView(new Uint8Array(0)); - expect(ByteString.EMPTY.equals(empty)).toEqual(true); - }); - - it('equal empty bytestring constructed from Uint8Array (unsafe)', () => { - const empty = ByteString.fromUint8ArrayUnsafe(new Uint8Array(0)); - expect(ByteString.EMPTY.equals(empty)).toEqual(true); - }); - - it('equal empty bytestring constructed from base64', () => { - const empty = ByteString.fromBase64String(''); - expect(ByteString.EMPTY.equals(empty)).toEqual(true); - }); - - it('equal other instance', () => { - const other = ByteString.fromArrayBuffer(arrayBufferSlice(TEST_BYTES, 0)); - expect(TEST_STRING.equals(other)).toEqual(true); - }); - - it('not equal different instance', () => { - const other = - ByteString.fromArrayBuffer(new Uint8Array([1, 2, 3, 4, 5]).buffer); - expect(TEST_STRING.equals(other)).toEqual(false); - }); - - it('equal other instance constructed from ArrayBufferView', () => { - const other = - ByteString.fromArrayBufferView(new Uint8Array(PREFIXED_TEST_BYTES, 1)); - expect(TEST_STRING.equals(other)).toEqual(true); - }); - - it('not equal different instance constructed from ArrayBufferView', () => { - const other = - ByteString.fromArrayBufferView(new Uint8Array([1, 2, 3, 4, 5])); - expect(TEST_STRING.equals(other)).toEqual(false); - }); - - it('equal other instance constructed from Uint8Array (unsafe)', () => { - const other = - ByteString.fromUint8ArrayUnsafe(new Uint8Array(PREFIXED_TEST_BYTES, 1)); - expect(TEST_STRING.equals(other)).toEqual(true); - }); - - it('not equal different instance constructed from Uint8Array (unsafe)', - () => { - const other = - ByteString.fromUint8ArrayUnsafe(new Uint8Array([1, 2, 3, 4, 5])); - expect(TEST_STRING.equals(other)).toEqual(false); - }); - - it('have same hashcode for empty bytes', () => { - const empty = ByteString.fromArrayBuffer(new ArrayBuffer(0)); - expect(ByteString.EMPTY.hashCode()).toEqual(empty.hashCode()); - }); - - it('have same hashcode for test bytes', () => { - const other = ByteString.fromArrayBuffer(arrayBufferSlice(TEST_BYTES, 0)); - expect(TEST_STRING.hashCode()).toEqual(other.hashCode()); - }); - - it('have same hashcode for test bytes', () => { - const other = ByteString.fromArrayBufferView( - new Uint8Array(arrayBufferSlice(TEST_BYTES, 0))); - expect(TEST_STRING.hashCode()).toEqual(other.hashCode()); - }); - - it('have same hashcode for different instance constructed with base64', - () => { - const other = ByteString.fromBase64String(HALLO_IN_BASE64); - expect(ByteString.fromArrayBufferView(BYTES_WITH_HALLO).hashCode()) - .toEqual(other.hashCode()); - }); - - it('preserves the length of a Uint8Array', () => { - const original = new Uint8Array([105, 183, 51, 251, 253, 118, 247]); - const afterByteString = new Uint8Array( - ByteString.fromArrayBufferView(original).toArrayBuffer()); - expect(afterByteString).toEqual(original); - }); - - it('preserves the length of a base64 value', () => { - const expected = new Uint8Array([105, 183, 51, 251, 253, 118, 247]); - const afterByteString = new Uint8Array( - ByteString.fromBase64String('abcz+/129w').toArrayBuffer()); - expect(afterByteString).toEqual(expected); - }); - - it('preserves the length of a base64 value with padding', () => { - const expected = new Uint8Array([105, 183, 51, 251, 253, 118, 247]); - const afterByteString = new Uint8Array( - ByteString.fromBase64String('abcz+/129w==').toArrayBuffer()); - expect(afterByteString).toEqual(expected); - }); -}); diff --git a/js/experimental/runtime/int64.js b/js/experimental/runtime/int64.js deleted file mode 100644 index 45585b752..000000000 --- a/js/experimental/runtime/int64.js +++ /dev/null @@ -1,403 +0,0 @@ -/** - * @fileoverview Protobufs Int64 representation. - */ -goog.module('protobuf.Int64'); - -const Long = goog.require('goog.math.Long'); -const {assert} = goog.require('goog.asserts'); - -/** - * A container for protobufs Int64/Uint64 data type. - * @final - */ -class Int64 { - /** @return {!Int64} */ - static getZero() { - return ZERO; - } - - /** @return {!Int64} */ - static getMinValue() { - return MIN_VALUE; - } - - /** @return {!Int64} */ - static getMaxValue() { - return MAX_VALUE; - } - - /** - * Constructs a Int64 given two 32 bit numbers - * @param {number} lowBits - * @param {number} highBits - * @return {!Int64} - */ - static fromBits(lowBits, highBits) { - return new Int64(lowBits, highBits); - } - - /** - * Constructs an Int64 from a signed 32 bit number. - * @param {number} value - * @return {!Int64} - */ - static fromInt(value) { - // TODO: Use our own checking system here. - assert(value === (value | 0), 'value should be a 32-bit integer'); - // Right shift 31 bits so all high bits are equal to the sign bit. - // Note: cannot use >> 32, because (1 >> 32) = 1 (!). - const signExtendedHighBits = value >> 31; - return new Int64(value, signExtendedHighBits); - } - - /** - * Constructs an Int64 from a number (over 32 bits). - * @param {number} value - * @return {!Int64} - */ - static fromNumber(value) { - if (value > 0) { - return new Int64(value, value / TWO_PWR_32_DBL); - } else if (value < 0) { - return negate(-value, -value / TWO_PWR_32_DBL); - } - return ZERO; - } - - /** - * Construct an Int64 from a signed decimal string. - * @param {string} value - * @return {!Int64} - */ - static fromDecimalString(value) { - // TODO: Use our own checking system here. - assert(value.length > 0); - // The basic Number conversion loses precision, but we can use it for - // a quick validation that the format is correct and it is an integer. - assert(Math.floor(Number(value)).toString().length == value.length); - return decimalStringToInt64(value); - } - - /** - * Construct an Int64 from a signed hexadecimal string. - * @param {string} value - * @return {!Int64} - */ - static fromHexString(value) { - // TODO: Use our own checking system here. - assert(value.length > 0); - assert(value.slice(0, 2) == '0x' || value.slice(0, 3) == '-0x'); - const minus = value[0] === '-'; - // Strip the 0x or -0x prefix. - value = value.slice(minus ? 3 : 2); - const lowBits = parseInt(value.slice(-8), 16); - const highBits = parseInt(value.slice(-16, -8) || '', 16); - return (minus ? negate : Int64.fromBits)(lowBits, highBits); - } - - // Note to the reader: - // goog.math.Long suffers from a code size issue. JsCompiler almost always - // considers toString methods to be alive in a program. So if you are - // constructing a Long instance the toString method is assumed to be live. - // Unfortunately Long's toString method makes a large chunk of code alive - // of the entire class adding 1.3kB (gzip) of extra code size. - // Callers that are sensitive to code size and are not using Long already - // should avoid calling this method. - /** - * Creates an Int64 instance from a Long value. - * @param {!Long} value - * @return {!Int64} - */ - static fromLong(value) { - return new Int64(value.getLowBits(), value.getHighBits()); - } - - /** - * @param {number} lowBits - * @param {number} highBits - * @private - */ - constructor(lowBits, highBits) { - /** @const @private {number} */ - this.lowBits_ = lowBits | 0; - /** @const @private {number} */ - this.highBits_ = highBits | 0; - } - - /** - * Returns the int64 value as a JavaScript number. This will lose precision - * if the number is outside of the safe range for JavaScript of 53 bits - * precision. - * @return {number} - */ - asNumber() { - const result = this.highBits_ * TWO_PWR_32_DBL + this.getLowBitsUnsigned(); - // TODO: Use our own checking system here. - assert( - Number.isSafeInteger(result), 'conversion to number loses precision.'); - return result; - } - - // Note to the reader: - // goog.math.Long suffers from a code size issue. JsCompiler almost always - // considers toString methods to be alive in a program. So if you are - // constructing a Long instance the toString method is assumed to be live. - // Unfortunately Long's toString method makes a large chunk of code alive - // of the entire class adding 1.3kB (gzip) of extra code size. - // Callers that are sensitive to code size and are not using Long already - // should avoid calling this method. - /** @return {!Long} */ - asLong() { - return Long.fromBits(this.lowBits_, this.highBits_); - } - - /** @return {number} Signed 32-bit integer value. */ - getLowBits() { - return this.lowBits_; - } - - /** @return {number} Signed 32-bit integer value. */ - getHighBits() { - return this.highBits_; - } - - /** @return {number} Unsigned 32-bit integer. */ - getLowBitsUnsigned() { - return this.lowBits_ >>> 0; - } - - /** @return {number} Unsigned 32-bit integer. */ - getHighBitsUnsigned() { - return this.highBits_ >>> 0; - } - - /** @return {string} */ - toSignedDecimalString() { - return joinSignedDecimalString(this); - } - - /** @return {string} */ - toUnsignedDecimalString() { - return joinUnsignedDecimalString(this); - } - - /** - * Returns an unsigned hexadecimal string representation of the Int64. - * @return {string} - */ - toHexString() { - let nibbles = new Array(16); - let lowBits = this.lowBits_; - let highBits = this.highBits_; - for (let highIndex = 7, lowIndex = 15; lowIndex > 7; - highIndex--, lowIndex--) { - nibbles[highIndex] = HEX_DIGITS[highBits & 0xF]; - nibbles[lowIndex] = HEX_DIGITS[lowBits & 0xF]; - highBits = highBits >>> 4; - lowBits = lowBits >>> 4; - } - // Always leave the least significant hex digit. - while (nibbles.length > 1 && nibbles[0] == '0') { - nibbles.shift(); - } - return `0x${nibbles.join('')}`; - } - - /** - * @param {*} other object to compare against. - * @return {boolean} Whether this Int64 equals the other. - */ - equals(other) { - if (this === other) { - return true; - } - if (!(other instanceof Int64)) { - return false; - } - // Compare low parts first as there is higher chance they are different. - const otherInt64 = /** @type{!Int64} */ (other); - return (this.lowBits_ === otherInt64.lowBits_) && - (this.highBits_ === otherInt64.highBits_); - } - - /** - * Returns a number (int32) that is suitable for using in hashed structures. - * @return {number} - */ - hashCode() { - return (31 * this.lowBits_ + 17 * this.highBits_) | 0; - } -} - -/** - * Losslessly converts a 64-bit unsigned integer in 32:32 split representation - * into a decimal string. - * @param {!Int64} int64 - * @return {string} The binary number represented as a string. - */ -const joinUnsignedDecimalString = (int64) => { - const lowBits = int64.getLowBitsUnsigned(); - const highBits = int64.getHighBitsUnsigned(); - // Skip the expensive conversion if the number is small enough to use the - // built-in conversions. - // Number.MAX_SAFE_INTEGER = 0x001FFFFF FFFFFFFF, thus any number with - // highBits <= 0x1FFFFF can be safely expressed with a double and retain - // integer precision. - // Proven by: Number.isSafeInteger(0x1FFFFF * 2**32 + 0xFFFFFFFF) == true. - if (highBits <= 0x1FFFFF) { - return String(TWO_PWR_32_DBL * highBits + lowBits); - } - - // What this code is doing is essentially converting the input number from - // base-2 to base-1e7, which allows us to represent the 64-bit range with - // only 3 (very large) digits. Those digits are then trivial to convert to - // a base-10 string. - - // The magic numbers used here are - - // 2^24 = 16777216 = (1,6777216) in base-1e7. - // 2^48 = 281474976710656 = (2,8147497,6710656) in base-1e7. - - // Split 32:32 representation into 16:24:24 representation so our - // intermediate digits don't overflow. - const low = lowBits & LOW_24_BITS; - const mid = ((lowBits >>> 24) | (highBits << 8)) & LOW_24_BITS; - const high = (highBits >> 16) & LOW_16_BITS; - - // Assemble our three base-1e7 digits, ignoring carries. The maximum - // value in a digit at this step is representable as a 48-bit integer, which - // can be stored in a 64-bit floating point number. - let digitA = low + (mid * 6777216) + (high * 6710656); - let digitB = mid + (high * 8147497); - let digitC = (high * 2); - - // Apply carries from A to B and from B to C. - const base = 10000000; - if (digitA >= base) { - digitB += Math.floor(digitA / base); - digitA %= base; - } - - if (digitB >= base) { - digitC += Math.floor(digitB / base); - digitB %= base; - } - - // If digitC is 0, then we should have returned in the trivial code path - // at the top for non-safe integers. Given this, we can assume both digitB - // and digitA need leading zeros. - // TODO: Use our own checking system here. - assert(digitC); - return digitC + decimalFrom1e7WithLeadingZeros(digitB) + - decimalFrom1e7WithLeadingZeros(digitA); -}; - -/** - * @param {number} digit1e7 Number < 1e7 - * @return {string} Decimal representation of digit1e7 with leading zeros. - */ -const decimalFrom1e7WithLeadingZeros = (digit1e7) => { - const partial = String(digit1e7); - return '0000000'.slice(partial.length) + partial; -}; - -/** - * Losslessly converts a 64-bit signed integer in 32:32 split representation - * into a decimal string. - * @param {!Int64} int64 - * @return {string} The binary number represented as a string. - */ -const joinSignedDecimalString = (int64) => { - // If we're treating the input as a signed value and the high bit is set, do - // a manual two's complement conversion before the decimal conversion. - const negative = (int64.getHighBits() & 0x80000000); - if (negative) { - int64 = negate(int64.getLowBits(), int64.getHighBits()); - } - - const result = joinUnsignedDecimalString(int64); - return negative ? '-' + result : result; -}; - -/** - * @param {string} dec - * @return {!Int64} - */ -const decimalStringToInt64 = (dec) => { - // Check for minus sign. - const minus = dec[0] === '-'; - if (minus) { - dec = dec.slice(1); - } - - // Work 6 decimal digits at a time, acting like we're converting base 1e6 - // digits to binary. This is safe to do with floating point math because - // Number.isSafeInteger(ALL_32_BITS * 1e6) == true. - const base = 1e6; - let lowBits = 0; - let highBits = 0; - function add1e6digit(begin, end = undefined) { - // Note: Number('') is 0. - const digit1e6 = Number(dec.slice(begin, end)); - highBits *= base; - lowBits = lowBits * base + digit1e6; - // Carry bits from lowBits to - if (lowBits >= TWO_PWR_32_DBL) { - highBits = highBits + ((lowBits / TWO_PWR_32_DBL) | 0); - lowBits = lowBits % TWO_PWR_32_DBL; - } - } - add1e6digit(-24, -18); - add1e6digit(-18, -12); - add1e6digit(-12, -6); - add1e6digit(-6); - - return (minus ? negate : Int64.fromBits)(lowBits, highBits); -}; - -/** - * @param {number} lowBits - * @param {number} highBits - * @return {!Int64} Two's compliment negation of input. - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers - */ -const negate = (lowBits, highBits) => { - highBits = ~highBits; - if (lowBits) { - lowBits = ~lowBits + 1; - } else { - // If lowBits is 0, then bitwise-not is 0xFFFFFFFF, - // adding 1 to that, results in 0x100000000, which leaves - // the low bits 0x0 and simply adds one to the high bits. - highBits += 1; - } - return Int64.fromBits(lowBits, highBits); -}; - -/** @const {!Int64} */ -const ZERO = new Int64(0, 0); - -/** @const @private {number} */ -const LOW_16_BITS = 0xFFFF; - -/** @const @private {number} */ -const LOW_24_BITS = 0xFFFFFF; - -/** @const @private {number} */ -const LOW_31_BITS = 0x7FFFFFFF; - -/** @const @private {number} */ -const ALL_32_BITS = 0xFFFFFFFF; - -/** @const {!Int64} */ -const MAX_VALUE = Int64.fromBits(ALL_32_BITS, LOW_31_BITS); - -/** @const {!Int64} */ -const MIN_VALUE = Int64.fromBits(0, 0x80000000); - -/** @const {number} */ -const TWO_PWR_32_DBL = 0x100000000; - -/** @const {string} */ -const HEX_DIGITS = '0123456789abcdef'; - -exports = Int64; diff --git a/js/experimental/runtime/int64_test.js b/js/experimental/runtime/int64_test.js deleted file mode 100644 index 76af14eab..000000000 --- a/js/experimental/runtime/int64_test.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @fileoverview Tests for Int64. - */ -goog.module('protobuf.Int64Test'); -goog.setTestOnly(); - -const Int64 = goog.require('protobuf.Int64'); -const Long = goog.require('goog.math.Long'); - -describe('Int64', () => { - it('can be constructed from bits', () => { - const int64 = Int64.fromBits(0, 1); - expect(int64.getLowBits()).toEqual(0); - expect(int64.getHighBits()).toEqual(1); - }); - - it('zero is defined', () => { - const int64 = Int64.getZero(); - expect(int64.getLowBits()).toEqual(0); - expect(int64.getHighBits()).toEqual(0); - }); - - it('max value is defined', () => { - const int64 = Int64.getMaxValue(); - expect(int64).toEqual(Int64.fromBits(0xFFFFFFFF, 0x7FFFFFFF)); - expect(int64.asLong()).toEqual(Long.getMaxValue()); - }); - - it('min value is defined', () => { - const int64 = Int64.getMinValue(); - expect(int64).toEqual(Int64.fromBits(0, 0x80000000)); - expect(int64.asLong()).toEqual(Long.getMinValue()); - }); - - it('Can be converted to long', () => { - const int64 = Int64.fromInt(1); - expect(int64.asLong()).toEqual(Long.fromInt(1)); - }); - - it('Negative value can be converted to long', () => { - const int64 = Int64.fromInt(-1); - expect(int64.getLowBits()).toEqual(0xFFFFFFFF | 0); - expect(int64.getHighBits()).toEqual(0xFFFFFFFF | 0); - expect(int64.asLong()).toEqual(Long.fromInt(-1)); - }); - - it('Can be converted to number', () => { - const int64 = Int64.fromInt(1); - expect(int64.asNumber()).toEqual(1); - }); - - it('Can convert negative value to number', () => { - const int64 = Int64.fromInt(-1); - expect(int64.asNumber()).toEqual(-1); - }); - - it('MAX_SAFE_INTEGER can be used.', () => { - const int64 = Int64.fromNumber(Number.MAX_SAFE_INTEGER); - expect(int64.getLowBitsUnsigned()).toEqual(0xFFFFFFFF); - expect(int64.getHighBits()).toEqual(0x1FFFFF); - expect(int64.asNumber()).toEqual(Number.MAX_SAFE_INTEGER); - }); - - it('MIN_SAFE_INTEGER can be used.', () => { - const int64 = Int64.fromNumber(Number.MIN_SAFE_INTEGER); - expect(int64.asNumber()).toEqual(Number.MIN_SAFE_INTEGER); - }); - - it('constructs fromInt', () => { - const int64 = Int64.fromInt(1); - expect(int64.getLowBits()).toEqual(1); - expect(int64.getHighBits()).toEqual(0); - }); - - it('constructs fromLong', () => { - const int64 = Int64.fromLong(Long.fromInt(1)); - expect(int64.getLowBits()).toEqual(1); - expect(int64.getHighBits()).toEqual(0); - }); - - // TODO: Use our own checking system here. - if (goog.DEBUG) { - it('asNumber throws for MAX_SAFE_INTEGER + 1', () => { - expect(() => Int64.fromNumber(Number.MAX_SAFE_INTEGER + 1).asNumber()) - .toThrow(); - }); - - it('fromInt(MAX_SAFE_INTEGER) throws', () => { - expect(() => Int64.fromInt(Number.MAX_SAFE_INTEGER)).toThrow(); - }); - - it('fromInt(1.5) throws', () => { - expect(() => Int64.fromInt(1.5)).toThrow(); - }); - } - - const decimalHexPairs = { - '0x0000000000000000': {signed: '0'}, - '0x0000000000000001': {signed: '1'}, - '0x00000000ffffffff': {signed: '4294967295'}, - '0x0000000100000000': {signed: '4294967296'}, - '0xffffffffffffffff': {signed: '-1', unsigned: '18446744073709551615'}, - '0x8000000000000000': - {signed: '-9223372036854775808', unsigned: '9223372036854775808'}, - '0x8000000080000000': - {signed: '-9223372034707292160', unsigned: '9223372039002259456'}, - '0x01b69b4bacd05f15': {signed: '123456789123456789'}, - '0xfe4964b4532fa0eb': - {signed: '-123456789123456789', unsigned: '18323287284586094827'}, - '0xa5a5a5a5a5a5a5a5': - {signed: '-6510615555426900571', unsigned: '11936128518282651045'}, - '0x5a5a5a5a5a5a5a5a': {signed: '6510615555426900570'}, - '0xffffffff00000000': - {signed: '-4294967296', unsigned: '18446744069414584320'}, - }; - - it('serializes to signed decimal strings', () => { - for (const [hex, decimals] of Object.entries(decimalHexPairs)) { - const int64 = hexToInt64(hex); - expect(int64.toSignedDecimalString()).toEqual(decimals.signed); - } - }); - - it('serializes to unsigned decimal strings', () => { - for (const [hex, decimals] of Object.entries(decimalHexPairs)) { - const int64 = hexToInt64(hex); - expect(int64.toUnsignedDecimalString()) - .toEqual(decimals.unsigned || decimals.signed); - } - }); - - it('serializes to unsigned hex strings', () => { - for (const [hex, decimals] of Object.entries(decimalHexPairs)) { - const int64 = hexToInt64(hex); - let shortHex = hex.replace(/0x0*/, '0x'); - if (shortHex == '0x') { - shortHex = '0x0'; - } - expect(int64.toHexString()).toEqual(shortHex); - } - }); - - it('parses decimal strings', () => { - for (const [hex, decimals] of Object.entries(decimalHexPairs)) { - const signed = Int64.fromDecimalString(decimals.signed); - expect(int64ToHex(signed)).toEqual(hex); - if (decimals.unsigned) { - const unsigned = Int64.fromDecimalString(decimals.unsigned); - expect(int64ToHex(unsigned)).toEqual(hex); - } - } - }); - - it('parses hex strings', () => { - for (const [hex, decimals] of Object.entries(decimalHexPairs)) { - expect(int64ToHex(Int64.fromHexString(hex))).toEqual(hex); - } - expect(int64ToHex(Int64.fromHexString('-0x1'))) - .toEqual('0xffffffffffffffff'); - }); - - // TODO: Use our own checking system here. - if (goog.DEBUG) { - it('throws when parsing empty string', () => { - expect(() => Int64.fromDecimalString('')).toThrow(); - }); - - it('throws when parsing float string', () => { - expect(() => Int64.fromDecimalString('1.5')).toThrow(); - }); - - it('throws when parsing non-numeric string', () => { - expect(() => Int64.fromDecimalString('0xa')).toThrow(); - }); - } - - it('checks if equal', () => { - const low = Int64.fromInt(1); - const high = Int64.getMaxValue(); - expect(low.equals(Int64.fromInt(1))).toEqual(true); - expect(low.equals(high)).toEqual(false); - expect(high.equals(Int64.getMaxValue())).toEqual(true); - }); - - it('returns unique hashcode', () => { - expect(Int64.fromInt(1).hashCode()).toEqual(Int64.fromInt(1).hashCode()); - expect(Int64.fromInt(1).hashCode()) - .not.toEqual(Int64.fromInt(2).hashCode()); - }); -}); - -/** - * @param {string} hexString - * @return {!Int64} - */ -function hexToInt64(hexString) { - const high = hexString.slice(2, 10); - const low = hexString.slice(10); - return Int64.fromBits(parseInt(low, 16), parseInt(high, 16)); -} - -/** - * @param {!Int64} int64 - * @return {string} - */ -function int64ToHex(int64) { - const ZEROS_32_BIT = '00000000'; - const highPartialHex = int64.getHighBitsUnsigned().toString(16); - const lowPartialHex = int64.getLowBitsUnsigned().toString(16); - const highHex = ZEROS_32_BIT.slice(highPartialHex.length) + highPartialHex; - const lowHex = ZEROS_32_BIT.slice(lowPartialHex.length) + lowPartialHex; - return `0x${highHex}${lowHex}`; -} diff --git a/js/experimental/runtime/internal/checks.js b/js/experimental/runtime/internal/checks.js deleted file mode 100644 index 3d1af548f..000000000 --- a/js/experimental/runtime/internal/checks.js +++ /dev/null @@ -1,708 +0,0 @@ -/** - * @fileoverview Proto internal runtime checks. - * - * Checks are grouped into different severity, see: - * http://g3doc/third_party/protobuf/javascript/README.md#configurable-check-support-in-protocol-buffers - * - * Checks are also grouped into different sections: - * - CHECK_BOUNDS: - * Checks that ensure that indexed access is within bounds - * (e.g. an array being accessed past its size). - * - CHECK_STATE - * Checks related to the state of an object - * (e.g. a parser hitting an invalid case). - * - CHECK_TYPE: - * Checks that relate to type errors (e.g. code receives a number instead - * of a string). - */ -goog.module('protobuf.internal.checks'); - -const ByteString = goog.require('protobuf.ByteString'); -const Int64 = goog.require('protobuf.Int64'); -const WireType = goog.require('protobuf.binary.WireType'); - -// -// See -// http://g3doc/third_party/protobuf/javascript/README.md#configurable-check-support-in-protocol-buffers -// -/** @define{string} */ -const CHECK_LEVEL_DEFINE = goog.define('protobuf.defines.CHECK_LEVEL', ''); - -/** @define{boolean} */ -const POLYFILL_TEXT_ENCODING = - goog.define('protobuf.defines.POLYFILL_TEXT_ENCODING', true); - -/** - * @const {number} - */ -const MAX_FIELD_NUMBER = Math.pow(2, 29) - 1; - -/** - * The largest finite float32 value. - * @const {number} - */ -const FLOAT32_MAX = 3.4028234663852886e+38; - -/** @enum {number} */ -const CheckLevel = { - DEBUG: 0, - CRITICAL: 1, - OFF: 2 -}; - - -/** @return {!CheckLevel} */ -function calculateCheckLevel() { - const definedLevel = CHECK_LEVEL_DEFINE.toUpperCase(); - if (definedLevel === '') { - // user did not set a value, value now just depends on goog.DEBUG - return goog.DEBUG ? CheckLevel.DEBUG : CheckLevel.CRITICAL; - } - - if (definedLevel === 'CRITICAL') { - return CheckLevel.CRITICAL; - } - - if (definedLevel === 'OFF') { - return CheckLevel.OFF; - } - - if (definedLevel === 'DEBUG') { - return CheckLevel.DEBUG; - } - - throw new Error(`Unknown value for CHECK_LEVEL: ${CHECK_LEVEL_DEFINE}`); -} - -const /** !CheckLevel */ CHECK_LEVEL = calculateCheckLevel(); - -const /** boolean */ CHECK_STATE = CHECK_LEVEL === CheckLevel.DEBUG; - -const /** boolean */ CHECK_CRITICAL_STATE = - CHECK_LEVEL === CheckLevel.CRITICAL || CHECK_LEVEL === CheckLevel.DEBUG; - -const /** boolean */ CHECK_BOUNDS = CHECK_LEVEL === CheckLevel.DEBUG; - -const /** boolean */ CHECK_CRITICAL_BOUNDS = - CHECK_LEVEL === CheckLevel.CRITICAL || CHECK_LEVEL === CheckLevel.DEBUG; - -const /** boolean */ CHECK_TYPE = CHECK_LEVEL === CheckLevel.DEBUG; - -const /** boolean */ CHECK_CRITICAL_TYPE = - CHECK_LEVEL === CheckLevel.CRITICAL || CHECK_LEVEL === CheckLevel.DEBUG; - -/** - * Ensures the truth of an expression involving the state of the calling - * instance, but not involving any parameters to the calling method. - * - * For cases where failing fast is pretty important and not failing early could - * cause bugs that are much harder to debug. - * @param {boolean} state - * @param {string=} message - * @throws {!Error} If the state is false and the check state is critical. - */ -function checkCriticalState(state, message = '') { - if (!CHECK_CRITICAL_STATE) { - return; - } - if (!state) { - throw new Error(message); - } -} - -/** - * Ensures the truth of an expression involving the state of the calling - * instance, but not involving any parameters to the calling method. - * - * @param {boolean} state - * @param {string=} message - * @throws {!Error} If the state is false and the check state is debug. - */ -function checkState(state, message = '') { - if (!CHECK_STATE) { - return; - } - checkCriticalState(state, message); -} - -/** - * Ensures that `index` specifies a valid position in an indexable object of - * size `size`. A position index may range from zero to size, inclusive. - * @param {number} index - * @param {number} size - * @throws {!Error} If the index is out of range and the check state is debug. - */ -function checkPositionIndex(index, size) { - if (!CHECK_BOUNDS) { - return; - } - checkCriticalPositionIndex(index, size); -} - -/** - * Ensures that `index` specifies a valid position in an indexable object of - * size `size`. A position index may range from zero to size, inclusive. - * @param {number} index - * @param {number} size - * @throws {!Error} If the index is out of range and the check state is - * critical. - */ -function checkCriticalPositionIndex(index, size) { - if (!CHECK_CRITICAL_BOUNDS) { - return; - } - if (index < 0 || index > size) { - throw new Error(`Index out of bounds: index: ${index} size: ${size}`); - } -} - -/** - * Ensures that `index` specifies a valid element in an indexable object of - * size `size`. A element index may range from zero to size, exclusive. - * @param {number} index - * @param {number} size - * @throws {!Error} If the index is out of range and the check state is - * debug. - */ -function checkElementIndex(index, size) { - if (!CHECK_BOUNDS) { - return; - } - checkCriticalElementIndex(index, size); -} - -/** - * Ensures that `index` specifies a valid element in an indexable object of - * size `size`. A element index may range from zero to size, exclusive. - * @param {number} index - * @param {number} size - * @throws {!Error} If the index is out of range and the check state is - * critical. - */ -function checkCriticalElementIndex(index, size) { - if (!CHECK_CRITICAL_BOUNDS) { - return; - } - if (index < 0 || index >= size) { - throw new Error(`Index out of bounds: index: ${index} size: ${size}`); - } -} - -/** - * Ensures the range of [start, end) is with the range of [0, size). - * @param {number} start - * @param {number} end - * @param {number} size - * @throws {!Error} If start and end are out of range and the check state is - * debug. - */ -function checkRange(start, end, size) { - if (!CHECK_BOUNDS) { - return; - } - checkCriticalRange(start, end, size); -} - -/** - * Ensures the range of [start, end) is with the range of [0, size). - * @param {number} start - * @param {number} end - * @param {number} size - * @throws {!Error} If start and end are out of range and the check state is - * critical. - */ -function checkCriticalRange(start, end, size) { - if (!CHECK_CRITICAL_BOUNDS) { - return; - } - if (start < 0 || end < 0 || start > size || end > size) { - throw new Error(`Range error: start: ${start} end: ${end} size: ${size}`); - } - if (start > end) { - throw new Error(`Start > end: ${start} > ${end}`); - } -} - -/** - * Ensures that field number is an integer and within the range of - * [1, MAX_FIELD_NUMBER]. - * @param {number} fieldNumber - * @throws {!Error} If the field number is out of range and the check state is - * debug. - */ -function checkFieldNumber(fieldNumber) { - if (!CHECK_TYPE) { - return; - } - checkCriticalFieldNumber(fieldNumber); -} - -/** - * Ensures that the value is neither null nor undefined. - * - * @param {T} value - * @return {R} - * - * @template T - * @template R := - * mapunion(T, (V) => - * cond(eq(V, 'null'), - * none(), - * cond(eq(V, 'undefined'), - * none(), - * V))) - * =: - */ -function checkDefAndNotNull(value) { - if (CHECK_TYPE) { - // Note that undefined == null. - if (value == null) { - throw new Error(`Value can't be null`); - } - } - return value; -} - -/** - * Ensures that the value exists and is a function. - * - * @param {function(?): ?} func - */ -function checkFunctionExists(func) { - if (CHECK_TYPE) { - if (typeof func !== 'function') { - throw new Error(`${func} is not a function`); - } - } -} - -/** - * Ensures that field number is an integer and within the range of - * [1, MAX_FIELD_NUMBER]. - * @param {number} fieldNumber - * @throws {!Error} If the field number is out of range and the check state is - * critical. - */ -function checkCriticalFieldNumber(fieldNumber) { - if (!CHECK_CRITICAL_TYPE) { - return; - } - if (fieldNumber <= 0 || fieldNumber > MAX_FIELD_NUMBER) { - throw new Error(`Field number is out of range: ${fieldNumber}`); - } -} - -/** - * Ensures that wire type is valid. - * @param {!WireType} wireType - * @throws {!Error} If the wire type is invalid and the check state is debug. - */ -function checkWireType(wireType) { - if (!CHECK_TYPE) { - return; - } - checkCriticalWireType(wireType); -} - -/** - * Ensures that wire type is valid. - * @param {!WireType} wireType - * @throws {!Error} If the wire type is invalid and the check state is critical. - */ -function checkCriticalWireType(wireType) { - if (!CHECK_CRITICAL_TYPE) { - return; - } - if (wireType < WireType.VARINT || wireType > WireType.FIXED32) { - throw new Error(`Invalid wire type: ${wireType}`); - } -} - -/** - * Ensures the given value has the correct type. - * @param {boolean} expression - * @param {string} errorMsg - * @throws {!Error} If the value has the wrong type and the check state is - * critical. - */ -function checkCriticalType(expression, errorMsg) { - if (!CHECK_CRITICAL_TYPE) { - return; - } - if (!expression) { - throw new Error(errorMsg); - } -} - -/** - * Checks whether a given object is an array. - * @param {*} value - * @return {!Array<*>} - */ -function checkCriticalTypeArray(value) { - checkCriticalType( - Array.isArray(value), `Must be an array, but got: ${value}`); - return /** @type {!Array<*>} */ (value); -} - -/** - * Checks whether a given object is an iterable. - * @param {*} value - * @return {!Iterable<*>} - */ -function checkCriticalTypeIterable(value) { - checkCriticalType( - !!value[Symbol.iterator], `Must be an iterable, but got: ${value}`); - return /** @type {!Iterable<*>} */ (value); -} - -/** - * Checks whether a given object is a boolean. - * @param {*} value - */ -function checkCriticalTypeBool(value) { - checkCriticalType( - typeof value === 'boolean', `Must be a boolean, but got: ${value}`); -} - -/** - * Checks whether a given object is an array of boolean. - * @param {*} values - */ -function checkCriticalTypeBoolArray(values) { - // TODO(b/134765672) - if (!CHECK_CRITICAL_TYPE) { - return; - } - const array = checkCriticalTypeArray(values); - for (const value of array) { - checkCriticalTypeBool(value); - } -} - -/** - * Checks whether a given object is a ByteString. - * @param {*} value - */ -function checkCriticalTypeByteString(value) { - checkCriticalType( - value instanceof ByteString, `Must be a ByteString, but got: ${value}`); -} - -/** - * Checks whether a given object is an array of ByteString. - * @param {*} values - */ -function checkCriticalTypeByteStringArray(values) { - // TODO(b/134765672) - if (!CHECK_CRITICAL_TYPE) { - return; - } - const array = checkCriticalTypeArray(values); - for (const value of array) { - checkCriticalTypeByteString(value); - } -} - -/** - * Checks whether a given object is a number. - * @param {*} value - * @throws {!Error} If the value is not float and the check state is debug. - */ -function checkTypeDouble(value) { - if (!CHECK_TYPE) { - return; - } - checkCriticalTypeDouble(value); -} - -/** - * Checks whether a given object is a number. - * @param {*} value - * @throws {!Error} If the value is not float and the check state is critical. - */ -function checkCriticalTypeDouble(value) { - checkCriticalType( - typeof value === 'number', `Must be a number, but got: ${value}`); -} - -/** - * Checks whether a given object is an array of double. - * @param {*} values - */ -function checkCriticalTypeDoubleArray(values) { - // TODO(b/134765672) - if (!CHECK_CRITICAL_TYPE) { - return; - } - const array = checkCriticalTypeArray(values); - for (const value of array) { - checkCriticalTypeDouble(value); - } -} - -/** - * Checks whether a given object is a number. - * @param {*} value - * @throws {!Error} If the value is not signed int32 and the check state is - * debug. - */ -function checkTypeSignedInt32(value) { - if (!CHECK_TYPE) { - return; - } - checkCriticalTypeSignedInt32(value); -} - -/** - * Checks whether a given object is a number. - * @param {*} value - * @throws {!Error} If the value is not signed int32 and the check state is - * critical. - */ -function checkCriticalTypeSignedInt32(value) { - checkCriticalTypeDouble(value); - const valueAsNumber = /** @type {number} */ (value); - if (CHECK_CRITICAL_TYPE) { - if (valueAsNumber < -Math.pow(2, 31) || valueAsNumber > Math.pow(2, 31) || - !Number.isInteger(valueAsNumber)) { - throw new Error(`Must be int32, but got: ${valueAsNumber}`); - } - } -} - -/** - * Checks whether a given object is an array of numbers. - * @param {*} values - */ -function checkCriticalTypeSignedInt32Array(values) { - // TODO(b/134765672) - if (!CHECK_CRITICAL_TYPE) { - return; - } - const array = checkCriticalTypeArray(values); - for (const value of array) { - checkCriticalTypeSignedInt32(value); - } -} - -/** - * Ensures that value is a long instance. - * @param {*} value - * @throws {!Error} If the value is not a long instance and check state is - * debug. - */ -function checkTypeSignedInt64(value) { - if (!CHECK_TYPE) { - return; - } - checkCriticalTypeSignedInt64(value); -} - -/** - * Ensures that value is a long instance. - * @param {*} value - * @throws {!Error} If the value is not a long instance and check state is - * critical. - */ -function checkCriticalTypeSignedInt64(value) { - if (!CHECK_CRITICAL_TYPE) { - return; - } - if (!(value instanceof Int64)) { - throw new Error(`Must be Int64 instance, but got: ${value}`); - } -} - -/** - * Checks whether a given object is an array of long instances. - * @param {*} values - * @throws {!Error} If values is not an array of long instances. - */ -function checkCriticalTypeSignedInt64Array(values) { - // TODO(b/134765672) - if (!CHECK_CRITICAL_TYPE) { - return; - } - const array = checkCriticalTypeArray(values); - for (const value of array) { - checkCriticalTypeSignedInt64(value); - } -} - -/** - * Checks whether a given object is a number and within float32 precision. - * @param {*} value - * @throws {!Error} If the value is not float and the check state is debug. - */ -function checkTypeFloat(value) { - if (!CHECK_TYPE) { - return; - } - checkCriticalTypeFloat(value); -} - -/** - * Checks whether a given object is a number and within float32 precision. - * @param {*} value - * @throws {!Error} If the value is not float and the check state is critical. - */ -function checkCriticalTypeFloat(value) { - checkCriticalTypeDouble(value); - if (CHECK_CRITICAL_TYPE) { - const valueAsNumber = /** @type {number} */ (value); - if (Number.isFinite(valueAsNumber) && - (valueAsNumber > FLOAT32_MAX || valueAsNumber < -FLOAT32_MAX)) { - throw new Error( - `Given number does not fit into float precision: ${value}`); - } - } -} - -/** - * Checks whether a given object is an iterable of floats. - * @param {*} values - */ -function checkCriticalTypeFloatIterable(values) { - // TODO(b/134765672) - if (!CHECK_CRITICAL_TYPE) { - return; - } - const iterable = checkCriticalTypeIterable(values); - for (const value of iterable) { - checkCriticalTypeFloat(value); - } -} - -/** - * Checks whether a given object is a string. - * @param {*} value - */ -function checkCriticalTypeString(value) { - checkCriticalType( - typeof value === 'string', `Must be string, but got: ${value}`); -} - -/** - * Checks whether a given object is an array of string. - * @param {*} values - */ -function checkCriticalTypeStringArray(values) { - // TODO(b/134765672) - if (!CHECK_CRITICAL_TYPE) { - return; - } - const array = checkCriticalTypeArray(values); - for (const value of array) { - checkCriticalTypeString(value); - } -} - -/** - * Ensures that value is a valid unsigned int32. - * @param {*} value - * @throws {!Error} If the value is out of range and the check state is debug. - */ -function checkTypeUnsignedInt32(value) { - if (!CHECK_TYPE) { - return; - } - checkCriticalTypeUnsignedInt32(value); -} - -/** - * Ensures that value is a valid unsigned int32. - * @param {*} value - * @throws {!Error} If the value is out of range and the check state - * is critical. - */ -function checkCriticalTypeUnsignedInt32(value) { - if (!CHECK_CRITICAL_TYPE) { - return; - } - checkCriticalTypeDouble(value); - const valueAsNumber = /** @type {number} */ (value); - if (valueAsNumber < 0 || valueAsNumber > Math.pow(2, 32) - 1 || - !Number.isInteger(valueAsNumber)) { - throw new Error(`Must be uint32, but got: ${value}`); - } -} - -/** - * Checks whether a given object is an array of unsigned int32. - * @param {*} values - */ -function checkCriticalTypeUnsignedInt32Array(values) { - // TODO(b/134765672) - if (!CHECK_CRITICAL_TYPE) { - return; - } - const array = checkCriticalTypeArray(values); - for (const value of array) { - checkCriticalTypeUnsignedInt32(value); - } -} - -/** - * Checks whether a given object is an array of message. - * @param {*} values - */ -function checkCriticalTypeMessageArray(values) { - // TODO(b/134765672) - if (!CHECK_CRITICAL_TYPE) { - return; - } - const array = checkCriticalTypeArray(values); - for (const value of array) { - checkCriticalType( - value !== null, 'Given value is not a message instance: null'); - } -} - -exports = { - checkDefAndNotNull, - checkCriticalElementIndex, - checkCriticalFieldNumber, - checkCriticalPositionIndex, - checkCriticalRange, - checkCriticalState, - checkCriticalTypeBool, - checkCriticalTypeBoolArray, - checkCriticalTypeByteString, - checkCriticalTypeByteStringArray, - checkCriticalTypeDouble, - checkTypeDouble, - checkCriticalTypeDoubleArray, - checkTypeFloat, - checkCriticalTypeFloat, - checkCriticalTypeFloatIterable, - checkCriticalTypeMessageArray, - checkCriticalTypeSignedInt32, - checkCriticalTypeSignedInt32Array, - checkCriticalTypeSignedInt64, - checkTypeSignedInt64, - checkCriticalTypeSignedInt64Array, - checkCriticalTypeString, - checkCriticalTypeStringArray, - checkCriticalTypeUnsignedInt32, - checkCriticalTypeUnsignedInt32Array, - checkCriticalType, - checkCriticalWireType, - checkElementIndex, - checkFieldNumber, - checkFunctionExists, - checkPositionIndex, - checkRange, - checkState, - checkTypeUnsignedInt32, - checkTypeSignedInt32, - checkWireType, - CHECK_BOUNDS, - CHECK_CRITICAL_BOUNDS, - CHECK_STATE, - CHECK_CRITICAL_STATE, - CHECK_TYPE, - CHECK_CRITICAL_TYPE, - MAX_FIELD_NUMBER, - POLYFILL_TEXT_ENCODING, -}; diff --git a/js/experimental/runtime/internal/checks_test.js b/js/experimental/runtime/internal/checks_test.js deleted file mode 100644 index 50e857b3e..000000000 --- a/js/experimental/runtime/internal/checks_test.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @fileoverview Tests for checks.js. - */ -goog.module('protobuf.internal.checksTest'); - -const {CHECK_TYPE, checkDefAndNotNull, checkFunctionExists} = goog.require('protobuf.internal.checks'); - -describe('checkDefAndNotNull', () => { - it('throws if undefined', () => { - let value; - if (CHECK_TYPE) { - expect(() => checkDefAndNotNull(value)).toThrow(); - } else { - expect(checkDefAndNotNull(value)).toBeUndefined(); - } - }); - - it('throws if null', () => { - const value = null; - if (CHECK_TYPE) { - expect(() => checkDefAndNotNull(value)).toThrow(); - } else { - expect(checkDefAndNotNull(value)).toBeNull(); - } - }); - - it('does not throw if empty string', () => { - const value = ''; - expect(checkDefAndNotNull(value)).toEqual(''); - }); -}); - -describe('checkFunctionExists', () => { - it('throws if the function is undefined', () => { - let foo = /** @type {function()} */ (/** @type {*} */ (undefined)); - if (CHECK_TYPE) { - expect(() => checkFunctionExists(foo)).toThrow(); - } else { - checkFunctionExists(foo); - } - }); - - it('throws if the property is defined but not a function', () => { - let foo = /** @type {function()} */ (/** @type {*} */ (1)); - if (CHECK_TYPE) { - expect(() => checkFunctionExists(foo)).toThrow(); - } else { - checkFunctionExists(foo); - } - }); - - it('does not throw if the function is defined', () => { - function foo(x) { - return x; - } - checkFunctionExists(foo); - }); -}); \ No newline at end of file diff --git a/js/experimental/runtime/kernel/binary_storage.js b/js/experimental/runtime/kernel/binary_storage.js deleted file mode 100644 index 4cbde30a6..000000000 --- a/js/experimental/runtime/kernel/binary_storage.js +++ /dev/null @@ -1,130 +0,0 @@ -goog.module('protobuf.runtime.BinaryStorage'); - -const Storage = goog.require('protobuf.runtime.Storage'); -const {checkDefAndNotNull} = goog.require('protobuf.internal.checks'); - -/** - * Class storing all the fields of a binary protobuf message. - * - * @package - * @template FieldType - * @implements {Storage} - */ -class BinaryStorage { - /** - * @param {number=} pivot - */ - constructor(pivot = Storage.DEFAULT_PIVOT) { - /** - * Fields having a field number no greater than the pivot value are stored - * into an array for fast access. A field with field number X is stored into - * the array position X - 1. - * - * @private @const {!Array} - */ - this.array_ = new Array(pivot); - - /** - * Fields having a field number higher than the pivot value are stored into - * the map. We create the map only when it's needed, since even an empty map - * takes up a significant amount of memory. - * - * @private {?Map} - */ - this.map_ = null; - } - - /** - * Fields having a field number no greater than the pivot value are stored - * into an array for fast access. A field with field number X is stored into - * the array position X - 1. - * @return {number} - * @override - */ - getPivot() { - return this.array_.length; - } - - /** - * Sets a field in the specified field number. - * - * @param {number} fieldNumber - * @param {!FieldType} field - * @override - */ - set(fieldNumber, field) { - if (fieldNumber <= this.getPivot()) { - this.array_[fieldNumber - 1] = field; - } else { - if (this.map_) { - this.map_.set(fieldNumber, field); - } else { - this.map_ = new Map([[fieldNumber, field]]); - } - } - } - - /** - * Returns a field at the specified field number. - * - * @param {number} fieldNumber - * @return {!FieldType|undefined} - * @override - */ - get(fieldNumber) { - if (fieldNumber <= this.getPivot()) { - return this.array_[fieldNumber - 1]; - } else { - return this.map_ ? this.map_.get(fieldNumber) : undefined; - } - } - - /** - * Deletes a field from the specified field number. - * - * @param {number} fieldNumber - * @override - */ - delete(fieldNumber) { - if (fieldNumber <= this.getPivot()) { - delete this.array_[fieldNumber - 1]; - } else { - if (this.map_) { - this.map_.delete(fieldNumber); - } - } - } - - /** - * Executes the provided function once for each field. - * - * @param {function(!FieldType, number): void} callback - * @override - */ - forEach(callback) { - this.array_.forEach((field, fieldNumber) => { - if (field) { - callback(checkDefAndNotNull(field), fieldNumber + 1); - } - }); - if (this.map_) { - this.map_.forEach(callback); - } - } - - /** - * Creates a shallow copy of the storage. - * - * @return {!BinaryStorage} - * @override - */ - shallowCopy() { - const copy = new BinaryStorage(this.getPivot()); - this.forEach( - (field, fieldNumber) => - void copy.set(fieldNumber, field.shallowCopy())); - return copy; - } -} - -exports = BinaryStorage; diff --git a/js/experimental/runtime/kernel/binary_storage_test.js b/js/experimental/runtime/kernel/binary_storage_test.js deleted file mode 100644 index 2686f04e4..000000000 --- a/js/experimental/runtime/kernel/binary_storage_test.js +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @fileoverview Tests for storage.js. - */ -goog.module('protobuf.runtime.BinaryStorageTest'); - -goog.setTestOnly(); - -const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); -const {Field} = goog.require('protobuf.binary.field'); - -/** - * @type {number} - */ -const DEFAULT_PIVOT = 24; - -const /** !Field */ field1 = - Field.fromDecodedValue(/* decodedValue= */ 1, /* encoder= */ () => {}); -const /** !Field */ field2 = - Field.fromDecodedValue(/* decodedValue= */ 2, /* encoder= */ () => {}); -const /** !Field */ field3 = - Field.fromDecodedValue(/* decodedValue= */ 3, /* encoder= */ () => {}); -const /** !Field */ field4 = - Field.fromDecodedValue(/* decodedValue= */ 4, /* encoder= */ () => {}); - -/** - * Returns the number of fields stored. - * - * @param {!BinaryStorage} storage - * @return {number} - */ -function getStorageSize(storage) { - let size = 0; - storage.forEach(() => void size++); - return size; -} - -describe('BinaryStorage', () => { - it('sets and gets a field not greater than the pivot', () => { - const storage = new BinaryStorage(DEFAULT_PIVOT); - - storage.set(1, field1); - storage.set(DEFAULT_PIVOT, field2); - - expect(storage.getPivot()).toBe(DEFAULT_PIVOT); - expect(storage.get(1)).toBe(field1); - expect(storage.get(DEFAULT_PIVOT)).toBe(field2); - }); - - it('sets and gets a field greater than the pivot', () => { - const storage = new BinaryStorage(DEFAULT_PIVOT); - - storage.set(DEFAULT_PIVOT + 1, field1); - storage.set(100000, field2); - - expect(storage.get(DEFAULT_PIVOT + 1)).toBe(field1); - expect(storage.get(100000)).toBe(field2); - }); - - it('sets and gets a field when pivot is zero', () => { - const storage = new BinaryStorage(0); - - storage.set(0, field1); - storage.set(100000, field2); - - expect(storage.getPivot()).toBe(0); - expect(storage.get(0)).toBe(field1); - expect(storage.get(100000)).toBe(field2); - }); - - it('sets and gets a field when pivot is undefined', () => { - const storage = new BinaryStorage(); - - storage.set(0, field1); - storage.set(DEFAULT_PIVOT, field2); - storage.set(DEFAULT_PIVOT + 1, field3); - - expect(storage.getPivot()).toBe(DEFAULT_PIVOT); - expect(storage.get(0)).toBe(field1); - expect(storage.get(DEFAULT_PIVOT)).toBe(field2); - expect(storage.get(DEFAULT_PIVOT + 1)).toBe(field3); - }); - - it('returns undefined for nonexistent fields', () => { - const storage = new BinaryStorage(DEFAULT_PIVOT); - - expect(storage.get(1)).toBeUndefined(); - expect(storage.get(DEFAULT_PIVOT)).toBeUndefined(); - expect(storage.get(DEFAULT_PIVOT + 1)).toBeUndefined(); - expect(storage.get(100000)).toBeUndefined(); - }); - - it('returns undefined for nonexistent fields after map initialization', - () => { - const storage = new BinaryStorage(DEFAULT_PIVOT); - storage.set(100001, field1); - - expect(storage.get(1)).toBeUndefined(); - expect(storage.get(DEFAULT_PIVOT)).toBeUndefined(); - expect(storage.get(DEFAULT_PIVOT + 1)).toBeUndefined(); - expect(storage.get(100000)).toBeUndefined(); - }); - - it('deletes a field in delete() when values are only in array', () => { - const storage = new BinaryStorage(DEFAULT_PIVOT); - storage.set(1, field1); - - storage.delete(1); - - expect(storage.get(1)).toBeUndefined(); - }); - - it('deletes a field in delete() when values are both in array and map', - () => { - const storage = new BinaryStorage(DEFAULT_PIVOT); - storage.set(DEFAULT_PIVOT, field2); - storage.set(DEFAULT_PIVOT + 1, field3); - - storage.delete(DEFAULT_PIVOT); - storage.delete(DEFAULT_PIVOT + 1); - - expect(storage.get(DEFAULT_PIVOT)).toBeUndefined(); - expect(storage.get(DEFAULT_PIVOT + 1)).toBeUndefined(); - }); - - it('deletes a field in delete() when values are only in map', () => { - const storage = new BinaryStorage(DEFAULT_PIVOT); - storage.set(100000, field4); - - storage.delete(100000); - - expect(storage.get(100000)).toBeUndefined(); - }); - - it('loops over all the elements in forEach()', () => { - const storage = new BinaryStorage(DEFAULT_PIVOT); - storage.set(1, field1); - storage.set(DEFAULT_PIVOT, field2); - storage.set(DEFAULT_PIVOT + 1, field3); - storage.set(100000, field4); - - const fields = new Map(); - storage.forEach( - (field, fieldNumber) => void fields.set(fieldNumber, field)); - - expect(fields.size).toEqual(4); - expect(fields.get(1)).toBe(field1); - expect(storage.get(DEFAULT_PIVOT)).toBe(field2); - expect(storage.get(DEFAULT_PIVOT + 1)).toBe(field3); - expect(fields.get(100000)).toBe(field4); - }); - - it('creates a shallow copy of the storage in shallowCopy()', () => { - const storage = new BinaryStorage(DEFAULT_PIVOT); - storage.set(1, field1); - storage.set(100000, field2); - - const copy = storage.shallowCopy(); - - expect(getStorageSize(copy)).toEqual(2); - expect(copy.get(1)).not.toBe(field1); - expect(copy.get(1).getDecodedValue()).toEqual(1); - expect(copy.get(100000)).not.toBe(field1); - expect(copy.get(100000).getDecodedValue()).toEqual(2); - }); -}); diff --git a/js/experimental/runtime/kernel/bool_test_pairs.js b/js/experimental/runtime/kernel/bool_test_pairs.js deleted file mode 100644 index 4323f5baa..000000000 --- a/js/experimental/runtime/kernel/bool_test_pairs.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @fileoverview Test data for bool encoding and decoding. - */ -goog.module('protobuf.binary.boolTestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of boolean values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, boolValue: boolean, bufferDecoder: - * !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>} - */ -function getBoolPairs() { - const boolPairs = [ - { - name: 'true', - boolValue: true, - bufferDecoder: createBufferDecoder(0x01), - }, - { - name: 'false', - boolValue: false, - bufferDecoder: createBufferDecoder(0x00), - }, - { - name: 'two-byte true', - boolValue: true, - bufferDecoder: createBufferDecoder(0x80, 0x01), - skip_writer: true, - }, - { - name: 'two-byte false', - boolValue: false, - bufferDecoder: createBufferDecoder(0x80, 0x00), - skip_writer: true, - }, - { - name: 'minus one', - boolValue: true, - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01), - skip_writer: true, - }, - { - name: 'max signed int 2^63 - 1', - boolValue: true, - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F), - skip_writer: true, - }, - { - name: 'min signed int -2^63', - boolValue: true, - bufferDecoder: createBufferDecoder( - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01), - skip_writer: true, - }, - { - name: 'overflowed but valid varint', - boolValue: false, - bufferDecoder: createBufferDecoder( - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x02), - skip_writer: true, - }, - { - name: 'errors out for 11 bytes', - boolValue: true, - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - error: true, - skip_writer: true, - }, - ]; - return [...boolPairs]; -} - -exports = {getBoolPairs}; diff --git a/js/experimental/runtime/kernel/buffer_decoder.js b/js/experimental/runtime/kernel/buffer_decoder.js deleted file mode 100644 index b0c453542..000000000 --- a/js/experimental/runtime/kernel/buffer_decoder.js +++ /dev/null @@ -1,343 +0,0 @@ -/** - * @fileoverview A buffer implementation that can decode data for protobufs. - */ - -goog.module('protobuf.binary.BufferDecoder'); - -const ByteString = goog.require('protobuf.ByteString'); -const functions = goog.require('goog.functions'); -const {POLYFILL_TEXT_ENCODING, checkCriticalPositionIndex, checkCriticalState, checkState} = goog.require('protobuf.internal.checks'); -const {byteStringFromUint8ArrayUnsafe} = goog.require('protobuf.byteStringInternal'); -const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays'); -const {decode} = goog.require('protobuf.binary.textencoding'); - -/** - * Returns a valid utf-8 decoder function based on TextDecoder if available or - * a polyfill. - * Some of the environments we run in do not have TextDecoder defined. - * TextDecoder is faster than our polyfill so we prefer it over the polyfill. - * @return {function(!DataView): string} - */ -function getStringDecoderFunction() { - if (goog.global['TextDecoder']) { - const textDecoder = new goog.global['TextDecoder']('utf-8', {fatal: true}); - return bytes => textDecoder.decode(bytes); - } - if (POLYFILL_TEXT_ENCODING) { - return decode; - } else { - throw new Error( - 'TextDecoder is missing. ' + - 'Enable protobuf.defines.POLYFILL_TEXT_ENCODING.'); - } -} - -/** @type {function(): function(!DataView): string} */ -const stringDecoderFunction = - functions.cacheReturnValue(() => getStringDecoderFunction()); - -/** @type {function(): !DataView} */ -const emptyDataView = - functions.cacheReturnValue(() => new DataView(new ArrayBuffer(0))); - -class BufferDecoder { - /** - * @param {!Array} bufferDecoders - * @return {!BufferDecoder} - */ - static merge(bufferDecoders) { - const uint8Arrays = bufferDecoders.map(b => b.asUint8Array()); - const bytesArray = concatenateByteArrays(uint8Arrays); - return BufferDecoder.fromArrayBuffer(bytesArray.buffer); - } - - /** - * @param {!ArrayBuffer} arrayBuffer - * @return {!BufferDecoder} - */ - static fromArrayBuffer(arrayBuffer) { - return new BufferDecoder( - new DataView(arrayBuffer), 0, arrayBuffer.byteLength); - } - - /** - * @param {!DataView} dataView - * @param {number} startIndex - * @param {number} length - * @private - */ - constructor(dataView, startIndex, length) { - /** @private @const {!DataView} */ - this.dataView_ = dataView; - /** @private @const {number} */ - this.startIndex_ = startIndex; - /** @private @const {number} */ - this.endIndex_ = startIndex + length; - /** @private {number} */ - this.cursor_ = startIndex; - } - - /** - * Returns the start index of the underlying buffer. - * @return {number} - */ - startIndex() { - return this.startIndex_; - } - - /** - * Returns the end index of the underlying buffer. - * @return {number} - */ - endIndex() { - return this.endIndex_; - } - - /** - * Returns the length of the underlying buffer. - * @return {number} - */ - length() { - return this.endIndex_ - this.startIndex_; - } - - /** - * Returns the start position of the next data, i.e. end position of the last - * read data + 1. - * @return {number} - */ - cursor() { - return this.cursor_; - } - - /** - * Sets the cursor to the specified position. - * @param {number} position - */ - setCursor(position) { - this.cursor_ = position; - } - - /** - * Returns if there is more data to read after the current cursor position. - * @return {boolean} - */ - hasNext() { - return this.cursor_ < this.endIndex_; - } - - /** - * Returns a float32 from a given index - * @param {number} index - * @return {number} - */ - getFloat32(index) { - this.cursor_ = index + 4; - return this.dataView_.getFloat32(index, true); - } - - /** - * Returns a float64 from a given index - * @param {number} index - * @return {number} - */ - getFloat64(index) { - this.cursor_ = index + 8; - return this.dataView_.getFloat64(index, true); - } - - /** - * Returns an int32 from a given index - * @param {number} index - * @return {number} - */ - getInt32(index) { - this.cursor_ = index + 4; - return this.dataView_.getInt32(index, true); - } - - /** - * Returns a uint32 from a given index - * @param {number} index - * @return {number} - */ - getUint32(index) { - this.cursor_ = index + 4; - return this.dataView_.getUint32(index, true); - } - - /** - * Returns two JS numbers each representing 32 bits of a 64 bit number. Also - * sets the cursor to the start of the next block of data. - * @param {number} index - * @return {{lowBits: number, highBits: number}} - */ - getVarint(index) { - this.cursor_ = index; - let lowBits = 0; - let highBits = 0; - - for (let shift = 0; shift < 28; shift += 7) { - const b = this.dataView_.getUint8(this.cursor_++); - lowBits |= (b & 0x7F) << shift; - if ((b & 0x80) === 0) { - return {lowBits, highBits}; - } - } - - const middleByte = this.dataView_.getUint8(this.cursor_++); - - // last four bits of the first 32 bit number - lowBits |= (middleByte & 0x0F) << 28; - - // 3 upper bits are part of the next 32 bit number - highBits = (middleByte & 0x70) >> 4; - - if ((middleByte & 0x80) === 0) { - return {lowBits, highBits}; - } - - - for (let shift = 3; shift <= 31; shift += 7) { - const b = this.dataView_.getUint8(this.cursor_++); - highBits |= (b & 0x7F) << shift; - if ((b & 0x80) === 0) { - return {lowBits, highBits}; - } - } - - checkCriticalState(false, 'Data is longer than 10 bytes'); - - return {lowBits, highBits}; - } - - /** - * Returns an unsigned int32 number at the current cursor position. The upper - * bits are discarded if the varint is longer than 32 bits. Also sets the - * cursor to the start of the next block of data. - * @return {number} - */ - getUnsignedVarint32() { - let b = this.dataView_.getUint8(this.cursor_++); - let result = b & 0x7F; - if ((b & 0x80) === 0) { - return result; - } - - b = this.dataView_.getUint8(this.cursor_++); - result |= (b & 0x7F) << 7; - if ((b & 0x80) === 0) { - return result; - } - - b = this.dataView_.getUint8(this.cursor_++); - result |= (b & 0x7F) << 14; - if ((b & 0x80) === 0) { - return result; - } - - b = this.dataView_.getUint8(this.cursor_++); - result |= (b & 0x7F) << 21; - if ((b & 0x80) === 0) { - return result; - } - - // Extract only last 4 bits - b = this.dataView_.getUint8(this.cursor_++); - result |= (b & 0x0F) << 28; - - for (let readBytes = 5; ((b & 0x80) !== 0) && readBytes < 10; readBytes++) { - b = this.dataView_.getUint8(this.cursor_++); - } - - checkCriticalState((b & 0x80) === 0, 'Data is longer than 10 bytes'); - - // Result can be have 32 bits, convert it to unsigned - return result >>> 0; - } - - /** - * Returns an unsigned int32 number at the specified index. The upper bits are - * discarded if the varint is longer than 32 bits. Also sets the cursor to the - * start of the next block of data. - * @param {number} index - * @return {number} - */ - getUnsignedVarint32At(index) { - this.cursor_ = index; - return this.getUnsignedVarint32(); - } - - /** - * Seeks forward by the given amount. - * @param {number} skipAmount - * @package - */ - skip(skipAmount) { - this.cursor_ += skipAmount; - checkCriticalPositionIndex(this.cursor_, this.endIndex_); - } - - /** - * Skips over a varint from the current cursor position. - * @package - */ - skipVarint() { - const startIndex = this.cursor_; - while (this.dataView_.getUint8(this.cursor_++) & 0x80) { - } - checkCriticalPositionIndex(this.cursor_, startIndex + 10); - } - - /** - * @param {number} startIndex - * @param {number} length - * @return {!BufferDecoder} - */ - subBufferDecoder(startIndex, length) { - checkState( - startIndex >= this.startIndex(), - `Current start: ${this.startIndex()}, subBufferDecoder start: ${ - startIndex}`); - checkState(length >= 0, `Length: ${length}`); - checkState( - startIndex + length <= this.endIndex(), - `Current end: ${this.endIndex()}, subBufferDecoder start: ${ - startIndex}, subBufferDecoder length: ${length}`); - return new BufferDecoder(this.dataView_, startIndex, length); - } - - /** - * Returns the buffer as a string. - * @return {string} - */ - asString() { - // TODO: Remove this check when we no longer need to support IE - const stringDataView = this.length() === 0 ? - emptyDataView() : - new DataView(this.dataView_.buffer, this.startIndex_, this.length()); - return stringDecoderFunction()(stringDataView); - } - - /** - * Returns the buffer as a ByteString. - * @return {!ByteString} - */ - asByteString() { - return byteStringFromUint8ArrayUnsafe(this.asUint8Array()); - } - - /** - * Returns the DataView as an Uint8Array. DO NOT MODIFY or expose the - * underlying buffer. - * - * @package - * @return {!Uint8Array} - */ - asUint8Array() { - return new Uint8Array( - this.dataView_.buffer, this.startIndex_, this.length()); - } -} - -exports = BufferDecoder; diff --git a/js/experimental/runtime/kernel/buffer_decoder_helper.js b/js/experimental/runtime/kernel/buffer_decoder_helper.js deleted file mode 100644 index eed3c42d0..000000000 --- a/js/experimental/runtime/kernel/buffer_decoder_helper.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @fileoverview Helper methods to create BufferDecoders. - */ -goog.module('protobuf.binary.bufferDecoderHelper'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); - -/** - * @param {...number} bytes - * @return {!BufferDecoder} - */ -function createBufferDecoder(...bytes) { - return BufferDecoder.fromArrayBuffer(new Uint8Array(bytes).buffer); -} - -exports = { - createBufferDecoder, -}; diff --git a/js/experimental/runtime/kernel/buffer_decoder_test.js b/js/experimental/runtime/kernel/buffer_decoder_test.js deleted file mode 100644 index 17f28966b..000000000 --- a/js/experimental/runtime/kernel/buffer_decoder_test.js +++ /dev/null @@ -1,242 +0,0 @@ -/** - * @fileoverview Tests for BufferDecoder. - */ - -goog.module('protobuf.binary.varintsTest'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {CHECK_CRITICAL_STATE, CHECK_STATE} = goog.require('protobuf.internal.checks'); - -goog.setTestOnly(); - -/** - * @param {...number} bytes - * @return {!ArrayBuffer} - */ -function createArrayBuffer(...bytes) { - return new Uint8Array(bytes).buffer; -} - -describe('setCursor does', () => { - it('set the cursor at the position specified', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1)); - expect(bufferDecoder.cursor()).toBe(0); - bufferDecoder.setCursor(1); - expect(bufferDecoder.cursor()).toBe(1); - }); -}); - -describe('skip does', () => { - it('advance the cursor', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1, 0x2)); - bufferDecoder.setCursor(1); - bufferDecoder.skip(1); - expect(bufferDecoder.cursor()).toBe(2); - }); -}); - -describe('Skip varint does', () => { - it('skip a varint', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)); - bufferDecoder.skipVarint(); - expect(bufferDecoder.cursor()).toBe(1); - }); - - it('fail when varint is larger than 10 bytes', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - - if (CHECK_CRITICAL_STATE) { - expect(() => bufferDecoder.skipVarint()).toThrow(); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - bufferDecoder.skipVarint(); - expect(bufferDecoder.cursor()).toBe(11); - } - }); - - it('fail when varint is beyond end of underlying array', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x80)); - expect(() => bufferDecoder.skipVarint()).toThrow(); - }); -}); - -describe('readVarint64 does', () => { - it('read zero', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00)); - const {lowBits, highBits} = bufferDecoder.getVarint(0); - expect(lowBits).toBe(0); - expect(highBits).toBe(0); - expect(bufferDecoder.cursor()).toBe(1); - }); - - it('read one', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)); - const {lowBits, highBits} = bufferDecoder.getVarint(0); - expect(lowBits).toBe(1); - expect(highBits).toBe(0); - expect(bufferDecoder.cursor()).toBe(1); - }); - - it('read max value', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01)); - const {lowBits, highBits} = bufferDecoder.getVarint(0); - expect(lowBits).toBe(-1); - expect(highBits).toBe(-1); - expect(bufferDecoder.cursor()).toBe(10); - }); -}); - -describe('readUnsignedVarint32 does', () => { - it('read zero', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00)); - const result = bufferDecoder.getUnsignedVarint32(); - expect(result).toBe(0); - expect(bufferDecoder.cursor()).toBe(1); - }); - - it('read one', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)); - const result = bufferDecoder.getUnsignedVarint32(); - expect(result).toBe(1); - expect(bufferDecoder.cursor()).toBe(1); - }); - - it('read max int32', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF, 0x0F)); - const result = bufferDecoder.getUnsignedVarint32(); - expect(result).toBe(4294967295); - expect(bufferDecoder.cursor()).toBe(5); - }); - - it('read max value', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01)); - const result = bufferDecoder.getUnsignedVarint32(); - expect(result).toBe(4294967295); - expect(bufferDecoder.cursor()).toBe(10); - }); - - it('fail if data is longer than 10 bytes', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01)); - if (CHECK_CRITICAL_STATE) { - expect(() => bufferDecoder.getUnsignedVarint32()).toThrow(); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const result = bufferDecoder.getUnsignedVarint32(); - expect(result).toBe(4294967295); - expect(bufferDecoder.cursor()).toBe(10); - } - }); -}); - -describe('readUnsignedVarint32At does', () => { - it('reads from a specific index', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x1, 0x2)); - const result = bufferDecoder.getUnsignedVarint32At(1); - expect(result).toBe(2); - expect(bufferDecoder.cursor()).toBe(2); - }); -}); - -describe('getFloat32 does', () => { - it('read one', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0x00, 0x00, 0x80, 0x3F)); - const result = bufferDecoder.getFloat32(0); - expect(result).toBe(1); - expect(bufferDecoder.cursor()).toBe(4); - }); -}); - -describe('getFloat64 does', () => { - it('read one', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F)); - const result = bufferDecoder.getFloat64(0); - expect(result).toBe(1); - expect(bufferDecoder.cursor()).toBe(8); - }); -}); - -describe('getInt32 does', () => { - it('read one', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0x01, 0x00, 0x00, 0x00)); - const result = bufferDecoder.getInt32(0); - expect(result).toBe(1); - expect(bufferDecoder.cursor()).toBe(4); - }); - - it('read minus one', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF)); - const result = bufferDecoder.getInt32(0); - expect(result).toBe(-1); - expect(bufferDecoder.cursor()).toBe(4); - }); -}); - -describe('getUint32 does', () => { - it('read one', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01, 0x00, 0x00, 0x0)); - const result = bufferDecoder.getUint32(0); - expect(result).toBe(1); - expect(bufferDecoder.cursor()).toBe(4); - }); - - it('read max uint32', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF)); - const result = bufferDecoder.getUint32(0); - expect(result).toBe(4294967295); - expect(bufferDecoder.cursor()).toBe(4); - }); -}); - -describe('subBufferDecoder does', () => { - it('can create valid sub buffers', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00, 0x01, 0x02)); - - expect(bufferDecoder.subBufferDecoder(0, 0)) - .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer())); - expect(bufferDecoder.subBufferDecoder(0, 1)) - .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00))); - expect(bufferDecoder.subBufferDecoder(1, 0)) - .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer())); - expect(bufferDecoder.subBufferDecoder(1, 1)) - .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01))); - expect(bufferDecoder.subBufferDecoder(1, 2)) - .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01, 0x02))); - }); - - it('can not create invalid', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00, 0x01, 0x02)); - if (CHECK_STATE) { - expect(() => bufferDecoder.subBufferDecoder(-1, 1)).toThrow(); - expect(() => bufferDecoder.subBufferDecoder(0, -4)).toThrow(); - expect(() => bufferDecoder.subBufferDecoder(0, 4)).toThrow(); - } - }); -}); diff --git a/js/experimental/runtime/kernel/conformance/conformance_request.js b/js/experimental/runtime/kernel/conformance/conformance_request.js deleted file mode 100644 index 2d4f1067f..000000000 --- a/js/experimental/runtime/kernel/conformance/conformance_request.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @fileoverview Handwritten code of ConformanceRequest. - */ -goog.module('proto.conformance.ConformanceRequest'); - -const Kernel = goog.require('protobuf.runtime.Kernel'); -const WireFormat = goog.require('proto.conformance.WireFormat'); - -/** - * Handwritten code of conformance.ConformanceRequest. - * This is used to send request from the conformance test runner to the testee. - * Check //third_party/protobuf/testing/protobuf/conformance/conformance.proto - * for more details. - * @final - */ -class ConformanceRequest { - /** - * @param {!ArrayBuffer} bytes - * @private - */ - constructor(bytes) { - /** @private @const {!Kernel} */ - this.accessor_ = Kernel.fromArrayBuffer(bytes); - } - - /** - * Create a request instance with the given bytes data. - * @param {!ArrayBuffer} bytes - * @return {!ConformanceRequest} - */ - static deserialize(bytes) { - return new ConformanceRequest(bytes); - } - - /** - * Gets the protobuf_payload. - * @return {!ArrayBuffer} - */ - getProtobufPayload() { - return this.accessor_.getBytesWithDefault(1).toArrayBuffer(); - } - - /** - * Gets the requested_output_format. - * @return {!WireFormat} - */ - getRequestedOutputFormat() { - return /** @type {!WireFormat} */ (this.accessor_.getInt32WithDefault(3)); - } - - /** - * Gets the message_type. - * @return {string} - */ - getMessageType() { - return this.accessor_.getStringWithDefault(4); - } - - /** - * Gets the oneof case for payload field. - * This implementation assumes only one field in a oneof group is set. - * @return {!ConformanceRequest.PayloadCase} - */ - getPayloadCase() { - if (this.accessor_.hasFieldNumber(1)) { - return /** @type {!ConformanceRequest.PayloadCase} */ ( - ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD); - } else if (this.accessor_.hasFieldNumber(2)) { - return /** @type {!ConformanceRequest.PayloadCase} */ ( - ConformanceRequest.PayloadCase.JSON_PAYLOAD); - } else if (this.accessor_.hasFieldNumber(8)) { - return /** @type {!ConformanceRequest.PayloadCase} */ ( - ConformanceRequest.PayloadCase.TEXT_PAYLOAD); - } else { - return /** @type {!ConformanceRequest.PayloadCase} */ ( - ConformanceRequest.PayloadCase.PAYLOAD_NOT_SET); - } - } -} - -/** - * @enum {number} - */ -ConformanceRequest.PayloadCase = { - PAYLOAD_NOT_SET: 0, - PROTOBUF_PAYLOAD: 1, - JSON_PAYLOAD: 2, - TEXT_PAYLOAD: 8, -}; - -exports = ConformanceRequest; diff --git a/js/experimental/runtime/kernel/conformance/conformance_response.js b/js/experimental/runtime/kernel/conformance/conformance_response.js deleted file mode 100644 index 482f31bb8..000000000 --- a/js/experimental/runtime/kernel/conformance/conformance_response.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @fileoverview Handwritten code of ConformanceResponse. - */ -goog.module('proto.conformance.ConformanceResponse'); - -const ByteString = goog.require('protobuf.ByteString'); -const Kernel = goog.require('protobuf.runtime.Kernel'); - -/** - * Handwritten code of conformance.ConformanceResponse. - * This is used to send response from the conformance testee to the test runner. - * Check //third_party/protobuf/testing/protobuf/conformance/conformance.proto - * for more details. - * @final - */ -class ConformanceResponse { - /** - * @param {!ArrayBuffer} bytes - * @private - */ - constructor(bytes) { - /** @private @const {!Kernel} */ - this.accessor_ = Kernel.fromArrayBuffer(bytes); - } - - /** - * Create an empty response instance. - * @return {!ConformanceResponse} - */ - static createEmpty() { - return new ConformanceResponse(new ArrayBuffer(0)); - } - - /** - * Sets parse_error field. - * @param {string} value - */ - setParseError(value) { - this.accessor_.setString(1, value); - } - - /** - * Sets runtime_error field. - * @param {string} value - */ - setRuntimeError(value) { - this.accessor_.setString(2, value); - } - - /** - * Sets protobuf_payload field. - * @param {!ArrayBuffer} value - */ - setProtobufPayload(value) { - const bytesString = ByteString.fromArrayBuffer(value); - this.accessor_.setBytes(3, bytesString); - } - - /** - * Sets skipped field. - * @param {string} value - */ - setSkipped(value) { - this.accessor_.setString(5, value); - } - - /** - * Serializes into binary data. - * @return {!ArrayBuffer} - */ - serialize() { - return this.accessor_.serialize(); - } -} - -exports = ConformanceResponse; diff --git a/js/experimental/runtime/kernel/conformance/conformance_testee.js b/js/experimental/runtime/kernel/conformance/conformance_testee.js deleted file mode 100755 index 2945228dd..000000000 --- a/js/experimental/runtime/kernel/conformance/conformance_testee.js +++ /dev/null @@ -1,103 +0,0 @@ -goog.module('javascript.protobuf.conformance'); - -const ConformanceRequest = goog.require('proto.conformance.ConformanceRequest'); -const ConformanceResponse = goog.require('proto.conformance.ConformanceResponse'); -const TestAllTypesProto2 = goog.require('proto.conformance.TestAllTypesProto2'); -const TestAllTypesProto3 = goog.require('proto.conformance.TestAllTypesProto3'); -const WireFormat = goog.require('proto.conformance.WireFormat'); -const base64 = goog.require('goog.crypt.base64'); - -/** - * Creates a `proto.conformance.ConformanceResponse` response according to the - * `proto.conformance.ConformanceRequest` request. - * @param {!ConformanceRequest} request - * @return {!ConformanceResponse} response - */ -function doTest(request) { - const response = ConformanceResponse.createEmpty(); - - if(request.getPayloadCase() === ConformanceRequest.PayloadCase.JSON_PAYLOAD) { - response.setSkipped('Json is not supported as input format.'); - return response; - } - - if(request.getPayloadCase() === ConformanceRequest.PayloadCase.TEXT_PAYLOAD) { - response.setSkipped('Text format is not supported as input format.'); - return response; - } - - if(request.getPayloadCase() === ConformanceRequest.PayloadCase.PAYLOAD_NOT_SET) { - response.setRuntimeError('Request didn\'t have payload.'); - return response; - } - - if(request.getPayloadCase() !== ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD) { - throw new Error('Request didn\'t have accepted input format.'); - } - - if (request.getRequestedOutputFormat() === WireFormat.JSON) { - response.setSkipped('Json is not supported as output format.'); - return response; - } - - if (request.getRequestedOutputFormat() === WireFormat.TEXT_FORMAT) { - response.setSkipped('Text format is not supported as output format.'); - return response; - } - - if (request.getRequestedOutputFormat() === WireFormat.TEXT_FORMAT) { - response.setRuntimeError('Unspecified output format'); - return response; - } - - if (request.getRequestedOutputFormat() !== WireFormat.PROTOBUF) { - throw new Error('Request didn\'t have accepted output format.'); - } - - if (request.getMessageType() === 'conformance.FailureSet') { - response.setProtobufPayload(new ArrayBuffer(0)); - } else if ( - request.getMessageType() === - 'protobuf_test_messages.proto2.TestAllTypesProto2') { - try { - const testMessage = - TestAllTypesProto2.deserialize(request.getProtobufPayload()); - response.setProtobufPayload(testMessage.serialize()); - } catch (err) { - response.setParseError(err.toString()); - } - } else if ( - request.getMessageType() === - 'protobuf_test_messages.proto3.TestAllTypesProto3') { - try { - const testMessage = - TestAllTypesProto3.deserialize(request.getProtobufPayload()); - response.setProtobufPayload(testMessage.serialize()); - } catch (err) { - response.setParseError(err.toString()); - } - } else { - throw new Error( - `Payload message not supported: ${request.getMessageType()}.`); - } - - return response; -} - -/** - * Same as doTest, but both request and response are in base64. - * @param {string} base64Request - * @return {string} response - */ -function runConformanceTest(base64Request) { - const request = - ConformanceRequest.deserialize( - base64.decodeStringToUint8Array(base64Request).buffer); - const response = doTest(request); - return base64.encodeByteArray(new Uint8Array(response.serialize())); -} - -// Needed for node test -exports.doTest = doTest; -// Needed for browser test -goog.exportSymbol('runConformanceTest', runConformanceTest); diff --git a/js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js b/js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js deleted file mode 100755 index c12f363ec..000000000 --- a/js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js +++ /dev/null @@ -1,62 +0,0 @@ -const ConformanceRequest = goog.require('proto.conformance.ConformanceRequest'); -const {doTest} = goog.require('javascript.protobuf.conformance'); -const fs = require('fs'); - - -/** - * Reads a buffer of N bytes. - * @param {number} bytes Number of bytes to read. - * @return {!Buffer} Buffer which contains data. - */ -function readBuffer(bytes) { - // Linux cannot use process.stdin.fd (which isn't set up as sync) - const buf = new Buffer.alloc(bytes); - const fd = fs.openSync('/dev/stdin', 'r'); - fs.readSync(fd, buf, 0, bytes); - fs.closeSync(fd); - return buf; -} - -/** - * Writes all data in buffer. - * @param {!Buffer} buffer Buffer which contains data. - */ -function writeBuffer(buffer) { - // Under linux, process.stdout.fd is async. Needs to open stdout in a synced - // way for sync write. - const fd = fs.openSync('/dev/stdout', 'w'); - fs.writeSync(fd, buffer, 0, buffer.length); - fs.closeSync(fd); -} - -/** - * Returns true if the test ran successfully, false on legitimate EOF. - * @return {boolean} Whether to continue test. - */ -function runConformanceTest() { - const requestLengthBuf = readBuffer(4); - const requestLength = requestLengthBuf.readInt32LE(0); - if (!requestLength) { - return false; - } - - const serializedRequest = readBuffer(requestLength); - const array = new Uint8Array(serializedRequest); - const request = ConformanceRequest.deserialize(array.buffer); - const response = doTest(request); - - const serializedResponse = response.serialize(); - - const responseLengthBuf = new Buffer.alloc(4); - responseLengthBuf.writeInt32LE(serializedResponse.byteLength, 0); - writeBuffer(responseLengthBuf); - writeBuffer(new Buffer.from(serializedResponse)); - - return true; -} - -while (true) { - if (!runConformanceTest()) { - break; - } -} diff --git a/js/experimental/runtime/kernel/conformance/test_all_types_proto2.js b/js/experimental/runtime/kernel/conformance/test_all_types_proto2.js deleted file mode 100644 index 3be1beea0..000000000 --- a/js/experimental/runtime/kernel/conformance/test_all_types_proto2.js +++ /dev/null @@ -1,309 +0,0 @@ -/** - * @fileoverview Handwritten code of TestAllTypesProto2. - */ -goog.module('proto.conformance.TestAllTypesProto2'); - -const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const Kernel = goog.require('protobuf.runtime.Kernel'); - -/** - * Handwritten code of conformance.TestAllTypesProto2. - * Check google/protobuf/test_messages_proto3.proto for more details. - * @implements {InternalMessage} - * @final - */ -class TestAllTypesProto2 { - /** - * @param {!Kernel=} accessor - * @private - */ - constructor(accessor = Kernel.createEmpty()) { - /** @private @const {!Kernel} */ - this.accessor_ = accessor; - } - - /** - * @override - * @package - * @return {!Kernel} - */ - internalGetKernel() { - return this.accessor_; - } - - /** - * Create a request instance with the given bytes data. - * If we directly use the accessor created by the binary decoding, the - * Kernel instance will only copy the same data over for encoding. By - * explicitly fetching data from the previous accessor and setting all fields - * into a new accessor, we will actually test encoding/decoding for the binary - * format. - * @param {!ArrayBuffer} bytes - * @return {!TestAllTypesProto2} - */ - static deserialize(bytes) { - const msg = new TestAllTypesProto2(); - const requestAccessor = Kernel.fromArrayBuffer(bytes); - - if (requestAccessor.hasFieldNumber(1)) { - const value = requestAccessor.getInt32WithDefault(1); - msg.accessor_.setInt32(1, value); - } - - if (requestAccessor.hasFieldNumber(2)) { - const value = requestAccessor.getInt64WithDefault(2); - msg.accessor_.setInt64(2, value); - } - - if (requestAccessor.hasFieldNumber(3)) { - const value = requestAccessor.getUint32WithDefault(3); - msg.accessor_.setUint32(3, value); - } - - if (requestAccessor.hasFieldNumber(4)) { - const value = requestAccessor.getUint64WithDefault(4); - msg.accessor_.setUint64(4, value); - } - - if (requestAccessor.hasFieldNumber(5)) { - const value = requestAccessor.getSint32WithDefault(5); - msg.accessor_.setSint32(5, value); - } - - if (requestAccessor.hasFieldNumber(6)) { - const value = requestAccessor.getSint64WithDefault(6); - msg.accessor_.setSint64(6, value); - } - - if (requestAccessor.hasFieldNumber(7)) { - const value = requestAccessor.getFixed32WithDefault(7); - msg.accessor_.setFixed32(7, value); - } - - if (requestAccessor.hasFieldNumber(8)) { - const value = requestAccessor.getFixed64WithDefault(8); - msg.accessor_.setFixed64(8, value); - } - - if (requestAccessor.hasFieldNumber(9)) { - const value = requestAccessor.getSfixed32WithDefault(9); - msg.accessor_.setSfixed32(9, value); - } - - if (requestAccessor.hasFieldNumber(10)) { - const value = requestAccessor.getSfixed64WithDefault(10); - msg.accessor_.setSfixed64(10, value); - } - - if (requestAccessor.hasFieldNumber(11)) { - const value = requestAccessor.getFloatWithDefault(11); - msg.accessor_.setFloat(11, value); - } - - if (requestAccessor.hasFieldNumber(12)) { - const value = requestAccessor.getDoubleWithDefault(12); - msg.accessor_.setDouble(12, value); - } - - if (requestAccessor.hasFieldNumber(13)) { - const value = requestAccessor.getBoolWithDefault(13); - msg.accessor_.setBool(13, value); - } - - if (requestAccessor.hasFieldNumber(14)) { - const value = requestAccessor.getStringWithDefault(14); - msg.accessor_.setString(14, value); - } - - if (requestAccessor.hasFieldNumber(15)) { - const value = requestAccessor.getBytesWithDefault(15); - msg.accessor_.setBytes(15, value); - } - - if (requestAccessor.hasFieldNumber(18)) { - const value = requestAccessor.getMessage( - 18, (accessor) => new TestAllTypesProto2(accessor)); - msg.accessor_.setMessage(18, value); - } - - if (requestAccessor.hasFieldNumber(21)) { - // Unknown enum is not checked here, because even if an enum is unknown, - // it should be kept during encoding. For the purpose of wire format test, - // we can simplify the implementation by treating it as an int32 field, - // which has the same semantic except for the unknown value checking. - const value = requestAccessor.getInt32WithDefault(21); - msg.accessor_.setInt32(21, value); - } - - if (requestAccessor.hasFieldNumber(31)) { - const value = requestAccessor.getRepeatedInt32Iterable(31); - msg.accessor_.setUnpackedInt32Iterable(31, value); - } - - if (requestAccessor.hasFieldNumber(32)) { - const value = requestAccessor.getRepeatedInt64Iterable(32); - msg.accessor_.setUnpackedInt64Iterable(32, value); - } - - if (requestAccessor.hasFieldNumber(33)) { - const value = requestAccessor.getRepeatedUint32Iterable(33); - msg.accessor_.setUnpackedUint32Iterable(33, value); - } - - if (requestAccessor.hasFieldNumber(34)) { - const value = requestAccessor.getRepeatedUint64Iterable(34); - msg.accessor_.setUnpackedUint64Iterable(34, value); - } - - if (requestAccessor.hasFieldNumber(35)) { - const value = requestAccessor.getRepeatedSint32Iterable(35); - msg.accessor_.setUnpackedSint32Iterable(35, value); - } - - if (requestAccessor.hasFieldNumber(36)) { - const value = requestAccessor.getRepeatedSint64Iterable(36); - msg.accessor_.setUnpackedSint64Iterable(36, value); - } - - if (requestAccessor.hasFieldNumber(37)) { - const value = requestAccessor.getRepeatedFixed32Iterable(37); - msg.accessor_.setUnpackedFixed32Iterable(37, value); - } - - if (requestAccessor.hasFieldNumber(38)) { - const value = requestAccessor.getRepeatedFixed64Iterable(38); - msg.accessor_.setUnpackedFixed64Iterable(38, value); - } - - if (requestAccessor.hasFieldNumber(39)) { - const value = requestAccessor.getRepeatedSfixed32Iterable(39); - msg.accessor_.setUnpackedSfixed32Iterable(39, value); - } - - if (requestAccessor.hasFieldNumber(40)) { - const value = requestAccessor.getRepeatedSfixed64Iterable(40); - msg.accessor_.setUnpackedSfixed64Iterable(40, value); - } - - if (requestAccessor.hasFieldNumber(41)) { - const value = requestAccessor.getRepeatedFloatIterable(41); - msg.accessor_.setUnpackedFloatIterable(41, value); - } - - if (requestAccessor.hasFieldNumber(42)) { - const value = requestAccessor.getRepeatedDoubleIterable(42); - msg.accessor_.setUnpackedDoubleIterable(42, value); - } - - if (requestAccessor.hasFieldNumber(43)) { - const value = requestAccessor.getRepeatedBoolIterable(43); - msg.accessor_.setUnpackedBoolIterable(43, value); - } - - if (requestAccessor.hasFieldNumber(44)) { - const value = requestAccessor.getRepeatedStringIterable(44); - msg.accessor_.setRepeatedStringIterable(44, value); - } - - if (requestAccessor.hasFieldNumber(45)) { - const value = requestAccessor.getRepeatedBytesIterable(45); - msg.accessor_.setRepeatedBytesIterable(45, value); - } - - if (requestAccessor.hasFieldNumber(48)) { - const value = requestAccessor.getRepeatedMessageIterable( - 48, (accessor) => new TestAllTypesProto2(accessor)); - msg.accessor_.setRepeatedMessageIterable(48, value); - } - - if (requestAccessor.hasFieldNumber(51)) { - // Unknown enum is not checked here, because even if an enum is unknown, - // it should be kept during encoding. For the purpose of wire format test, - // we can simplify the implementation by treating it as an int32 field, - // which has the same semantic except for the unknown value checking. - const value = requestAccessor.getRepeatedInt32Iterable(51); - msg.accessor_.setUnpackedInt32Iterable(51, value); - } - - if (requestAccessor.hasFieldNumber(75)) { - const value = requestAccessor.getRepeatedInt32Iterable(75); - msg.accessor_.setPackedInt32Iterable(75, value); - } - - if (requestAccessor.hasFieldNumber(76)) { - const value = requestAccessor.getRepeatedInt64Iterable(76); - msg.accessor_.setPackedInt64Iterable(76, value); - } - - if (requestAccessor.hasFieldNumber(77)) { - const value = requestAccessor.getRepeatedUint32Iterable(77); - msg.accessor_.setPackedUint32Iterable(77, value); - } - - if (requestAccessor.hasFieldNumber(78)) { - const value = requestAccessor.getRepeatedUint64Iterable(78); - msg.accessor_.setPackedUint64Iterable(78, value); - } - - if (requestAccessor.hasFieldNumber(79)) { - const value = requestAccessor.getRepeatedSint32Iterable(79); - msg.accessor_.setPackedSint32Iterable(79, value); - } - - if (requestAccessor.hasFieldNumber(80)) { - const value = requestAccessor.getRepeatedSint64Iterable(80); - msg.accessor_.setPackedSint64Iterable(80, value); - } - - if (requestAccessor.hasFieldNumber(81)) { - const value = requestAccessor.getRepeatedFixed32Iterable(81); - msg.accessor_.setPackedFixed32Iterable(81, value); - } - - if (requestAccessor.hasFieldNumber(82)) { - const value = requestAccessor.getRepeatedFixed64Iterable(82); - msg.accessor_.setPackedFixed64Iterable(82, value); - } - - if (requestAccessor.hasFieldNumber(83)) { - const value = requestAccessor.getRepeatedSfixed32Iterable(83); - msg.accessor_.setPackedSfixed32Iterable(83, value); - } - - if (requestAccessor.hasFieldNumber(84)) { - const value = requestAccessor.getRepeatedSfixed64Iterable(84); - msg.accessor_.setPackedSfixed64Iterable(84, value); - } - - if (requestAccessor.hasFieldNumber(85)) { - const value = requestAccessor.getRepeatedFloatIterable(85); - msg.accessor_.setPackedFloatIterable(85, value); - } - - if (requestAccessor.hasFieldNumber(86)) { - const value = requestAccessor.getRepeatedDoubleIterable(86); - msg.accessor_.setPackedDoubleIterable(86, value); - } - - if (requestAccessor.hasFieldNumber(87)) { - const value = requestAccessor.getRepeatedBoolIterable(87); - msg.accessor_.setPackedBoolIterable(87, value); - } - - if (requestAccessor.hasFieldNumber(88)) { - const value = requestAccessor.getRepeatedInt32Iterable(88); - msg.accessor_.setPackedInt32Iterable(88, value); - } - return msg; - } - - /** - * Serializes into binary data. - * @return {!ArrayBuffer} - */ - serialize() { - return this.accessor_.serialize(); - } -} - -exports = TestAllTypesProto2; diff --git a/js/experimental/runtime/kernel/conformance/test_all_types_proto3.js b/js/experimental/runtime/kernel/conformance/test_all_types_proto3.js deleted file mode 100644 index c68d370f1..000000000 --- a/js/experimental/runtime/kernel/conformance/test_all_types_proto3.js +++ /dev/null @@ -1,310 +0,0 @@ -/** - * @fileoverview Handwritten code of TestAllTypesProto3. - */ -goog.module('proto.conformance.TestAllTypesProto3'); - -const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const Kernel = goog.require('protobuf.runtime.Kernel'); - -/** - * Handwritten code of conformance.TestAllTypesProto3. - * Check google/protobuf/test_messages_proto3.proto for more details. - * @implements {InternalMessage} - * @final - */ -class TestAllTypesProto3 { - /** - * @param {!Kernel=} accessor - * @private - */ - constructor(accessor = Kernel.createEmpty()) { - /** @private @const {!Kernel} */ - this.accessor_ = accessor; - } - - /** - * @override - * @package - * @return {!Kernel} - */ - internalGetKernel() { - return this.accessor_; - } - - /** - * Create a request instance with the given bytes data. - * If we directly use the accessor created by the binary decoding, the - * Kernel instance will only copy the same data over for encoding. By - * explicitly fetching data from the previous accessor and setting all fields - * into a new accessor, we will actually test encoding/decoding for the binary - * format. - * @param {!ArrayBuffer} bytes - * @return {!TestAllTypesProto3} - */ - static deserialize(bytes) { - const msg = new TestAllTypesProto3(); - const requestAccessor = Kernel.fromArrayBuffer(bytes); - - if (requestAccessor.hasFieldNumber(1)) { - const value = requestAccessor.getInt32WithDefault(1); - msg.accessor_.setInt32(1, value); - } - - if (requestAccessor.hasFieldNumber(2)) { - const value = requestAccessor.getInt64WithDefault(2); - msg.accessor_.setInt64(2, value); - } - - if (requestAccessor.hasFieldNumber(3)) { - const value = requestAccessor.getUint32WithDefault(3); - msg.accessor_.setUint32(3, value); - } - - if (requestAccessor.hasFieldNumber(4)) { - const value = requestAccessor.getUint64WithDefault(4); - msg.accessor_.setUint64(4, value); - } - - if (requestAccessor.hasFieldNumber(5)) { - const value = requestAccessor.getSint32WithDefault(5); - msg.accessor_.setSint32(5, value); - } - - if (requestAccessor.hasFieldNumber(6)) { - const value = requestAccessor.getSint64WithDefault(6); - msg.accessor_.setSint64(6, value); - } - - if (requestAccessor.hasFieldNumber(7)) { - const value = requestAccessor.getFixed32WithDefault(7); - msg.accessor_.setFixed32(7, value); - } - - if (requestAccessor.hasFieldNumber(8)) { - const value = requestAccessor.getFixed64WithDefault(8); - msg.accessor_.setFixed64(8, value); - } - - if (requestAccessor.hasFieldNumber(9)) { - const value = requestAccessor.getSfixed32WithDefault(9); - msg.accessor_.setSfixed32(9, value); - } - - if (requestAccessor.hasFieldNumber(10)) { - const value = requestAccessor.getSfixed64WithDefault(10); - msg.accessor_.setSfixed64(10, value); - } - - if (requestAccessor.hasFieldNumber(11)) { - const value = requestAccessor.getFloatWithDefault(11); - msg.accessor_.setFloat(11, value); - } - - if (requestAccessor.hasFieldNumber(12)) { - const value = requestAccessor.getDoubleWithDefault(12); - msg.accessor_.setDouble(12, value); - } - - if (requestAccessor.hasFieldNumber(13)) { - const value = requestAccessor.getBoolWithDefault(13); - msg.accessor_.setBool(13, value); - } - - if (requestAccessor.hasFieldNumber(14)) { - const value = requestAccessor.getStringWithDefault(14); - msg.accessor_.setString(14, value); - } - - if (requestAccessor.hasFieldNumber(15)) { - const value = requestAccessor.getBytesWithDefault(15); - msg.accessor_.setBytes(15, value); - } - - if (requestAccessor.hasFieldNumber(18)) { - const value = requestAccessor.getMessage( - 18, (accessor) => new TestAllTypesProto3(accessor)); - msg.accessor_.setMessage(18, value); - } - - if (requestAccessor.hasFieldNumber(21)) { - // Unknown enum is not checked here, because even if an enum is unknown, - // it should be kept during encoding. For the purpose of wire format test, - // we can simplify the implementation by treating it as an int32 field, - // which has the same semantic except for the unknown value checking. - const value = requestAccessor.getInt32WithDefault(21); - msg.accessor_.setInt32(21, value); - } - - if (requestAccessor.hasFieldNumber(31)) { - const value = requestAccessor.getRepeatedInt32Iterable(31); - msg.accessor_.setPackedInt32Iterable(31, value); - } - - if (requestAccessor.hasFieldNumber(32)) { - const value = requestAccessor.getRepeatedInt64Iterable(32); - msg.accessor_.setPackedInt64Iterable(32, value); - } - - if (requestAccessor.hasFieldNumber(33)) { - const value = requestAccessor.getRepeatedUint32Iterable(33); - msg.accessor_.setPackedUint32Iterable(33, value); - } - - if (requestAccessor.hasFieldNumber(34)) { - const value = requestAccessor.getRepeatedUint64Iterable(34); - msg.accessor_.setPackedUint64Iterable(34, value); - } - - if (requestAccessor.hasFieldNumber(35)) { - const value = requestAccessor.getRepeatedSint32Iterable(35); - msg.accessor_.setPackedSint32Iterable(35, value); - } - - if (requestAccessor.hasFieldNumber(36)) { - const value = requestAccessor.getRepeatedSint64Iterable(36); - msg.accessor_.setPackedSint64Iterable(36, value); - } - - if (requestAccessor.hasFieldNumber(37)) { - const value = requestAccessor.getRepeatedFixed32Iterable(37); - msg.accessor_.setPackedFixed32Iterable(37, value); - } - - if (requestAccessor.hasFieldNumber(38)) { - const value = requestAccessor.getRepeatedFixed64Iterable(38); - msg.accessor_.setPackedFixed64Iterable(38, value); - } - - if (requestAccessor.hasFieldNumber(39)) { - const value = requestAccessor.getRepeatedSfixed32Iterable(39); - msg.accessor_.setPackedSfixed32Iterable(39, value); - } - - if (requestAccessor.hasFieldNumber(40)) { - const value = requestAccessor.getRepeatedSfixed64Iterable(40); - msg.accessor_.setPackedSfixed64Iterable(40, value); - } - - if (requestAccessor.hasFieldNumber(41)) { - const value = requestAccessor.getRepeatedFloatIterable(41); - msg.accessor_.setPackedFloatIterable(41, value); - } - - if (requestAccessor.hasFieldNumber(42)) { - const value = requestAccessor.getRepeatedDoubleIterable(42); - msg.accessor_.setPackedDoubleIterable(42, value); - } - - if (requestAccessor.hasFieldNumber(43)) { - const value = requestAccessor.getRepeatedBoolIterable(43); - msg.accessor_.setPackedBoolIterable(43, value); - } - - if (requestAccessor.hasFieldNumber(44)) { - const value = requestAccessor.getRepeatedStringIterable(44); - msg.accessor_.setRepeatedStringIterable(44, value); - } - - if (requestAccessor.hasFieldNumber(45)) { - const value = requestAccessor.getRepeatedBytesIterable(45); - msg.accessor_.setRepeatedBytesIterable(45, value); - } - - if (requestAccessor.hasFieldNumber(48)) { - const value = requestAccessor.getRepeatedMessageIterable( - 48, (accessor) => new TestAllTypesProto3(accessor)); - msg.accessor_.setRepeatedMessageIterable(48, value); - } - - if (requestAccessor.hasFieldNumber(51)) { - // Unknown enum is not checked here, because even if an enum is unknown, - // it should be kept during encoding. For the purpose of wire format test, - // we can simplify the implementation by treating it as an int32 field, - // which has the same semantic except for the unknown value checking. - const value = requestAccessor.getRepeatedInt32Iterable(51); - msg.accessor_.setPackedInt32Iterable(51, value); - } - - if (requestAccessor.hasFieldNumber(89)) { - const value = requestAccessor.getRepeatedInt32Iterable(89); - msg.accessor_.setUnpackedInt32Iterable(89, value); - } - - if (requestAccessor.hasFieldNumber(90)) { - const value = requestAccessor.getRepeatedInt64Iterable(90); - msg.accessor_.setUnpackedInt64Iterable(90, value); - } - - if (requestAccessor.hasFieldNumber(91)) { - const value = requestAccessor.getRepeatedUint32Iterable(91); - msg.accessor_.setUnpackedUint32Iterable(91, value); - } - - if (requestAccessor.hasFieldNumber(92)) { - const value = requestAccessor.getRepeatedUint64Iterable(92); - msg.accessor_.setUnpackedUint64Iterable(92, value); - } - - if (requestAccessor.hasFieldNumber(93)) { - const value = requestAccessor.getRepeatedSint32Iterable(93); - msg.accessor_.setUnpackedSint32Iterable(93, value); - } - - if (requestAccessor.hasFieldNumber(94)) { - const value = requestAccessor.getRepeatedSint64Iterable(94); - msg.accessor_.setUnpackedSint64Iterable(94, value); - } - - if (requestAccessor.hasFieldNumber(95)) { - const value = requestAccessor.getRepeatedFixed32Iterable(95); - msg.accessor_.setUnpackedFixed32Iterable(95, value); - } - - if (requestAccessor.hasFieldNumber(96)) { - const value = requestAccessor.getRepeatedFixed64Iterable(96); - msg.accessor_.setUnpackedFixed64Iterable(96, value); - } - - if (requestAccessor.hasFieldNumber(97)) { - const value = requestAccessor.getRepeatedSfixed32Iterable(97); - msg.accessor_.setUnpackedSfixed32Iterable(97, value); - } - - if (requestAccessor.hasFieldNumber(98)) { - const value = requestAccessor.getRepeatedSfixed64Iterable(98); - msg.accessor_.setUnpackedSfixed64Iterable(98, value); - } - - if (requestAccessor.hasFieldNumber(99)) { - const value = requestAccessor.getRepeatedFloatIterable(99); - msg.accessor_.setUnpackedFloatIterable(99, value); - } - - if (requestAccessor.hasFieldNumber(100)) { - const value = requestAccessor.getRepeatedDoubleIterable(100); - msg.accessor_.setUnpackedDoubleIterable(100, value); - } - - if (requestAccessor.hasFieldNumber(101)) { - const value = requestAccessor.getRepeatedBoolIterable(101); - msg.accessor_.setUnpackedBoolIterable(101, value); - } - - if (requestAccessor.hasFieldNumber(102)) { - const value = requestAccessor.getRepeatedInt32Iterable(102); - msg.accessor_.setUnpackedInt32Iterable(102, value); - } - - return msg; - } - - /** - * Serializes into binary data. - * @return {!ArrayBuffer} - */ - serialize() { - return this.accessor_.serialize(); - } -} - -exports = TestAllTypesProto3; diff --git a/js/experimental/runtime/kernel/conformance/wire_format.js b/js/experimental/runtime/kernel/conformance/wire_format.js deleted file mode 100644 index 636e827bc..000000000 --- a/js/experimental/runtime/kernel/conformance/wire_format.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @fileoverview Handwritten code of WireFormat. - */ -goog.module('proto.conformance.WireFormat'); - -/** - * @enum {number} - */ -const WireFormat = { - UNSPECIFIED: 0, - PROTOBUF: 1, - JSON: 2, - TEXT_FORMAT: 4, -}; - -exports = WireFormat; diff --git a/js/experimental/runtime/kernel/double_test_pairs.js b/js/experimental/runtime/kernel/double_test_pairs.js deleted file mode 100644 index 86e1f2608..000000000 --- a/js/experimental/runtime/kernel/double_test_pairs.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @fileoverview Test data for double encoding and decoding. - */ -goog.module('protobuf.binary.doubleTestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of double values and their bit representation. - * This is used to test encoding and decoding from the protobuf wire format. - * @return {!Array<{name: string, doubleValue:number, bufferDecoder: - * !BufferDecoder}>} - */ -function getDoublePairs() { - const doublePairs = [ - { - name: 'zero', - doubleValue: 0, - bufferDecoder: - createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) - }, - { - name: 'minus zero', - doubleValue: -0, - bufferDecoder: - createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80) - }, - { - name: 'one', - doubleValue: 1, - bufferDecoder: - createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F) - }, - { - name: 'minus one', - doubleValue: -1, - bufferDecoder: - createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF) - }, - - { - name: 'PI', - doubleValue: Math.PI, - bufferDecoder: - createBufferDecoder(0x18, 0x2D, 0x44, 0x54, 0xFB, 0x21, 0x09, 0x40) - - }, - { - name: 'max value', - doubleValue: Number.MAX_VALUE, - bufferDecoder: - createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F) - }, - { - name: 'min value', - doubleValue: Number.MIN_VALUE, - bufferDecoder: - createBufferDecoder(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) - }, - { - name: 'Infinity', - doubleValue: Infinity, - bufferDecoder: - createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F) - }, - { - name: 'minus Infinity', - doubleValue: -Infinity, - bufferDecoder: - createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF) - }, - { - name: 'Number.MAX_SAFE_INTEGER', - doubleValue: Number.MAX_SAFE_INTEGER, - bufferDecoder: - createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x43) - }, - { - name: 'Number.MIN_SAFE_INTEGER', - doubleValue: Number.MIN_SAFE_INTEGER, - bufferDecoder: - createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xC3) - }, - ]; - return [...doublePairs]; -} - -exports = {getDoublePairs}; diff --git a/js/experimental/runtime/kernel/field.js b/js/experimental/runtime/kernel/field.js deleted file mode 100644 index 46d69997b..000000000 --- a/js/experimental/runtime/kernel/field.js +++ /dev/null @@ -1,196 +0,0 @@ -/** - * @fileoverview Contains classes that hold data for a protobuf field. - */ - -goog.module('protobuf.binary.field'); - -const WireType = goog.requireType('protobuf.binary.WireType'); -const Writer = goog.requireType('protobuf.binary.Writer'); -const {checkDefAndNotNull, checkState} = goog.require('protobuf.internal.checks'); - -/** - * Number of bits taken to represent a wire type. - * @const {number} - */ -const WIRE_TYPE_LENGTH_BITS = 3; - -/** @const {number} */ -const WIRE_TYPE_EXTRACTOR = (1 << WIRE_TYPE_LENGTH_BITS) - 1; - -/** - * An IndexEntry consists of the wire type and the position of a field in the - * binary data. The wire type and the position are encoded into a single number - * to save memory, which can be decoded using Field.getWireType() and - * Field.getStartIndex() methods. - * @typedef {number} - */ -let IndexEntry; - -/** - * An entry containing the index into the binary data and/or the corresponding - * cached JS object(s) for a field. - * @template T - * @final - * @package - */ -class Field { - /** - * Creates a field and inserts the wireType and position of the first - * occurrence of a field. - * @param {!WireType} wireType - * @param {number} startIndex - * @return {!Field} - */ - static fromFirstIndexEntry(wireType, startIndex) { - return new Field([Field.encodeIndexEntry(wireType, startIndex)]); - } - - /** - * @param {T} decodedValue The cached JS object decoded from the binary data. - * @param {function(!Writer, number, T):void|undefined} encoder Write function - * to encode the cache into binary bytes. - * @return {!Field} - * @template T - */ - static fromDecodedValue(decodedValue, encoder) { - return new Field(null, decodedValue, encoder); - } - - /** - * @param {!WireType} wireType - * @param {number} startIndex - * @return {!IndexEntry} - */ - static encodeIndexEntry(wireType, startIndex) { - return startIndex << WIRE_TYPE_LENGTH_BITS | wireType; - } - - /** - * @param {!IndexEntry} indexEntry - * @return {!WireType} - */ - static getWireType(indexEntry) { - return /** @type {!WireType} */ (indexEntry & WIRE_TYPE_EXTRACTOR); - } - - /** - * @param {!IndexEntry} indexEntry - * @return {number} - */ - static getStartIndex(indexEntry) { - return indexEntry >> WIRE_TYPE_LENGTH_BITS; - } - - /** - * @param {?Array} indexArray - * @param {T=} decodedValue - * @param {function(!Writer, number, T):void=} encoder - * @private - */ - constructor(indexArray, decodedValue = undefined, encoder = undefined) { - checkState( - !!indexArray || decodedValue !== undefined, - 'At least one of indexArray and decodedValue must be set'); - - /** @private {?Array} */ - this.indexArray_ = indexArray; - /** @private {T|undefined} */ - this.decodedValue_ = decodedValue; - // TODO: Consider storing an enum to represent encoder - /** @private {function(!Writer, number, T)|undefined} */ - this.encoder_ = encoder; - } - - /** - * Adds a new IndexEntry. - * @param {!WireType} wireType - * @param {number} startIndex - */ - addIndexEntry(wireType, startIndex) { - checkDefAndNotNull(this.indexArray_) - .push(Field.encodeIndexEntry(wireType, startIndex)); - } - - /** - * Returns the array of IndexEntry. - * @return {?Array} - */ - getIndexArray() { - return this.indexArray_; - } - - /** - * Caches the decoded value and sets the write function to encode cache into - * binary bytes. - * @param {T} decodedValue - * @param {function(!Writer, number, T):void|undefined} encoder - */ - setCache(decodedValue, encoder) { - this.decodedValue_ = decodedValue; - this.encoder_ = encoder; - this.maybeRemoveIndexArray_(); - } - - /** - * If the decoded value has been set. - * @return {boolean} - */ - hasDecodedValue() { - return this.decodedValue_ !== undefined; - } - - /** - * Returns the cached decoded value. The value needs to be set when this - * method is called. - * @return {T} - */ - getDecodedValue() { - // Makes sure that the decoded value in the cache has already been set. This - // prevents callers from doing `if (field.getDecodedValue()) {...}` to check - // if a value exist in the cache, because the check might return false even - // if the cache has a valid value set (e.g. 0 or empty string). - checkState(this.decodedValue_ !== undefined); - return this.decodedValue_; - } - - /** - * Returns the write function to encode cache into binary bytes. - * @return {function(!Writer, number, T)|undefined} - */ - getEncoder() { - return this.encoder_; - } - - /** - * Returns a copy of the field, containing the original index entries and a - * shallow copy of the cache. - * @return {!Field} - */ - shallowCopy() { - // Repeated fields are arrays in the cache. - // We have to copy the array to make sure that modifications to a repeated - // field (e.g. add) are not seen on a cloned accessor. - const copiedCache = this.hasDecodedValue() ? - (Array.isArray(this.getDecodedValue()) ? [...this.getDecodedValue()] : - this.getDecodedValue()) : - undefined; - return new Field(this.getIndexArray(), copiedCache, this.getEncoder()); - } - - /** - * @private - */ - maybeRemoveIndexArray_() { - checkState( - this.encoder_ === undefined || this.decodedValue_ !== undefined, - 'Encoder exists but decoded value doesn\'t'); - if (this.encoder_ !== undefined) { - this.indexArray_ = null; - } - } -} - -exports = { - IndexEntry, - Field, -}; diff --git a/js/experimental/runtime/kernel/fixed32_test_pairs.js b/js/experimental/runtime/kernel/fixed32_test_pairs.js deleted file mode 100644 index 1bbab3eb0..000000000 --- a/js/experimental/runtime/kernel/fixed32_test_pairs.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @fileoverview Test data for float encoding and decoding. - */ -goog.module('protobuf.binary.fixed32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of float values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, intValue: number, bufferDecoder: - * !BufferDecoder}>} - */ -function getFixed32Pairs() { - const fixed32Pairs = [ - { - name: 'zero', - intValue: 0, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x00), - }, - { - name: 'one ', - intValue: 1, - bufferDecoder: createBufferDecoder(0x01, 0x00, 0x00, 0x00) - }, - { - name: 'max int 2^32 -1', - intValue: Math.pow(2, 32) - 1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF) - }, - ]; - return [...fixed32Pairs]; -} - -exports = {getFixed32Pairs}; diff --git a/js/experimental/runtime/kernel/float_test_pairs.js b/js/experimental/runtime/kernel/float_test_pairs.js deleted file mode 100644 index 816bdc2c9..000000000 --- a/js/experimental/runtime/kernel/float_test_pairs.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @fileoverview Test data for float encoding and decoding. - */ -goog.module('protobuf.binary.floatTestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of float values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, floatValue:number, bufferDecoder: - * !BufferDecoder}>} - */ -function getFloatPairs() { - const floatPairs = [ - { - name: 'zero', - floatValue: 0, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x00), - }, - { - name: 'minus zero', - floatValue: -0, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x80) - }, - { - name: 'one ', - floatValue: 1, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0x3F) - }, - { - name: 'minus one', - floatValue: -1, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0xBF) - }, - { - name: 'two', - floatValue: 2, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x40) - }, - { - name: 'max float32', - floatValue: Math.pow(2, 127) * (2 - 1 / Math.pow(2, 23)), - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0x7F, 0x7F) - }, - - { - name: 'min float32', - floatValue: 1 / Math.pow(2, 127 - 1), - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0x00) - }, - - { - name: 'Infinity', - floatValue: Infinity, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0x7F) - }, - { - name: 'minus Infinity', - floatValue: -Infinity, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0xFF) - }, - { - name: '1.5', - floatValue: 1.5, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0xC0, 0x3F) - }, - { - name: '1.6', - floatValue: 1.6, - bufferDecoder: createBufferDecoder(0xCD, 0xCC, 0xCC, 0x3F) - }, - ]; - return [...floatPairs]; -} - -exports = {getFloatPairs}; diff --git a/js/experimental/runtime/kernel/indexer.js b/js/experimental/runtime/kernel/indexer.js deleted file mode 100644 index 205a34e44..000000000 --- a/js/experimental/runtime/kernel/indexer.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @fileoverview Utilities to index a binary proto by fieldnumbers without - * relying on strutural proto information. - */ -goog.module('protobuf.binary.indexer'); - -const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const WireType = goog.require('protobuf.binary.WireType'); -const {Field} = goog.require('protobuf.binary.field'); -const {checkCriticalState} = goog.require('protobuf.internal.checks'); -const {skipField, tagToFieldNumber, tagToWireType} = goog.require('protobuf.binary.tag'); - -/** - * Appends a new entry in the index array for the given field number. - * @param {!BinaryStorage} storage - * @param {number} fieldNumber - * @param {!WireType} wireType - * @param {number} startIndex - */ -function addIndexEntry(storage, fieldNumber, wireType, startIndex) { - const field = storage.get(fieldNumber); - if (field !== undefined) { - field.addIndexEntry(wireType, startIndex); - } else { - storage.set(fieldNumber, Field.fromFirstIndexEntry(wireType, startIndex)); - } -} - -/** - * Creates an index of field locations in a given binary protobuf. - * @param {!BufferDecoder} bufferDecoder - * @param {number|undefined} pivot - * @return {!BinaryStorage} - * @package - */ -function buildIndex(bufferDecoder, pivot) { - bufferDecoder.setCursor(bufferDecoder.startIndex()); - - const storage = new BinaryStorage(pivot); - while (bufferDecoder.hasNext()) { - const tag = bufferDecoder.getUnsignedVarint32(); - const wireType = tagToWireType(tag); - const fieldNumber = tagToFieldNumber(tag); - checkCriticalState(fieldNumber > 0, `Invalid field number ${fieldNumber}`); - addIndexEntry(storage, fieldNumber, wireType, bufferDecoder.cursor()); - skipField(bufferDecoder, wireType, fieldNumber); - } - return storage; -} - -exports = { - buildIndex, - tagToWireType, -}; diff --git a/js/experimental/runtime/kernel/indexer_test.js b/js/experimental/runtime/kernel/indexer_test.js deleted file mode 100644 index ffb880799..000000000 --- a/js/experimental/runtime/kernel/indexer_test.js +++ /dev/null @@ -1,334 +0,0 @@ -/** - * @fileoverview Tests for indexer.js. - */ -goog.module('protobuf.binary.IndexerTest'); - -goog.setTestOnly(); - -// Note to the reader: -// Since the index behavior changes with the checking level some of the tests -// in this file have to know which checking level is enabled to make correct -// assertions. -// Test are run in all checking levels. -const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const WireType = goog.require('protobuf.binary.WireType'); -const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); -const {Field, IndexEntry} = goog.require('protobuf.binary.field'); -const {buildIndex} = goog.require('protobuf.binary.indexer'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * Returns the number of fields stored. - * - * @param {!BinaryStorage} storage - * @return {number} - */ -function getStorageSize(storage) { - let size = 0; - storage.forEach(() => void size++); - return size; -} - -/** - * @type {number} - */ -const PIVOT = 1; - -/** - * Asserts a single IndexEntry at a given field number. - * @param {!BinaryStorage} storage - * @param {number} fieldNumber - * @param {...!IndexEntry} expectedEntries - */ -function assertStorageEntries(storage, fieldNumber, ...expectedEntries) { - expect(getStorageSize(storage)).toBe(1); - - const entryArray = storage.get(fieldNumber).getIndexArray(); - expect(entryArray).not.toBeUndefined(); - expect(entryArray.length).toBe(expectedEntries.length); - - for (let i = 0; i < entryArray.length; i++) { - const storageEntry = entryArray[i]; - const expectedEntry = expectedEntries[i]; - - expect(storageEntry).toBe(expectedEntry); - } -} - -describe('Indexer does', () => { - it('return empty storage for empty array', () => { - const storage = buildIndex(createBufferDecoder(), PIVOT); - expect(storage).not.toBeNull(); - expect(getStorageSize(storage)).toBe(0); - }); - - it('throw for null array', () => { - expect( - () => buildIndex( - /** @type {!BufferDecoder} */ (/** @type {*} */ (null)), PIVOT)) - .toThrow(); - }); - - it('fail for invalid wire type (6)', () => { - expect(() => buildIndex(createBufferDecoder(0x0E, 0x01), PIVOT)) - .toThrowError('Unexpected wire type: 6'); - }); - - it('fail for invalid wire type (7)', () => { - expect(() => buildIndex(createBufferDecoder(0x0F, 0x01), PIVOT)) - .toThrowError('Unexpected wire type: 7'); - }); - - it('index varint', () => { - const data = createBufferDecoder(0x08, 0x01, 0x08, 0x01); - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 1), - Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 3)); - }); - - it('index varint with two bytes field number', () => { - const data = createBufferDecoder(0xF8, 0x01, 0x01); - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 31, - Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 2)); - }); - - it('fail for varints that are longer than 10 bytes', () => { - const data = createBufferDecoder( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00); - if (CHECK_CRITICAL_STATE) { - expect(() => buildIndex(data, PIVOT)) - .toThrowError('Index out of bounds: index: 12 size: 11'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 1)); - } - }); - - it('fail for varints with no data', () => { - const data = createBufferDecoder(0x08); - expect(() => buildIndex(data, PIVOT)).toThrow(); - }); - - it('index fixed64', () => { - const data = createBufferDecoder( - /* first= */ 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - /* second= */ 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08); - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 1), - Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 10)); - }); - - it('fail for fixed64 data missing in input', () => { - const data = - createBufferDecoder(0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07); - if (CHECK_CRITICAL_STATE) { - expect(() => buildIndex(data, PIVOT)) - .toThrowError('Index out of bounds: index: 9 size: 8'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 1)); - } - }); - - it('fail for fixed64 tag that has no data after it', () => { - if (CHECK_CRITICAL_STATE) { - const data = createBufferDecoder(0x09); - expect(() => buildIndex(data, PIVOT)) - .toThrowError('Index out of bounds: index: 9 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const data = createBufferDecoder(0x09); - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 1)); - } - }); - - it('index delimited', () => { - const data = createBufferDecoder( - /* first= */ 0x0A, 0x02, 0x00, 0x01, /* second= */ 0x0A, 0x02, 0x00, - 0x01); - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.DELIMITED, /* startIndex= */ 1), - Field.encodeIndexEntry(WireType.DELIMITED, /* startIndex= */ 5)); - }); - - it('fail for length deliimted field data missing in input', () => { - const data = createBufferDecoder(0x0A, 0x04, 0x00, 0x01); - if (CHECK_CRITICAL_STATE) { - expect(() => buildIndex(data, PIVOT)) - .toThrowError('Index out of bounds: index: 6 size: 4'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.DELIMITED, /* startIndex= */ 1)); - } - }); - - it('fail for delimited tag that has no data after it', () => { - const data = createBufferDecoder(0x0A); - expect(() => buildIndex(data, PIVOT)).toThrow(); - }); - - it('index fixed32', () => { - const data = createBufferDecoder( - /* first= */ 0x0D, 0x01, 0x02, 0x03, 0x04, /* second= */ 0x0D, 0x01, - 0x02, 0x03, 0x04); - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 1), - Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 6)); - }); - - it('fail for fixed32 data missing in input', () => { - const data = createBufferDecoder(0x0D, 0x01, 0x02, 0x03); - - if (CHECK_CRITICAL_STATE) { - expect(() => buildIndex(data, PIVOT)) - .toThrowError('Index out of bounds: index: 5 size: 4'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 1)); - } - }); - - it('fail for fixed32 tag that has no data after it', () => { - if (CHECK_CRITICAL_STATE) { - const data = createBufferDecoder(0x0D); - expect(() => buildIndex(data, PIVOT)) - .toThrowError('Index out of bounds: index: 5 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const data = createBufferDecoder(0x0D); - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 1)); - } - }); - - it('index group', () => { - const data = createBufferDecoder( - /* first= */ 0x0B, 0x08, 0x01, 0x0C, /* second= */ 0x0B, 0x08, 0x01, - 0x0C); - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1), - Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 5)); - }); - - it('index group and skips inner group', () => { - const data = - createBufferDecoder(0x0B, 0x0B, 0x08, 0x01, 0x0C, 0x08, 0x01, 0x0C); - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1)); - }); - - it('fail on unmatched stop group', () => { - const data = createBufferDecoder(0x0C, 0x01); - expect(() => buildIndex(data, PIVOT)) - .toThrowError('Unexpected wire type: 4'); - }); - - it('fail for groups without matching stop group', () => { - const data = createBufferDecoder(0x0B, 0x08, 0x01, 0x1C); - if (CHECK_CRITICAL_STATE) { - expect(() => buildIndex(data, PIVOT)) - .toThrowError('Expected stop group for fieldnumber 1 not found.'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1)); - } - }); - - it('fail for groups without stop group', () => { - const data = createBufferDecoder(0x0B, 0x08, 0x01); - if (CHECK_CRITICAL_STATE) { - expect(() => buildIndex(data, PIVOT)).toThrowError('No end group found.'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1)); - } - }); - - it('fail for group tag that has no data after it', () => { - const data = createBufferDecoder(0x0B); - if (CHECK_CRITICAL_STATE) { - expect(() => buildIndex(data, PIVOT)).toThrowError('No end group found.'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const storage = buildIndex(data, PIVOT); - assertStorageEntries( - storage, /* fieldNumber= */ 1, - Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1)); - } - }); - - it('index too large tag', () => { - const data = createBufferDecoder(0xF8, 0xFF, 0xFF, 0xFF, 0xFF); - expect(() => buildIndex(data, PIVOT)).toThrow(); - }); - - it('fail for varint tag that has no data after it', () => { - const data = createBufferDecoder(0x08); - expect(() => buildIndex(data, PIVOT)).toThrow(); - }); -}); diff --git a/js/experimental/runtime/kernel/int32_test_pairs.js b/js/experimental/runtime/kernel/int32_test_pairs.js deleted file mode 100644 index ef4f2e9c1..000000000 --- a/js/experimental/runtime/kernel/int32_test_pairs.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @fileoverview Test data for int32 encoding and decoding. - */ -goog.module('protobuf.binary.int32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of float values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, intValue:number, bufferDecoder: - * !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>} - */ -function getInt32Pairs() { - const int32Pairs = [ - { - name: 'zero', - intValue: 0, - bufferDecoder: createBufferDecoder(0x00), - }, - { - name: 'one ', - intValue: 1, - bufferDecoder: createBufferDecoder(0x01), - }, - { - name: 'minus one', - intValue: -1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F), - // The writer will encode this with 64 bits, see below - skip_writer: true, - }, - { - name: 'minus one (64bits)', - intValue: -1, - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01), - }, - { - name: 'max signed int 2^31 - 1', - intValue: Math.pow(2, 31) - 1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x07), - - }, - { - name: 'min signed int -2^31', - intValue: -Math.pow(2, 31), - bufferDecoder: createBufferDecoder(0x80, 0x80, 0x80, 0x80, 0x08), - // The writer will encode this with 64 bits, see below - skip_writer: true, - }, - { - name: 'value min signed int -2^31 (64 bit)', - intValue: -Math.pow(2, 31), - bufferDecoder: createBufferDecoder( - 0x80, 0x80, 0x80, 0x80, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x01), - }, - { - name: 'errors out for 11 bytes', - intValue: -1, - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - error: true, - skip_writer: true, - }, - ]; - return [...int32Pairs]; -} - -exports = {getInt32Pairs}; diff --git a/js/experimental/runtime/kernel/int64_test_pairs.js b/js/experimental/runtime/kernel/int64_test_pairs.js deleted file mode 100644 index 19ef46ba4..000000000 --- a/js/experimental/runtime/kernel/int64_test_pairs.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @fileoverview Test data for int64 encoding and decoding. - */ -goog.module('protobuf.binary.int64TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const Int64 = goog.require('protobuf.Int64'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of float values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, longValue: !Int64, bufferDecoder: - * !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>} - */ -function getInt64Pairs() { - const int64Pairs = [ - { - name: 'zero', - longValue: Int64.fromInt(0), - bufferDecoder: createBufferDecoder(0x00), - }, - { - name: 'one ', - longValue: Int64.fromInt(1), - bufferDecoder: createBufferDecoder(0x01), - }, - { - name: 'minus one', - longValue: Int64.fromInt(-1), - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01), - }, - { - name: 'max signed int 2^63 - 1', - longValue: Int64.fromBits(0xFFFFFFFF, 0x7FFFFFFF), - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F), - - }, - { - name: 'value min signed int -2^63 (64 bit)', - longValue: Int64.fromBits(0xFFFFFFFF, 0xFFFFFFFF), - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01), - }, - { - name: 'errors out for 11 bytes', - longValue: Int64.fromInt(-1), - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - error: true, - skip_writer: true, - }, - ]; - return [...int64Pairs]; -} - -exports = {getInt64Pairs}; diff --git a/js/experimental/runtime/kernel/internal_message.js b/js/experimental/runtime/kernel/internal_message.js deleted file mode 100644 index 1ba9ed983..000000000 --- a/js/experimental/runtime/kernel/internal_message.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @fileoverview Internal interface for messages implemented with the binary - * kernel. - */ -goog.module('protobuf.binary.InternalMessage'); - -const Kernel = goog.requireType('protobuf.runtime.Kernel'); - -/** - * Interface that needs to be implemented by messages implemented with the - * binary kernel. This is an internal only interface and should be used only by - * the classes in binary kernel. - * - * @interface - */ -class InternalMessage { - /** - * @package - * @return {!Kernel} - */ - internalGetKernel() {} -} - -exports = InternalMessage; \ No newline at end of file diff --git a/js/experimental/runtime/kernel/kernel.js b/js/experimental/runtime/kernel/kernel.js deleted file mode 100644 index bb2608398..000000000 --- a/js/experimental/runtime/kernel/kernel.js +++ /dev/null @@ -1,4122 +0,0 @@ -/** - * @fileoverview Kernel is a class to provide type-checked accessing - * (read/write bool/int32/string/...) on binary data. - * - * When creating the Kernel with the binary data, there is no deep - * decoding done (which requires full type information). The deep decoding is - * deferred until the first time accessing (when accessors can provide - * full type information). - * - * Because accessors can be statically analyzed and stripped, unlike eager - * binary decoding (which requires the full type information of all defined - * fields), Kernel will only need the full type information of used - * fields. - */ -goog.module('protobuf.runtime.Kernel'); - -const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const ByteString = goog.require('protobuf.ByteString'); -const Int64 = goog.require('protobuf.Int64'); -const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const Storage = goog.require('protobuf.runtime.Storage'); -const WireType = goog.require('protobuf.binary.WireType'); -const Writer = goog.require('protobuf.binary.Writer'); -const reader = goog.require('protobuf.binary.reader'); -const {CHECK_TYPE, checkCriticalElementIndex, checkCriticalState, checkCriticalType, checkCriticalTypeBool, checkCriticalTypeBoolArray, checkCriticalTypeByteString, checkCriticalTypeByteStringArray, checkCriticalTypeDouble, checkCriticalTypeDoubleArray, checkCriticalTypeFloat, checkCriticalTypeFloatIterable, checkCriticalTypeMessageArray, checkCriticalTypeSignedInt32, checkCriticalTypeSignedInt32Array, checkCriticalTypeSignedInt64, checkCriticalTypeSignedInt64Array, checkCriticalTypeString, checkCriticalTypeStringArray, checkCriticalTypeUnsignedInt32, checkCriticalTypeUnsignedInt32Array, checkDefAndNotNull, checkElementIndex, checkFieldNumber, checkFunctionExists, checkState, checkTypeDouble, checkTypeFloat, checkTypeSignedInt32, checkTypeSignedInt64, checkTypeUnsignedInt32} = goog.require('protobuf.internal.checks'); -const {Field, IndexEntry} = goog.require('protobuf.binary.field'); -const {buildIndex} = goog.require('protobuf.binary.indexer'); -const {createTag, get32BitVarintLength, getTagLength} = goog.require('protobuf.binary.tag'); - - -/** - * Validates the index entry has the correct wire type. - * @param {!IndexEntry} indexEntry - * @param {!WireType} expected - */ -function validateWireType(indexEntry, expected) { - const wireType = Field.getWireType(indexEntry); - checkCriticalState( - wireType === expected, - `Expected wire type: ${expected} but found: ${wireType}`); -} - -/** - * Checks if the object implements InternalMessage interface. - * @param {?} obj - * @return {!InternalMessage} - */ -function checkIsInternalMessage(obj) { - const message = /** @type {!InternalMessage} */ (obj); - checkFunctionExists(message.internalGetKernel); - return message; -} - -/** - * Checks if the instanceCreator returns an instance that implements the - * InternalMessage interface. - * @param {function(!Kernel):T} instanceCreator - * @template T - */ -function checkInstanceCreator(instanceCreator) { - if (CHECK_TYPE) { - const emptyMessage = instanceCreator(Kernel.createEmpty()); - checkFunctionExists(emptyMessage.internalGetKernel); - } -} - -/** - * Reads the last entry of the index array using the given read function. - * This is used to implement parsing singular primitive fields. - * @param {!Array} indexArray - * @param {!BufferDecoder} bufferDecoder - * @param {function(!BufferDecoder, number):T} readFunc - * @param {!WireType} wireType - * @return {T} - * @template T - */ -function readOptional(indexArray, bufferDecoder, readFunc, wireType) { - const index = indexArray.length - 1; - checkElementIndex(index, indexArray.length); - const indexEntry = indexArray[index]; - validateWireType(indexEntry, wireType); - return readFunc(bufferDecoder, Field.getStartIndex(indexEntry)); -} - -/** - * Converts all entries of the index array to the template type using given read - * methods and return an Iterable containing those converted values. - * Primitive repeated fields may be encoded either packed or unpacked. Thus, two - * read methods are needed for those two cases. - * This is used to implement parsing repeated primitive fields. - * @param {!Array} indexArray - * @param {!BufferDecoder} bufferDecoder - * @param {function(!BufferDecoder, number):T} singularReadFunc - * @param {function(!BufferDecoder, number):!Array} packedReadFunc - * @param {!WireType} expectedWireType - * @return {!Array} - * @template T - */ -function readRepeatedPrimitive( - indexArray, bufferDecoder, singularReadFunc, packedReadFunc, - expectedWireType) { - // Fast path when there is a single packed entry. - if (indexArray.length === 1 && - Field.getWireType(indexArray[0]) === WireType.DELIMITED) { - return packedReadFunc(bufferDecoder, Field.getStartIndex(indexArray[0])); - } - - let /** !Array */ result = []; - for (const indexEntry of indexArray) { - const wireType = Field.getWireType(indexEntry); - const startIndex = Field.getStartIndex(indexEntry); - if (wireType === WireType.DELIMITED) { - result = result.concat(packedReadFunc(bufferDecoder, startIndex)); - } else { - validateWireType(indexEntry, expectedWireType); - result.push(singularReadFunc(bufferDecoder, startIndex)); - } - } - return result; -} - -/** - * Converts all entries of the index array to the template type using the given - * read function and return an Array containing those converted values. This is - * used to implement parsing repeated non-primitive fields. - * @param {!Array} indexArray - * @param {!BufferDecoder} bufferDecoder - * @param {function(!BufferDecoder, number):T} singularReadFunc - * @return {!Array} - * @template T - */ -function readRepeatedNonPrimitive(indexArray, bufferDecoder, singularReadFunc) { - const result = new Array(indexArray.length); - for (let i = 0; i < indexArray.length; i++) { - validateWireType(indexArray[i], WireType.DELIMITED); - result[i] = - singularReadFunc(bufferDecoder, Field.getStartIndex(indexArray[i])); - } - return result; -} - -/** - * Converts all entries of the index array to the template type using the given - * read function and return an Array containing those converted values. This is - * used to implement parsing repeated non-primitive fields. - * @param {!Array} indexArray - * @param {!BufferDecoder} bufferDecoder - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {!Array} - * @template T - */ -function readRepeatedGroup( - indexArray, bufferDecoder, fieldNumber, instanceCreator, pivot) { - const result = new Array(indexArray.length); - for (let i = 0; i < indexArray.length; i++) { - result[i] = doReadGroup( - bufferDecoder, indexArray[i], fieldNumber, instanceCreator, pivot); - } - return result; -} - -/** - * Creates a new bytes array to contain all data of a submessage. - * When there are multiple entries, merge them together. - * @param {!Array} indexArray - * @param {!BufferDecoder} bufferDecoder - * @return {!BufferDecoder} - */ -function mergeMessageArrays(indexArray, bufferDecoder) { - const dataArrays = indexArray.map( - indexEntry => - reader.readDelimited(bufferDecoder, Field.getStartIndex(indexEntry))); - return BufferDecoder.merge(dataArrays); -} - -/** - * @param {!Array} indexArray - * @param {!BufferDecoder} bufferDecoder - * @param {number=} pivot - * @return {!Kernel} - */ -function readAccessor(indexArray, bufferDecoder, pivot = undefined) { - checkState(indexArray.length > 0); - let accessorBuffer; - // Faster access for one member. - if (indexArray.length === 1) { - const indexEntry = indexArray[0]; - validateWireType(indexEntry, WireType.DELIMITED); - accessorBuffer = - reader.readDelimited(bufferDecoder, Field.getStartIndex(indexEntry)); - } else { - indexArray.forEach(indexEntry => { - validateWireType(indexEntry, WireType.DELIMITED); - }); - accessorBuffer = mergeMessageArrays(indexArray, bufferDecoder); - } - return Kernel.fromBufferDecoder_(accessorBuffer, pivot); -} - -/** - * Merges all index entries of the index array using the given read function. - * This is used to implement parsing singular message fields. - * @param {!Array} indexArray - * @param {!BufferDecoder} bufferDecoder - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ -function readMessage(indexArray, bufferDecoder, instanceCreator, pivot) { - checkInstanceCreator(instanceCreator); - const accessor = readAccessor(indexArray, bufferDecoder, pivot); - return instanceCreator(accessor); -} - -/** - * Merges all index entries of the index array using the given read function. - * This is used to implement parsing singular group fields. - * @param {!Array} indexArray - * @param {!BufferDecoder} bufferDecoder - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ -function readGroup( - indexArray, bufferDecoder, fieldNumber, instanceCreator, pivot) { - checkInstanceCreator(instanceCreator); - checkState(indexArray.length > 0); - return doReadGroup( - bufferDecoder, indexArray[indexArray.length - 1], fieldNumber, - instanceCreator, pivot); -} - -/** - * Merges all index entries of the index array using the given read function. - * This is used to implement parsing singular message fields. - * @param {!BufferDecoder} bufferDecoder - * @param {!IndexEntry} indexEntry - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ -function doReadGroup( - bufferDecoder, indexEntry, fieldNumber, instanceCreator, pivot) { - validateWireType(indexEntry, WireType.START_GROUP); - const fieldStartIndex = Field.getStartIndex(indexEntry); - const tag = createTag(WireType.START_GROUP, fieldNumber); - const groupTagLength = get32BitVarintLength(tag); - const groupLength = getTagLength( - bufferDecoder, fieldStartIndex, WireType.START_GROUP, fieldNumber); - const accessorBuffer = bufferDecoder.subBufferDecoder( - fieldStartIndex, groupLength - groupTagLength); - const kernel = Kernel.fromBufferDecoder_(accessorBuffer, pivot); - return instanceCreator(kernel); -} - -/** - * @param {!Writer} writer - * @param {number} fieldNumber - * @param {?InternalMessage} value - */ -function writeMessage(writer, fieldNumber, value) { - writer.writeDelimited( - fieldNumber, checkDefAndNotNull(value).internalGetKernel().serialize()); -} - -/** - * @param {!Writer} writer - * @param {number} fieldNumber - * @param {?InternalMessage} value - */ -function writeGroup(writer, fieldNumber, value) { - const kernel = checkDefAndNotNull(value).internalGetKernel(); - writer.writeStartGroup(fieldNumber); - kernel.serializeToWriter(writer); - writer.writeEndGroup(fieldNumber); -} - -/** - * Writes the array of Messages into the writer for the given field number. - * @param {!Writer} writer - * @param {number} fieldNumber - * @param {!Iterable} values - */ -function writeRepeatedMessage(writer, fieldNumber, values) { - for (const value of values) { - writeMessage(writer, fieldNumber, value); - } -} - -/** - * Writes the array of Messages into the writer for the given field number. - * @param {!Writer} writer - * @param {number} fieldNumber - * @param {!Array} values - */ -function writeRepeatedGroup(writer, fieldNumber, values) { - for (const value of values) { - writeGroup(writer, fieldNumber, value); - } -} - -/** - * Array.from has a weird type definition in google3/javascript/externs/es6.js - * and wants the mapping function accept strings. - * @const {function((string|number)): number} - */ -const fround = /** @type {function((string|number)): number} */ (Math.fround); - -/** - * Wraps an array and exposes it as an Iterable. This class is used to provide - * immutable access of the array to the caller. - * @implements {Iterable} - * @template T - */ -class ArrayIterable { - /** - * @param {!Array} array - */ - constructor(array) { - /** @private @const {!Array} */ - this.array_ = array; - } - - /** @return {!Iterator} */ - [Symbol.iterator]() { - return this.array_[Symbol.iterator](); - } -} - -/** - * Accesses protobuf fields on binary format data. Binary data is decoded lazily - * at the first access. - * @final - */ -class Kernel { - /** - * Create a Kernel for the given binary bytes. - * The bytes array is kept by the Kernel. DON'T MODIFY IT. - * @param {!ArrayBuffer} arrayBuffer Binary bytes. - * @param {number=} pivot Fields with a field number no greater than the pivot - * value will be stored in an array for fast access. Other fields will be - * stored in a map. A higher pivot value can improve runtime performance - * at the expense of requiring more memory. It's recommended to set the - * value to the max field number of the message unless the field numbers - * are too sparse. If the value is not set, a default value specified in - * storage.js will be used. - * @return {!Kernel} - */ - static fromArrayBuffer(arrayBuffer, pivot = undefined) { - const bufferDecoder = BufferDecoder.fromArrayBuffer(arrayBuffer); - return Kernel.fromBufferDecoder_(bufferDecoder, pivot); - } - - /** - * Creates an empty Kernel. - * @param {number=} pivot Fields with a field number no greater than the pivot - * value will be stored in an array for fast access. Other fields will be - * stored in a map. A higher pivot value can improve runtime performance - * at the expense of requiring more memory. It's recommended to set the - * value to the max field number of the message unless the field numbers - * are too sparse. If the value is not set, a default value specified in - * storage.js will be used. - * @return {!Kernel} - */ - static createEmpty(pivot = undefined) { - return new Kernel(/* bufferDecoder= */ null, new BinaryStorage(pivot)); - } - - /** - * Create a Kernel for the given binary bytes. - * The bytes array is kept by the Kernel. DON'T MODIFY IT. - * @param {!BufferDecoder} bufferDecoder Binary bytes. - * @param {number|undefined} pivot - * @return {!Kernel} - * @private - */ - static fromBufferDecoder_(bufferDecoder, pivot) { - return new Kernel(bufferDecoder, buildIndex(bufferDecoder, pivot)); - } - - /** - * @param {?BufferDecoder} bufferDecoder Binary bytes. Accessor treats the - * bytes as immutable and will never attempt to write to it. - * @param {!Storage} fields A map of field number to Field. The - * IndexEntry in each Field needs to be populated with the location of the - * field in the binary data. - * @private - */ - constructor(bufferDecoder, fields) { - /** @private @const {?BufferDecoder} */ - this.bufferDecoder_ = bufferDecoder; - /** @private @const {!Storage} */ - this.fields_ = fields; - } - - /** - * Creates a shallow copy of the accessor. - * @return {!Kernel} - */ - shallowCopy() { - return new Kernel(this.bufferDecoder_, this.fields_.shallowCopy()); - } - - /** - * See definition of the pivot parameter on the fromArrayBuffer() method. - * @return {number} - */ - getPivot() { - return this.fields_.getPivot(); - } - - /** - * Clears the field for the given field number. - * @param {number} fieldNumber - */ - clearField(fieldNumber) { - this.fields_.delete(fieldNumber); - } - - /** - * Returns data for a field specified by the given field number. Also cache - * the data if it doesn't already exist in the cache. When no data is - * available, return the given default value. - * @param {number} fieldNumber - * @param {?T} defaultValue - * @param {function(!Array, !BufferDecoder):T} readFunc - * @param {function(!Writer, number, T)=} encoder - * @return {T} - * @template T - * @private - */ - getFieldWithDefault_( - fieldNumber, defaultValue, readFunc, encoder = undefined) { - checkFieldNumber(fieldNumber); - - const field = this.fields_.get(fieldNumber); - if (field === undefined) { - return defaultValue; - } - - if (field.hasDecodedValue()) { - checkState(!encoder || !!field.getEncoder()); - return field.getDecodedValue(); - } - - const parsed = readFunc( - checkDefAndNotNull(field.getIndexArray()), - checkDefAndNotNull(this.bufferDecoder_)); - field.setCache(parsed, encoder); - return parsed; - } - - /** - * Sets data for a singular field specified by the given field number. - * @param {number} fieldNumber - * @param {T} value - * @param {function(!Writer, number, T)} encoder - * @return {T} - * @template T - * @private - */ - setField_(fieldNumber, value, encoder) { - checkFieldNumber(fieldNumber); - this.fields_.set(fieldNumber, Field.fromDecodedValue(value, encoder)); - } - - /** - * Serializes internal contents to binary format bytes array to the - * given writer. - * @param {!Writer} writer - * @package - */ - serializeToWriter(writer) { - // If we use for...of here, jscompiler returns an array of both types for - // fieldNumber and field without specifying which type is for - // field, which prevents us to use fieldNumber. Thus, we use - // forEach here. - this.fields_.forEach((field, fieldNumber) => { - // If encoder doesn't exist, there is no need to encode the value - // because the data in the index is still valid. - if (field.getEncoder() !== undefined) { - const encoder = checkDefAndNotNull(field.getEncoder()); - encoder(writer, fieldNumber, field.getDecodedValue()); - return; - } - - const indexArr = field.getIndexArray(); - if (indexArr) { - for (const indexEntry of indexArr) { - writer.writeTag(fieldNumber, Field.getWireType(indexEntry)); - writer.writeBufferDecoder( - checkDefAndNotNull(this.bufferDecoder_), - Field.getStartIndex(indexEntry), Field.getWireType(indexEntry), - fieldNumber); - } - } - }); - } - - /** - * Serializes internal contents to binary format bytes array. - * @return {!ArrayBuffer} - */ - serialize() { - const writer = new Writer(); - this.serializeToWriter(writer); - return writer.getAndResetResultBuffer(); - } - - /** - * Returns whether data exists at the given field number. - * @param {number} fieldNumber - * @return {boolean} - */ - hasFieldNumber(fieldNumber) { - checkFieldNumber(fieldNumber); - const field = this.fields_.get(fieldNumber); - - if (field === undefined) { - return false; - } - - if (field.getIndexArray() !== null) { - return true; - } - - if (Array.isArray(field.getDecodedValue())) { - // For repeated fields, existence is decided by number of elements. - return (/** !Array */ (field.getDecodedValue())).length > 0; - } - return true; - } - - /*************************************************************************** - * OPTIONAL GETTER METHODS - ***************************************************************************/ - - /** - * Returns data as boolean for the given field number. - * If no default is given, use false as the default. - * @param {number} fieldNumber - * @param {boolean=} defaultValue - * @return {boolean} - */ - getBoolWithDefault(fieldNumber, defaultValue = false) { - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => - readOptional(indexArray, bytes, reader.readBool, WireType.VARINT)); - } - - /** - * Returns data as a ByteString for the given field number. - * If no default is given, use false as the default. - * @param {number} fieldNumber - * @param {!ByteString=} defaultValue - * @return {!ByteString} - */ - getBytesWithDefault(fieldNumber, defaultValue = ByteString.EMPTY) { - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readBytes, WireType.DELIMITED)); - } - - /** - * Returns a double for the given field number. - * If no default is given uses zero as the default. - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getDoubleWithDefault(fieldNumber, defaultValue = 0) { - checkTypeDouble(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readDouble, WireType.FIXED64)); - } - - /** - * Returns a fixed32 for the given field number. - * If no default is given zero as the default. - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getFixed32WithDefault(fieldNumber, defaultValue = 0) { - checkTypeUnsignedInt32(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readFixed32, WireType.FIXED32)); - } - - /** - * Returns a fixed64 for the given field number. - * Note: Since g.m.Long does not support unsigned int64 values we are going - * the Java route here for now and simply output the number as a signed int64. - * Users can get to individual bits by themselves. - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getFixed64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - return this.getSfixed64WithDefault(fieldNumber, defaultValue); - } - - /** - * Returns a float for the given field number. - * If no default is given zero as the default. - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getFloatWithDefault(fieldNumber, defaultValue = 0) { - checkTypeFloat(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readFloat, WireType.FIXED32)); - } - - /** - * Returns a int32 for the given field number. - * If no default is given zero as the default. - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getInt32WithDefault(fieldNumber, defaultValue = 0) { - checkTypeSignedInt32(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => - readOptional(indexArray, bytes, reader.readInt32, WireType.VARINT)); - } - - /** - * Returns a int64 for the given field number. - * If no default is given zero as the default. - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getInt64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - checkTypeSignedInt64(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => - readOptional(indexArray, bytes, reader.readInt64, WireType.VARINT)); - } - - /** - * Returns a sfixed32 for the given field number. - * If no default is given zero as the default. - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getSfixed32WithDefault(fieldNumber, defaultValue = 0) { - checkTypeSignedInt32(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readSfixed32, WireType.FIXED32)); - } - - /** - * Returns a sfixed64 for the given field number. - * If no default is given zero as the default. - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getSfixed64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - checkTypeSignedInt64(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readSfixed64, WireType.FIXED64)); - } - - /** - * Returns a sint32 for the given field number. - * If no default is given zero as the default. - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getSint32WithDefault(fieldNumber, defaultValue = 0) { - checkTypeSignedInt32(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readSint32, WireType.VARINT)); - } - - /** - * Returns a sint64 for the given field number. - * If no default is given zero as the default. - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getSint64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - checkTypeSignedInt64(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readSint64, WireType.VARINT)); - } - - /** - * Returns a string for the given field number. - * If no default is given uses empty string as the default. - * @param {number} fieldNumber - * @param {string=} defaultValue - * @return {string} - */ - getStringWithDefault(fieldNumber, defaultValue = '') { - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readString, WireType.DELIMITED)); - } - - /** - * Returns a uint32 for the given field number. - * If no default is given zero as the default. - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getUint32WithDefault(fieldNumber, defaultValue = 0) { - checkTypeUnsignedInt32(defaultValue); - return this.getFieldWithDefault_( - fieldNumber, defaultValue, - (indexArray, bytes) => readOptional( - indexArray, bytes, reader.readUint32, WireType.VARINT)); - } - - /** - * Returns a uint64 for the given field number. - * Note: Since g.m.Long does not support unsigned int64 values we are going - * the Java route here for now and simply output the number as a signed int64. - * Users can get to individual bits by themselves. - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getUint64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - return this.getInt64WithDefault(fieldNumber, defaultValue); - } - - /** - * Returns data as a mutable proto Message for the given field number. - * If no value has been set, return null. - * If hasFieldNumber(fieldNumber) == false before calling, it remains false. - * - * This method should not be used along with getMessage, since calling - * getMessageOrNull after getMessage will not register the encoder. - * - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {?T} - * @template T - */ - getMessageOrNull(fieldNumber, instanceCreator, pivot = undefined) { - return this.getFieldWithDefault_( - fieldNumber, null, - (indexArray, bytes) => - readMessage(indexArray, bytes, instanceCreator, pivot), - writeMessage); - } - - /** - * Returns data as a mutable proto Message for the given field number. - * If no value has been set, return null. - * If hasFieldNumber(fieldNumber) == false before calling, it remains false. - * - * This method should not be used along with getMessage, since calling - * getMessageOrNull after getMessage will not register the encoder. - * - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {?T} - * @template T - */ - getGroupOrNull(fieldNumber, instanceCreator, pivot = undefined) { - return this.getFieldWithDefault_( - fieldNumber, null, - (indexArray, bytes) => - readGroup(indexArray, bytes, fieldNumber, instanceCreator, pivot), - writeGroup); - } - - /** - * Returns data as a mutable proto Message for the given field number. - * If no value has been set previously, creates and attaches an instance. - * Postcondition: hasFieldNumber(fieldNumber) == true. - * - * This method should not be used along with getMessage, since calling - * getMessageAttach after getMessage will not register the encoder. - * - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ - getMessageAttach(fieldNumber, instanceCreator, pivot = undefined) { - checkInstanceCreator(instanceCreator); - let instance = this.getMessageOrNull(fieldNumber, instanceCreator, pivot); - if (!instance) { - instance = instanceCreator(Kernel.createEmpty()); - this.setField_(fieldNumber, instance, writeMessage); - } - return instance; - } - - /** - * Returns data as a mutable proto Message for the given field number. - * If no value has been set previously, creates and attaches an instance. - * Postcondition: hasFieldNumber(fieldNumber) == true. - * - * This method should not be used along with getMessage, since calling - * getMessageAttach after getMessage will not register the encoder. - * - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ - getGroupAttach(fieldNumber, instanceCreator, pivot = undefined) { - checkInstanceCreator(instanceCreator); - let instance = this.getGroupOrNull(fieldNumber, instanceCreator, pivot); - if (!instance) { - instance = instanceCreator(Kernel.createEmpty()); - this.setField_(fieldNumber, instance, writeGroup); - } - return instance; - } - - /** - * Returns data as a proto Message for the given field number. - * If no value has been set, return a default instance. - * This default instance is guaranteed to be the same instance, unless this - * field is cleared. - * Does not register the encoder, so changes made to the returned - * sub-message will not be included when serializing the parent message. - * Use getMessageAttach() if the resulting sub-message should be mutable. - * - * This method should not be used along with getMessageOrNull or - * getMessageAttach, since these methods register the encoder. - * - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ - getMessage(fieldNumber, instanceCreator, pivot = undefined) { - checkInstanceCreator(instanceCreator); - const message = this.getFieldWithDefault_( - fieldNumber, null, - (indexArray, bytes) => - readMessage(indexArray, bytes, instanceCreator, pivot)); - // Returns an empty message as the default value if the field doesn't exist. - // We don't pass the default value to getFieldWithDefault_ to reduce object - // allocation. - return message === null ? instanceCreator(Kernel.createEmpty()) : message; - } - - /** - * Returns data as a proto Message for the given field number. - * If no value has been set, return a default instance. - * This default instance is guaranteed to be the same instance, unless this - * field is cleared. - * Does not register the encoder, so changes made to the returned - * sub-message will not be included when serializing the parent message. - * Use getMessageAttach() if the resulting sub-message should be mutable. - * - * This method should not be used along with getMessageOrNull or - * getMessageAttach, since these methods register the encoder. - * - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ - getGroup(fieldNumber, instanceCreator, pivot = undefined) { - checkInstanceCreator(instanceCreator); - const message = this.getFieldWithDefault_( - fieldNumber, null, - (indexArray, bytes) => - readGroup(indexArray, bytes, fieldNumber, instanceCreator, pivot)); - // Returns an empty message as the default value if the field doesn't exist. - // We don't pass the default value to getFieldWithDefault_ to reduce object - // allocation. - return message === null ? instanceCreator(Kernel.createEmpty()) : message; - } - - /** - * Returns the accessor for the given singular message, or returns null if - * it hasn't been set. - * @param {number} fieldNumber - * @param {number=} pivot - * @return {?Kernel} - */ - getMessageAccessorOrNull(fieldNumber, pivot = undefined) { - checkFieldNumber(fieldNumber); - const field = this.fields_.get(fieldNumber); - if (field === undefined) { - return null; - } - - if (field.hasDecodedValue()) { - return checkIsInternalMessage(field.getDecodedValue()) - .internalGetKernel(); - } else { - return readAccessor( - checkDefAndNotNull(field.getIndexArray()), - checkDefAndNotNull(this.bufferDecoder_), pivot); - } - } - - /*************************************************************************** - * REPEATED GETTER METHODS - ***************************************************************************/ - - /* Bool */ - - /** - * Returns an Array instance containing boolean values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedBoolArray_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readBool, reader.readPackedBool, - WireType.VARINT)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {boolean} - */ - getRepeatedBoolElement(fieldNumber, index) { - const array = this.getRepeatedBoolArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing boolean values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedBoolIterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedBoolArray_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedBoolArray_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedBoolSize(fieldNumber) { - return this.getRepeatedBoolArray_(fieldNumber).length; - } - - /* Double */ - - /** - * Returns an Array instance containing double values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedDoubleArray_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readDouble, reader.readPackedDouble, - WireType.FIXED64)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedDoubleElement(fieldNumber, index) { - const array = this.getRepeatedDoubleArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing double values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedDoubleIterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedDoubleArray_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedDoubleArray_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedDoubleSize(fieldNumber) { - return this.getRepeatedDoubleArray_(fieldNumber).length; - } - - /* Fixed32 */ - - /** - * Returns an Array instance containing fixed32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedFixed32Array_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readFixed32, reader.readPackedFixed32, - WireType.FIXED32)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedFixed32Element(fieldNumber, index) { - const array = this.getRepeatedFixed32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing fixed32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedFixed32Iterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedFixed32Array_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedFixed32Array_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedFixed32Size(fieldNumber) { - return this.getRepeatedFixed32Array_(fieldNumber).length; - } - - /* Fixed64 */ - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedFixed64Element(fieldNumber, index) { - return this.getRepeatedSfixed64Element(fieldNumber, index); - } - - /** - * Returns an Iterable instance containing fixed64 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedFixed64Iterable(fieldNumber) { - return this.getRepeatedSfixed64Iterable(fieldNumber); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedFixed64Size(fieldNumber) { - return this.getRepeatedSfixed64Size(fieldNumber); - } - - /* Float */ - - /** - * Returns an Array instance containing float values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedFloatArray_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readFloat, reader.readPackedFloat, - WireType.FIXED32)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedFloatElement(fieldNumber, index) { - const array = this.getRepeatedFloatArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing float values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedFloatIterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedFloatArray_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedFloatArray_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedFloatSize(fieldNumber) { - return this.getRepeatedFloatArray_(fieldNumber).length; - } - - /* Int32 */ - - /** - * Returns an Array instance containing int32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedInt32Array_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readInt32, reader.readPackedInt32, - WireType.VARINT)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedInt32Element(fieldNumber, index) { - const array = this.getRepeatedInt32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing int32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedInt32Iterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedInt32Array_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedInt32Array_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedInt32Size(fieldNumber) { - return this.getRepeatedInt32Array_(fieldNumber).length; - } - - /* Int64 */ - - /** - * Returns an Array instance containing int64 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedInt64Array_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readInt64, reader.readPackedInt64, - WireType.VARINT)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedInt64Element(fieldNumber, index) { - const array = this.getRepeatedInt64Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing int64 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedInt64Iterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedInt64Array_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedInt64Array_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedInt64Size(fieldNumber) { - return this.getRepeatedInt64Array_(fieldNumber).length; - } - - /* Sfixed32 */ - - /** - * Returns an Array instance containing sfixed32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedSfixed32Array_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readSfixed32, reader.readPackedSfixed32, - WireType.FIXED32)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedSfixed32Element(fieldNumber, index) { - const array = this.getRepeatedSfixed32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing sfixed32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedSfixed32Iterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedSfixed32Array_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedSfixed32Array_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedSfixed32Size(fieldNumber) { - return this.getRepeatedSfixed32Array_(fieldNumber).length; - } - - /* Sfixed64 */ - - /** - * Returns an Array instance containing sfixed64 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedSfixed64Array_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readSfixed64, reader.readPackedSfixed64, - WireType.FIXED64)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedSfixed64Element(fieldNumber, index) { - const array = this.getRepeatedSfixed64Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing sfixed64 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedSfixed64Iterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedSfixed64Array_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedSfixed64Array_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedSfixed64Size(fieldNumber) { - return this.getRepeatedSfixed64Array_(fieldNumber).length; - } - - /* Sint32 */ - - /** - * Returns an Array instance containing sint32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedSint32Array_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readSint32, reader.readPackedSint32, - WireType.VARINT)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedSint32Element(fieldNumber, index) { - const array = this.getRepeatedSint32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing sint32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedSint32Iterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedSint32Array_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedSint32Array_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedSint32Size(fieldNumber) { - return this.getRepeatedSint32Array_(fieldNumber).length; - } - - /* Sint64 */ - - /** - * Returns an Array instance containing sint64 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedSint64Array_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readSint64, reader.readPackedSint64, - WireType.VARINT)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedSint64Element(fieldNumber, index) { - const array = this.getRepeatedSint64Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing sint64 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedSint64Iterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedSint64Array_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedSint64Array_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedSint64Size(fieldNumber) { - return this.getRepeatedSint64Array_(fieldNumber).length; - } - - /* Uint32 */ - - /** - * Returns an Array instance containing uint32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedUint32Array_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => readRepeatedPrimitive( - indexArray, bytes, reader.readUint32, reader.readPackedUint32, - WireType.VARINT)); - } - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedUint32Element(fieldNumber, index) { - const array = this.getRepeatedUint32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing uint32 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedUint32Iterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedUint32Array_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedUint32Array_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedUint32Size(fieldNumber) { - return this.getRepeatedUint32Array_(fieldNumber).length; - } - - /* Uint64 */ - - /** - * Returns the element at index for the given field number. - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedUint64Element(fieldNumber, index) { - return this.getRepeatedInt64Element(fieldNumber, index); - } - - /** - * Returns an Iterable instance containing uint64 values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedUint64Iterable(fieldNumber) { - return this.getRepeatedInt64Iterable(fieldNumber); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedUint64Size(fieldNumber) { - return this.getRepeatedInt64Size(fieldNumber); - } - - /* Bytes */ - - /** - * Returns an array instance containing bytes values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedBytesArray_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bytes) => - readRepeatedNonPrimitive(indexArray, bytes, reader.readBytes)); - } - - /** - * Returns the element at index for the given field number as a bytes. - * @param {number} fieldNumber - * @param {number} index - * @return {!ByteString} - */ - getRepeatedBytesElement(fieldNumber, index) { - const array = this.getRepeatedBytesArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing bytes values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedBytesIterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedBytesArray_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedBytesArray_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedBytesSize(fieldNumber) { - return this.getRepeatedBytesArray_(fieldNumber).length; - } - - /* String */ - - /** - * Returns an array instance containing string values for the given field - * number. - * @param {number} fieldNumber - * @return {!Array} - * @private - */ - getRepeatedStringArray_(fieldNumber) { - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], - (indexArray, bufferDecoder) => readRepeatedNonPrimitive( - indexArray, bufferDecoder, reader.readString)); - } - - /** - * Returns the element at index for the given field number as a string. - * @param {number} fieldNumber - * @param {number} index - * @return {string} - */ - getRepeatedStringElement(fieldNumber, index) { - const array = this.getRepeatedStringArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing string values for the given field - * number. - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedStringIterable(fieldNumber) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedStringArray_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable(this.getRepeatedStringArray_(fieldNumber)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedStringSize(fieldNumber) { - return this.getRepeatedStringArray_(fieldNumber).length; - } - - /* Message */ - - /** - * Returns an Array instance containing boolean values for the given field - * number. - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number|undefined} pivot - * @return {!Array} - * @template T - * @private - */ - getRepeatedMessageArray_(fieldNumber, instanceCreator, pivot) { - // This method can be shortened using getFieldWithDefault and - // getRepeatedNonPrimitive methods. But that will require creating and - // passing a reader closure every time getRepeatedMessageArray_ is called, - // which is expensive. - checkInstanceCreator(instanceCreator); - checkFieldNumber(fieldNumber); - - const field = this.fields_.get(fieldNumber); - if (field === undefined) { - return []; - } - - if (field.hasDecodedValue()) { - return field.getDecodedValue(); - } - - const indexArray = checkDefAndNotNull(field.getIndexArray()); - const result = new Array(indexArray.length); - for (let i = 0; i < indexArray.length; i++) { - validateWireType(indexArray[i], WireType.DELIMITED); - const subMessageBuffer = reader.readDelimited( - checkDefAndNotNull(this.bufferDecoder_), - Field.getStartIndex(indexArray[i])); - result[i] = - instanceCreator(Kernel.fromBufferDecoder_(subMessageBuffer, pivot)); - } - field.setCache(result, writeRepeatedMessage); - - return result; - } - - /** - * Returns the element at index for the given field number as a message. - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number} index - * @param {number=} pivot - * @return {T} - * @template T - */ - getRepeatedMessageElement( - fieldNumber, instanceCreator, index, pivot = undefined) { - const array = - this.getRepeatedMessageArray_(fieldNumber, instanceCreator, pivot); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing message values for the given field - * number. - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {!Iterable} - * @template T - */ - getRepeatedMessageIterable(fieldNumber, instanceCreator, pivot = undefined) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedMessageArray_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable( - this.getRepeatedMessageArray_(fieldNumber, instanceCreator, pivot)); - } - - /** - * Returns an Iterable instance containing message accessors for the given - * field number. - * @param {number} fieldNumber - * @param {number=} pivot - * @return {!Iterable} - */ - getRepeatedMessageAccessorIterable(fieldNumber, pivot = undefined) { - checkFieldNumber(fieldNumber); - - const field = this.fields_.get(fieldNumber); - if (!field) { - return []; - } - - if (field.hasDecodedValue()) { - return new ArrayIterable(field.getDecodedValue().map( - value => checkIsInternalMessage(value).internalGetKernel())); - } - - const readMessageFunc = (bufferDecoder, start) => Kernel.fromBufferDecoder_( - reader.readDelimited(bufferDecoder, start), pivot); - const array = readRepeatedNonPrimitive( - checkDefAndNotNull(field.getIndexArray()), - checkDefAndNotNull(this.bufferDecoder_), readMessageFunc); - return new ArrayIterable(array); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @return {number} - * @param {number=} pivot - * @template T - */ - getRepeatedMessageSize(fieldNumber, instanceCreator, pivot = undefined) { - return this.getRepeatedMessageArray_(fieldNumber, instanceCreator, pivot) - .length; - } - - /** - * Returns an Array instance containing boolean values for the given field - * number. - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number|undefined} pivot - * @return {!Array} - * @template T - * @private - */ - getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot) { - return this.getFieldWithDefault_( - fieldNumber, [], - (indexArray, bufferDecoder) => readRepeatedGroup( - indexArray, bufferDecoder, fieldNumber, instanceCreator, pivot), - writeRepeatedGroup); - } - - /** - * Returns the element at index for the given field number as a group. - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number} index - * @param {number=} pivot - * @return {T} - * @template T - */ - getRepeatedGroupElement( - fieldNumber, instanceCreator, index, pivot = undefined) { - const array = - this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot); - checkCriticalElementIndex(index, array.length); - return array[index]; - } - - /** - * Returns an Iterable instance containing group values for the given field - * number. - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {!Iterable} - * @template T - */ - getRepeatedGroupIterable(fieldNumber, instanceCreator, pivot = undefined) { - // Don't split this statement unless needed. JS compiler thinks - // getRepeatedMessageArray_ might have side effects and doesn't inline the - // call in the compiled code. See cl/293894484 for details. - return new ArrayIterable( - this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot)); - } - - /** - * Returns the size of the repeated field. - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @return {number} - * @param {number=} pivot - * @template T - */ - getRepeatedGroupSize(fieldNumber, instanceCreator, pivot = undefined) { - return this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot) - .length; - } - - /*************************************************************************** - * OPTIONAL SETTER METHODS - ***************************************************************************/ - - /** - * Sets a boolean value to the field with the given field number. - * @param {number} fieldNumber - * @param {boolean} value - */ - setBool(fieldNumber, value) { - checkCriticalTypeBool(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeBool(fieldNumber, value); - }); - } - - /** - * Sets a boolean value to the field with the given field number. - * @param {number} fieldNumber - * @param {!ByteString} value - */ - setBytes(fieldNumber, value) { - checkCriticalTypeByteString(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeBytes(fieldNumber, value); - }); - } - - /** - * Sets a double value to the field with the given field number. - * @param {number} fieldNumber - * @param {number} value - */ - setDouble(fieldNumber, value) { - checkCriticalTypeDouble(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeDouble(fieldNumber, value); - }); - } - - /** - * Sets a fixed32 value to the field with the given field number. - * @param {number} fieldNumber - * @param {number} value - */ - setFixed32(fieldNumber, value) { - checkCriticalTypeUnsignedInt32(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeFixed32(fieldNumber, value); - }); - } - - /** - * Sets a uint64 value to the field with the given field number.\ - * Note: Since g.m.Long does not support unsigned int64 values we are going - * the Java route here for now and simply output the number as a signed int64. - * Users can get to individual bits by themselves. - * @param {number} fieldNumber - * @param {!Int64} value - */ - setFixed64(fieldNumber, value) { - this.setSfixed64(fieldNumber, value); - } - - /** - * Sets a float value to the field with the given field number. - * @param {number} fieldNumber - * @param {number} value - */ - setFloat(fieldNumber, value) { - checkCriticalTypeFloat(value); - // Eagerly round to 32-bit precision so that reading back after set will - // yield the same value a reader will receive after serialization. - const floatValue = Math.fround(value); - this.setField_(fieldNumber, floatValue, (writer, fieldNumber, value) => { - writer.writeFloat(fieldNumber, value); - }); - } - - /** - * Sets a int32 value to the field with the given field number. - * @param {number} fieldNumber - * @param {number} value - */ - setInt32(fieldNumber, value) { - checkCriticalTypeSignedInt32(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeInt32(fieldNumber, value); - }); - } - - /** - * Sets a int64 value to the field with the given field number. - * @param {number} fieldNumber - * @param {!Int64} value - */ - setInt64(fieldNumber, value) { - checkCriticalTypeSignedInt64(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeInt64(fieldNumber, value); - }); - } - - /** - * Sets a sfixed32 value to the field with the given field number. - * @param {number} fieldNumber - * @param {number} value - */ - setSfixed32(fieldNumber, value) { - checkCriticalTypeSignedInt32(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeSfixed32(fieldNumber, value); - }); - } - - /** - * Sets a sfixed64 value to the field with the given field number. - * @param {number} fieldNumber - * @param {!Int64} value - */ - setSfixed64(fieldNumber, value) { - checkCriticalTypeSignedInt64(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeSfixed64(fieldNumber, value); - }); - } - - /** - * Sets a sint32 value to the field with the given field number. - * @param {number} fieldNumber - * @param {number} value - */ - setSint32(fieldNumber, value) { - checkCriticalTypeSignedInt32(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeSint32(fieldNumber, value); - }); - } - - /** - * Sets a sint64 value to the field with the given field number. - * @param {number} fieldNumber - * @param {!Int64} value - */ - setSint64(fieldNumber, value) { - checkCriticalTypeSignedInt64(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeSint64(fieldNumber, value); - }); - } - - /** - * Sets a boolean value to the field with the given field number. - * @param {number} fieldNumber - * @param {string} value - */ - setString(fieldNumber, value) { - checkCriticalTypeString(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeString(fieldNumber, value); - }); - } - - /** - * Sets a uint32 value to the field with the given field number. - * @param {number} fieldNumber - * @param {number} value - */ - setUint32(fieldNumber, value) { - checkCriticalTypeUnsignedInt32(value); - this.setField_(fieldNumber, value, (writer, fieldNumber, value) => { - writer.writeUint32(fieldNumber, value); - }); - } - - /** - * Sets a uint64 value to the field with the given field number.\ - * Note: Since g.m.Long does not support unsigned int64 values we are going - * the Java route here for now and simply output the number as a signed int64. - * Users can get to individual bits by themselves. - * @param {number} fieldNumber - * @param {!Int64} value - */ - setUint64(fieldNumber, value) { - this.setInt64(fieldNumber, value); - } - - /** - * Sets a proto Group to the field with the given field number. - * Instead of working with the Kernel inside of the message directly, we - * need the message instance to keep its reference equality for subsequent - * gettings. - * @param {number} fieldNumber - * @param {!InternalMessage} value - */ - setGroup(fieldNumber, value) { - checkCriticalType( - value !== null, 'Given value is not a message instance: null'); - this.setField_(fieldNumber, value, writeGroup); - } - - /** - * Sets a proto Message to the field with the given field number. - * Instead of working with the Kernel inside of the message directly, we - * need the message instance to keep its reference equality for subsequent - * gettings. - * @param {number} fieldNumber - * @param {!InternalMessage} value - */ - setMessage(fieldNumber, value) { - checkCriticalType( - value !== null, 'Given value is not a message instance: null'); - this.setField_(fieldNumber, value, writeMessage); - } - - /*************************************************************************** - * REPEATED SETTER METHODS - ***************************************************************************/ - - /* Bool */ - - /** - * Adds all boolean values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedBoolIterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedBoolArray_(fieldNumber), ...values]; - checkCriticalTypeBoolArray(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single boolean value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {boolean} value - */ - addPackedBoolElement(fieldNumber, value) { - this.addRepeatedBoolIterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedBool(fieldNumber, values); - }); - } - - /** - * Adds all boolean values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedBoolIterable(fieldNumber, values) { - this.addRepeatedBoolIterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedBool(fieldNumber, values); - }); - } - - /** - * Adds a single boolean value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {boolean} value - */ - addUnpackedBoolElement(fieldNumber, value) { - this.addRepeatedBoolIterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedBool(fieldNumber, values); - }); - } - - /** - * Adds all boolean values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedBoolIterable(fieldNumber, values) { - this.addRepeatedBoolIterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedBool(fieldNumber, values); - }); - } - - /** - * Sets a single boolean value into the field for the given field number at - * the given index. How these values are encoded depends on the given write - * function. - * @param {number} fieldNumber - * @param {number} index - * @param {boolean} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedBoolElement_(fieldNumber, index, value, encoder) { - checkCriticalTypeBool(value); - const array = this.getRepeatedBoolArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single boolean value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {boolean} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedBoolElement(fieldNumber, index, value) { - this.setRepeatedBoolElement_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedBool(fieldNumber, values); - }); - } - - /** - * Sets all boolean values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedBoolIterable(fieldNumber, values) { - const /** !Array */ array = Array.from(values); - checkCriticalTypeBoolArray(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedBool(fieldNumber, values); - }); - } - - /** - * Sets a single boolean value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {boolean} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedBoolElement(fieldNumber, index, value) { - this.setRepeatedBoolElement_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedBool(fieldNumber, values); - }); - } - - /** - * Sets all boolean values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedBoolIterable(fieldNumber, values) { - const /** !Array */ array = Array.from(values); - checkCriticalTypeBoolArray(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedBool(fieldNumber, values); - }); - } - - /* Double */ - - /** - * Adds all double values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedDoubleIterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedDoubleArray_(fieldNumber), ...values]; - checkCriticalTypeDoubleArray(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single double value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} value - */ - addPackedDoubleElement(fieldNumber, value) { - this.addRepeatedDoubleIterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedDouble(fieldNumber, values); - }); - } - - /** - * Adds all double values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedDoubleIterable(fieldNumber, values) { - this.addRepeatedDoubleIterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedDouble(fieldNumber, values); - }); - } - - /** - * Adds a single double value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedDoubleElement(fieldNumber, value) { - this.addRepeatedDoubleIterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedDouble(fieldNumber, values); - }); - } - - /** - * Adds all double values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedDoubleIterable(fieldNumber, values) { - this.addRepeatedDoubleIterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedDouble(fieldNumber, values); - }); - } - - /** - * Sets a single double value into the field for the given field number at the - * given index. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedDoubleElement_(fieldNumber, index, value, encoder) { - checkCriticalTypeDouble(value); - const array = this.getRepeatedDoubleArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single double value into the field for the given field number at the - * given index. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedDoubleElement(fieldNumber, index, value) { - this.setRepeatedDoubleElement_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedDouble(fieldNumber, values); - }); - } - - /** - * Sets all double values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedDoubleIterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeDoubleArray(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedDouble(fieldNumber, values); - }); - } - - /** - * Sets a single double value into the field for the given field number at the - * given index. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedDoubleElement(fieldNumber, index, value) { - this.setRepeatedDoubleElement_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedDouble(fieldNumber, values); - }); - } - - /** - * Sets all double values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedDoubleIterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeDoubleArray(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedDouble(fieldNumber, values); - }); - } - - /* Fixed32 */ - - /** - * Adds all fixed32 values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedFixed32Iterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedFixed32Array_(fieldNumber), ...values]; - checkCriticalTypeUnsignedInt32Array(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single fixed32 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} value - */ - addPackedFixed32Element(fieldNumber, value) { - this.addRepeatedFixed32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedFixed32(fieldNumber, values); - }); - } - - /** - * Adds all fixed32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedFixed32Iterable(fieldNumber, values) { - this.addRepeatedFixed32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedFixed32(fieldNumber, values); - }); - } - - /** - * Adds a single fixed32 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedFixed32Element(fieldNumber, value) { - this.addRepeatedFixed32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedFixed32(fieldNumber, values); - }); - } - - /** - * Adds all fixed32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedFixed32Iterable(fieldNumber, values) { - this.addRepeatedFixed32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedFixed32(fieldNumber, values); - }); - } - - /** - * Sets a single fixed32 value into the field for the given field number at - * the given index. How these values are encoded depends on the given write - * function. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedFixed32Element_(fieldNumber, index, value, encoder) { - checkCriticalTypeUnsignedInt32(value); - const array = this.getRepeatedFixed32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single fixed32 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedFixed32Element(fieldNumber, index, value) { - this.setRepeatedFixed32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedFixed32(fieldNumber, values); - }); - } - - /** - * Sets all fixed32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedFixed32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeUnsignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedFixed32(fieldNumber, values); - }); - } - - /** - * Sets a single fixed32 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedFixed32Element(fieldNumber, index, value) { - this.setRepeatedFixed32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedFixed32(fieldNumber, values); - }); - } - - /** - * Sets all fixed32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedFixed32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeUnsignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedFixed32(fieldNumber, values); - }); - } - - /* Fixed64 */ - - /** - * Adds a single fixed64 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedFixed64Element(fieldNumber, value) { - this.addPackedSfixed64Element(fieldNumber, value); - } - - /** - * Adds all fixed64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedFixed64Iterable(fieldNumber, values) { - this.addPackedSfixed64Iterable(fieldNumber, values); - } - - /** - * Adds a single fixed64 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedFixed64Element(fieldNumber, value) { - this.addUnpackedSfixed64Element(fieldNumber, value); - } - - /** - * Adds all fixed64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedFixed64Iterable(fieldNumber, values) { - this.addUnpackedSfixed64Iterable(fieldNumber, values); - } - - /** - * Sets a single fixed64 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedFixed64Element(fieldNumber, index, value) { - this.setPackedSfixed64Element(fieldNumber, index, value); - } - - /** - * Sets all fixed64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedFixed64Iterable(fieldNumber, values) { - this.setPackedSfixed64Iterable(fieldNumber, values); - } - - /** - * Sets a single fixed64 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedFixed64Element(fieldNumber, index, value) { - this.setUnpackedSfixed64Element(fieldNumber, index, value); - } - - /** - * Sets all fixed64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedFixed64Iterable(fieldNumber, values) { - this.setUnpackedSfixed64Iterable(fieldNumber, values); - } - - /* Float */ - - /** - * Adds all float values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedFloatIterable_(fieldNumber, values, encoder) { - checkCriticalTypeFloatIterable(values); - // Eagerly round to 32-bit precision so that reading back after set will - // yield the same value a reader will receive after serialization. - const floatValues = Array.from(values, fround); - const array = [...this.getRepeatedFloatArray_(fieldNumber), ...floatValues]; - checkCriticalTypeFloatIterable(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single float value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} value - */ - addPackedFloatElement(fieldNumber, value) { - this.addRepeatedFloatIterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedFloat(fieldNumber, values); - }); - } - - /** - * Adds all float values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedFloatIterable(fieldNumber, values) { - this.addRepeatedFloatIterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedFloat(fieldNumber, values); - }); - } - - /** - * Adds a single float value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedFloatElement(fieldNumber, value) { - this.addRepeatedFloatIterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedFloat(fieldNumber, values); - }); - } - - /** - * Adds all float values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedFloatIterable(fieldNumber, values) { - this.addRepeatedFloatIterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedFloat(fieldNumber, values); - }); - } - - /** - * Sets a single float value into the field for the given field number at the - * given index. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedFloatElement_(fieldNumber, index, value, encoder) { - checkCriticalTypeFloat(value); - // Eagerly round to 32-bit precision so that reading back after set will - // yield the same value a reader will receive after serialization. - const floatValue = Math.fround(value); - const array = this.getRepeatedFloatArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = floatValue; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single float value into the field for the given field number at the - * given index. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedFloatElement(fieldNumber, index, value) { - this.setRepeatedFloatElement_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedFloat(fieldNumber, values); - }); - } - - /** - * Sets all float values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedFloatIterable(fieldNumber, values) { - checkCriticalTypeFloatIterable(values); - // Eagerly round to 32-bit precision so that reading back after set will - // yield the same value a reader will receive after serialization. - const array = Array.from(values, fround); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedFloat(fieldNumber, values); - }); - } - - /** - * Sets a single float value into the field for the given field number at the - * given index. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedFloatElement(fieldNumber, index, value) { - this.setRepeatedFloatElement_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedFloat(fieldNumber, values); - }); - } - - /** - * Sets all float values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedFloatIterable(fieldNumber, values) { - checkCriticalTypeFloatIterable(values); - // Eagerly round to 32-bit precision so that reading back after set will - // yield the same value a reader will receive after serialization. - const array = Array.from(values, fround); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedFloat(fieldNumber, values); - }); - } - - /* Int32 */ - - /** - * Adds all int32 values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedInt32Iterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedInt32Array_(fieldNumber), ...values]; - checkCriticalTypeSignedInt32Array(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single int32 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} value - */ - addPackedInt32Element(fieldNumber, value) { - this.addRepeatedInt32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedInt32(fieldNumber, values); - }); - } - - /** - * Adds all int32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedInt32Iterable(fieldNumber, values) { - this.addRepeatedInt32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedInt32(fieldNumber, values); - }); - } - - /** - * Adds a single int32 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedInt32Element(fieldNumber, value) { - this.addRepeatedInt32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedInt32(fieldNumber, values); - }); - } - - /** - * Adds all int32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedInt32Iterable(fieldNumber, values) { - this.addRepeatedInt32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedInt32(fieldNumber, values); - }); - } - - /** - * Sets a single int32 value into the field for the given field number at - * the given index. How these values are encoded depends on the given write - * function. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedInt32Element_(fieldNumber, index, value, encoder) { - checkCriticalTypeSignedInt32(value); - const array = this.getRepeatedInt32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single int32 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedInt32Element(fieldNumber, index, value) { - this.setRepeatedInt32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedInt32(fieldNumber, values); - }); - } - - /** - * Sets all int32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedInt32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedInt32(fieldNumber, values); - }); - } - - /** - * Sets a single int32 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedInt32Element(fieldNumber, index, value) { - this.setRepeatedInt32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedInt32(fieldNumber, values); - }); - } - - /** - * Sets all int32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedInt32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedInt32(fieldNumber, values); - }); - } - - /* Int64 */ - - /** - * Adds all int64 values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedInt64Iterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedInt64Array_(fieldNumber), ...values]; - checkCriticalTypeSignedInt64Array(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single int64 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedInt64Element(fieldNumber, value) { - this.addRepeatedInt64Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedInt64(fieldNumber, values); - }); - } - - /** - * Adds all int64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedInt64Iterable(fieldNumber, values) { - this.addRepeatedInt64Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedInt64(fieldNumber, values); - }); - } - - /** - * Adds a single int64 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedInt64Element(fieldNumber, value) { - this.addRepeatedInt64Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedInt64(fieldNumber, values); - }); - } - - /** - * Adds all int64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedInt64Iterable(fieldNumber, values) { - this.addRepeatedInt64Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedInt64(fieldNumber, values); - }); - } - - /** - * Sets a single int64 value into the field for the given field number at - * the given index. How these values are encoded depends on the given write - * function. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedInt64Element_(fieldNumber, index, value, encoder) { - checkCriticalTypeSignedInt64(value); - const array = this.getRepeatedInt64Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single int64 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedInt64Element(fieldNumber, index, value) { - this.setRepeatedInt64Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedInt64(fieldNumber, values); - }); - } - - /** - * Sets all int64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedInt64Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt64Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedInt64(fieldNumber, values); - }); - } - - /** - * Sets a single int64 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedInt64Element(fieldNumber, index, value) { - this.setRepeatedInt64Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedInt64(fieldNumber, values); - }); - } - - /** - * Sets all int64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedInt64Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt64Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedInt64(fieldNumber, values); - }); - } - - /* Sfixed32 */ - - /** - * Adds all sfixed32 values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedSfixed32Iterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedSfixed32Array_(fieldNumber), ...values]; - checkCriticalTypeSignedInt32Array(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single sfixed32 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} value - */ - addPackedSfixed32Element(fieldNumber, value) { - this.addRepeatedSfixed32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedSfixed32(fieldNumber, values); - }); - } - - /** - * Adds all sfixed32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedSfixed32Iterable(fieldNumber, values) { - this.addRepeatedSfixed32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedSfixed32(fieldNumber, values); - }); - } - - /** - * Adds a single sfixed32 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedSfixed32Element(fieldNumber, value) { - this.addRepeatedSfixed32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedSfixed32(fieldNumber, values); - }); - } - - /** - * Adds all sfixed32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedSfixed32Iterable(fieldNumber, values) { - this.addRepeatedSfixed32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedSfixed32(fieldNumber, values); - }); - } - - /** - * Sets a single sfixed32 value into the field for the given field number at - * the given index. How these values are encoded depends on the given write - * function. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedSfixed32Element_(fieldNumber, index, value, encoder) { - checkCriticalTypeSignedInt32(value); - const array = this.getRepeatedSfixed32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single sfixed32 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedSfixed32Element(fieldNumber, index, value) { - this.setRepeatedSfixed32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedSfixed32(fieldNumber, values); - }); - } - - /** - * Sets all sfixed32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedSfixed32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedSfixed32(fieldNumber, values); - }); - } - - /** - * Sets a single sfixed32 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedSfixed32Element(fieldNumber, index, value) { - this.setRepeatedSfixed32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedSfixed32(fieldNumber, values); - }); - } - - /** - * Sets all sfixed32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedSfixed32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedSfixed32(fieldNumber, values); - }); - } - - /* Sfixed64 */ - - /** - * Adds all sfixed64 values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedSfixed64Iterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedSfixed64Array_(fieldNumber), ...values]; - checkCriticalTypeSignedInt64Array(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single sfixed64 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedSfixed64Element(fieldNumber, value) { - this.addRepeatedSfixed64Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedSfixed64(fieldNumber, values); - }); - } - - /** - * Adds all sfixed64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedSfixed64Iterable(fieldNumber, values) { - this.addRepeatedSfixed64Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedSfixed64(fieldNumber, values); - }); - } - - /** - * Adds a single sfixed64 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedSfixed64Element(fieldNumber, value) { - this.addRepeatedSfixed64Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedSfixed64(fieldNumber, values); - }); - } - - /** - * Adds all sfixed64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedSfixed64Iterable(fieldNumber, values) { - this.addRepeatedSfixed64Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedSfixed64(fieldNumber, values); - }); - } - - /** - * Sets a single sfixed64 value into the field for the given field number at - * the given index. How these values are encoded depends on the given write - * function. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedSfixed64Element_(fieldNumber, index, value, encoder) { - checkCriticalTypeSignedInt64(value); - const array = this.getRepeatedSfixed64Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single sfixed64 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedSfixed64Element(fieldNumber, index, value) { - this.setRepeatedSfixed64Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedSfixed64(fieldNumber, values); - }); - } - - /** - * Sets all sfixed64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedSfixed64Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt64Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedSfixed64(fieldNumber, values); - }); - } - - /** - * Sets a single sfixed64 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedSfixed64Element(fieldNumber, index, value) { - this.setRepeatedSfixed64Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedSfixed64(fieldNumber, values); - }); - } - - /** - * Sets all sfixed64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedSfixed64Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt64Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedSfixed64(fieldNumber, values); - }); - } - - /* Sint32 */ - - /** - * Adds all sint32 values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedSint32Iterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedSint32Array_(fieldNumber), ...values]; - checkCriticalTypeSignedInt32Array(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single sint32 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} value - */ - addPackedSint32Element(fieldNumber, value) { - this.addRepeatedSint32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedSint32(fieldNumber, values); - }); - } - - /** - * Adds all sint32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedSint32Iterable(fieldNumber, values) { - this.addRepeatedSint32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedSint32(fieldNumber, values); - }); - } - - /** - * Adds a single sint32 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedSint32Element(fieldNumber, value) { - this.addRepeatedSint32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedSint32(fieldNumber, values); - }); - } - - /** - * Adds all sint32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedSint32Iterable(fieldNumber, values) { - this.addRepeatedSint32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedSint32(fieldNumber, values); - }); - } - - /** - * Sets a single sint32 value into the field for the given field number at - * the given index. How these values are encoded depends on the given write - * function. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedSint32Element_(fieldNumber, index, value, encoder) { - checkCriticalTypeSignedInt32(value); - const array = this.getRepeatedSint32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single sint32 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedSint32Element(fieldNumber, index, value) { - this.setRepeatedSint32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedSint32(fieldNumber, values); - }); - } - - /** - * Sets all sint32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedSint32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedSint32(fieldNumber, values); - }); - } - - /** - * Sets a single sint32 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedSint32Element(fieldNumber, index, value) { - this.setRepeatedSint32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedSint32(fieldNumber, values); - }); - } - - /** - * Sets all sint32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedSint32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedSint32(fieldNumber, values); - }); - } - - /* Sint64 */ - - /** - * Adds all sint64 values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedSint64Iterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedSint64Array_(fieldNumber), ...values]; - checkCriticalTypeSignedInt64Array(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single sint64 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedSint64Element(fieldNumber, value) { - this.addRepeatedSint64Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedSint64(fieldNumber, values); - }); - } - - /** - * Adds all sint64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedSint64Iterable(fieldNumber, values) { - this.addRepeatedSint64Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedSint64(fieldNumber, values); - }); - } - - /** - * Adds a single sint64 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedSint64Element(fieldNumber, value) { - this.addRepeatedSint64Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedSint64(fieldNumber, values); - }); - } - - /** - * Adds all sint64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedSint64Iterable(fieldNumber, values) { - this.addRepeatedSint64Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedSint64(fieldNumber, values); - }); - } - - /** - * Sets a single sint64 value into the field for the given field number at - * the given index. How these values are encoded depends on the given write - * function. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedSint64Element_(fieldNumber, index, value, encoder) { - checkCriticalTypeSignedInt64(value); - const array = this.getRepeatedSint64Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single sint64 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedSint64Element(fieldNumber, index, value) { - this.setRepeatedSint64Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedSint64(fieldNumber, values); - }); - } - - /** - * Sets all sint64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedSint64Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt64Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedSint64(fieldNumber, values); - }); - } - - /** - * Sets a single sint64 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedSint64Element(fieldNumber, index, value) { - this.setRepeatedSint64Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedSint64(fieldNumber, values); - }); - } - - /** - * Sets all sint64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedSint64Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeSignedInt64Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedSint64(fieldNumber, values); - }); - } - - /* Uint32 */ - - /** - * Adds all uint32 values into the field for the given field number. - * How these values are encoded depends on the given write function. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Writer, number, !Array): undefined} encoder - * @private - */ - addRepeatedUint32Iterable_(fieldNumber, values, encoder) { - const array = [...this.getRepeatedUint32Array_(fieldNumber), ...values]; - checkCriticalTypeUnsignedInt32Array(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Adds a single uint32 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} value - */ - addPackedUint32Element(fieldNumber, value) { - this.addRepeatedUint32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writePackedUint32(fieldNumber, values); - }); - } - - /** - * Adds all uint32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedUint32Iterable(fieldNumber, values) { - this.addRepeatedUint32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writePackedUint32(fieldNumber, values); - }); - } - - /** - * Adds a single uint32 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedUint32Element(fieldNumber, value) { - this.addRepeatedUint32Iterable_( - fieldNumber, [value], (writer, fieldNumber, values) => { - writer.writeRepeatedUint32(fieldNumber, values); - }); - } - - /** - * Adds all uint32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedUint32Iterable(fieldNumber, values) { - this.addRepeatedUint32Iterable_( - fieldNumber, values, (writer, fieldNumber, values) => { - writer.writeRepeatedUint32(fieldNumber, values); - }); - } - - /** - * Sets a single uint32 value into the field for the given field number at - * the given index. How these values are encoded depends on the given write - * function. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @param {function(!Writer, number, !Array): undefined} encoder - * @throws {!Error} if index is out of range when check mode is critical - * @private - */ - setRepeatedUint32Element_(fieldNumber, index, value, encoder) { - checkCriticalTypeUnsignedInt32(value); - const array = this.getRepeatedUint32Array_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, encoder); - } - - /** - * Sets a single uint32 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedUint32Element(fieldNumber, index, value) { - this.setRepeatedUint32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writePackedUint32(fieldNumber, values); - }); - } - - /** - * Sets all uint32 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedUint32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeUnsignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writePackedUint32(fieldNumber, values); - }); - } - - /** - * Sets a single uint32 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedUint32Element(fieldNumber, index, value) { - this.setRepeatedUint32Element_( - fieldNumber, index, value, (writer, fieldNumber, values) => { - writer.writeRepeatedUint32(fieldNumber, values); - }); - } - - /** - * Sets all uint32 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedUint32Iterable(fieldNumber, values) { - const array = Array.from(values); - checkCriticalTypeUnsignedInt32Array(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedUint32(fieldNumber, values); - }); - } - - /* Uint64 */ - - /** - * Adds a single uint64 value into the field for the given field number. - * All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedUint64Element(fieldNumber, value) { - this.addPackedInt64Element(fieldNumber, value); - } - - /** - * Adds all uint64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedUint64Iterable(fieldNumber, values) { - this.addPackedInt64Iterable(fieldNumber, values); - } - - /** - * Adds a single uint64 value into the field for the given field number. - * All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedUint64Element(fieldNumber, value) { - this.addUnpackedInt64Element(fieldNumber, value); - } - - /** - * Adds all uint64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedUint64Iterable(fieldNumber, values) { - this.addUnpackedInt64Iterable(fieldNumber, values); - } - - /** - * Sets a single uint64 value into the field for the given field number at - * the given index. All values will be encoded as packed values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedUint64Element(fieldNumber, index, value) { - this.setPackedInt64Element(fieldNumber, index, value); - } - - /** - * Sets all uint64 values into the field for the given field number. - * All these values will be encoded as packed values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedUint64Iterable(fieldNumber, values) { - this.setPackedInt64Iterable(fieldNumber, values); - } - - /** - * Sets a single uint64 value into the field for the given field number at - * the given index. All values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedUint64Element(fieldNumber, index, value) { - this.setUnpackedInt64Element(fieldNumber, index, value); - } - - /** - * Sets all uint64 values into the field for the given field number. - * All these values will be encoded as unpacked values. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedUint64Iterable(fieldNumber, values) { - this.setUnpackedInt64Iterable(fieldNumber, values); - } - - /* Bytes */ - - /** - * Sets all bytes values into the field for the given field number. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setRepeatedBytesIterable(fieldNumber, values) { - const /** !Array */ array = Array.from(values); - checkCriticalTypeByteStringArray(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedBytes(fieldNumber, values); - }); - } - - /** - * Adds all bytes values into the field for the given field number. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addRepeatedBytesIterable(fieldNumber, values) { - const array = [...this.getRepeatedBytesArray_(fieldNumber), ...values]; - checkCriticalTypeByteStringArray(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedBytes(fieldNumber, values); - }); - } - - /** - * Sets a single bytes value into the field for the given field number at - * the given index. - * @param {number} fieldNumber - * @param {number} index - * @param {!ByteString} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setRepeatedBytesElement(fieldNumber, index, value) { - checkCriticalTypeByteString(value); - const array = this.getRepeatedBytesArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedBytes(fieldNumber, values); - }); - } - - /** - * Adds a single bytes value into the field for the given field number. - * @param {number} fieldNumber - * @param {!ByteString} value - */ - addRepeatedBytesElement(fieldNumber, value) { - this.addRepeatedBytesIterable(fieldNumber, [value]); - } - - /* String */ - - /** - * Sets all string values into the field for the given field number. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setRepeatedStringIterable(fieldNumber, values) { - const /** !Array */ array = Array.from(values); - checkCriticalTypeStringArray(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedString(fieldNumber, values); - }); - } - - /** - * Adds all string values into the field for the given field number. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addRepeatedStringIterable(fieldNumber, values) { - const array = [...this.getRepeatedStringArray_(fieldNumber), ...values]; - checkCriticalTypeStringArray(array); - // Needs to set it back because the default empty array was not cached. - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedString(fieldNumber, values); - }); - } - - /** - * Sets a single string value into the field for the given field number at - * the given index. - * @param {number} fieldNumber - * @param {number} index - * @param {string} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setRepeatedStringElement(fieldNumber, index, value) { - checkCriticalTypeString(value); - const array = this.getRepeatedStringArray_(fieldNumber); - checkCriticalElementIndex(index, array.length); - array[index] = value; - // Needs to set it back to set encoder. - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writer.writeRepeatedString(fieldNumber, values); - }); - } - - /** - * Adds a single string value into the field for the given field number. - * @param {number} fieldNumber - * @param {string} value - */ - addRepeatedStringElement(fieldNumber, value) { - this.addRepeatedStringIterable(fieldNumber, [value]); - } - - /* Message */ - - /** - * Sets all message values into the field for the given field number. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setRepeatedMessageIterable(fieldNumber, values) { - const /** !Array */ array = Array.from(values); - checkCriticalTypeMessageArray(array); - this.setField_(fieldNumber, array, (writer, fieldNumber, values) => { - writeRepeatedMessage(writer, fieldNumber, values); - }); - } - - /** - * Adds all message values into the field for the given field number. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Kernel):!InternalMessage} instanceCreator - * @param {number=} pivot - */ - addRepeatedMessageIterable( - fieldNumber, values, instanceCreator, pivot = undefined) { - const array = [ - ...this.getRepeatedMessageArray_(fieldNumber, instanceCreator, pivot), - ...values, - ]; - checkCriticalTypeMessageArray(array); - // Needs to set it back with the new array. - this.setField_( - fieldNumber, array, - (writer, fieldNumber, values) => - writeRepeatedMessage(writer, fieldNumber, values)); - } - - /** - * Sets a single message value into the field for the given field number at - * the given index. - * @param {number} fieldNumber - * @param {!InternalMessage} value - * @param {function(!Kernel):!InternalMessage} instanceCreator - * @param {number} index - * @param {number=} pivot - * @throws {!Error} if index is out of range when check mode is critical - */ - setRepeatedMessageElement( - fieldNumber, value, instanceCreator, index, pivot = undefined) { - checkInstanceCreator(instanceCreator); - checkCriticalType( - value !== null, 'Given value is not a message instance: null'); - const array = - this.getRepeatedMessageArray_(fieldNumber, instanceCreator, pivot); - checkCriticalElementIndex(index, array.length); - array[index] = value; - } - - /** - * Adds a single message value into the field for the given field number. - * @param {number} fieldNumber - * @param {!InternalMessage} value - * @param {function(!Kernel):!InternalMessage} instanceCreator - * @param {number=} pivot - */ - addRepeatedMessageElement( - fieldNumber, value, instanceCreator, pivot = undefined) { - this.addRepeatedMessageIterable( - fieldNumber, [value], instanceCreator, pivot); - } - - // Groups - /** - * Sets all message values into the field for the given field number. - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setRepeatedGroupIterable(fieldNumber, values) { - const /** !Array */ array = Array.from(values); - checkCriticalTypeMessageArray(array); - this.setField_(fieldNumber, array, writeRepeatedGroup); - } - - /** - * Adds all message values into the field for the given field number. - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Kernel):!InternalMessage} instanceCreator - * @param {number=} pivot - */ - addRepeatedGroupIterable( - fieldNumber, values, instanceCreator, pivot = undefined) { - const array = [ - ...this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot), - ...values, - ]; - checkCriticalTypeMessageArray(array); - // Needs to set it back with the new array. - this.setField_(fieldNumber, array, writeRepeatedGroup); - } - - /** - * Sets a single message value into the field for the given field number at - * the given index. - * @param {number} fieldNumber - * @param {!InternalMessage} value - * @param {function(!Kernel):!InternalMessage} instanceCreator - * @param {number} index - * @param {number=} pivot - * @throws {!Error} if index is out of range when check mode is critical - */ - setRepeatedGroupElement( - fieldNumber, value, instanceCreator, index, pivot = undefined) { - checkInstanceCreator(instanceCreator); - checkCriticalType( - value !== null, 'Given value is not a message instance: null'); - const array = - this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot); - checkCriticalElementIndex(index, array.length); - array[index] = value; - } - - /** - * Adds a single message value into the field for the given field number. - * @param {number} fieldNumber - * @param {!InternalMessage} value - * @param {function(!Kernel):!InternalMessage} instanceCreator - * @param {number=} pivot - */ - addRepeatedGroupElement( - fieldNumber, value, instanceCreator, pivot = undefined) { - this.addRepeatedGroupIterable(fieldNumber, [value], instanceCreator, pivot); - } -} - -exports = Kernel; diff --git a/js/experimental/runtime/kernel/kernel_compatibility_test.js b/js/experimental/runtime/kernel/kernel_compatibility_test.js deleted file mode 100644 index 155008f7b..000000000 --- a/js/experimental/runtime/kernel/kernel_compatibility_test.js +++ /dev/null @@ -1,266 +0,0 @@ -/** - * @fileoverview Tests to make sure Kernel can read data in a backward - * compatible way even when protobuf schema changes according to the rules - * defined in - * https://developers.google.com/protocol-buffers/docs/proto#updating and - * https://developers.google.com/protocol-buffers/docs/proto3#updating. - * - * third_party/protobuf/conformance/binary_json_conformance_suite.cc already - * covers many compatibility tests, this file covers only the tests not covered - * by binary_json_conformance_suite. Ultimately all of the tests in this file - * should be moved to binary_json_conformance_suite. - */ -goog.module('protobuf.runtime.KernelCompatibilityTest'); - -goog.setTestOnly(); - -const ByteString = goog.require('protobuf.ByteString'); -const Int64 = goog.require('protobuf.Int64'); -const Kernel = goog.require('protobuf.runtime.Kernel'); -const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); -const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); - -/** - * @param {...number} bytes - * @return {!ArrayBuffer} - */ -function createArrayBuffer(...bytes) { - return new Uint8Array(bytes).buffer; -} - -/** - * Returns the Unicode character codes of a string. - * @param {string} str - * @return {!Array} - */ -function getCharacterCodes(str) { - return Array.from(str, (c) => c.charCodeAt(0)); -} - -describe('optional -> repeated compatibility', () => { - it('is maintained for scalars', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.setInt32(1, 1); - const serializedData = oldAccessor.serialize(); - expect(serializedData).toEqual(createArrayBuffer(0x8, 0x1)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getRepeatedInt32Size(1)).toEqual(1); - expect(newAccessor.getRepeatedInt32Element(1, 0)).toEqual(1); - }); - - it('is maintained for messages', () => { - const message = new TestMessage(Kernel.createEmpty()); - message.setInt32(1, 1); - - const oldAccessor = Kernel.createEmpty(); - oldAccessor.setMessage(1, message); - const serializedData = oldAccessor.serialize(); - expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getRepeatedMessageSize(1, TestMessage.instanceCreator)) - .toEqual(1); - expect( - newAccessor.getRepeatedMessageElement(1, TestMessage.instanceCreator, 0) - .serialize()) - .toEqual(message.serialize()); - }); - - it('is maintained for bytes', () => { - const message = new TestMessage(Kernel.createEmpty()); - message.setInt32(1, 1); - - const oldAccessor = Kernel.createEmpty(); - oldAccessor.setBytes( - 1, ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB))); - const serializedData = oldAccessor.serialize(); - expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0xA, 0xB)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getRepeatedBytesSize(1)).toEqual(1); - expect(newAccessor.getRepeatedBoolElement(1, 0)) - .toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB))); - }); - - it('is maintained for strings', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.setString(1, 'hello'); - const serializedData = oldAccessor.serialize(); - expect(serializedData) - .toEqual(createArrayBuffer(0xA, 0x5, 0x68, 0x65, 0x6C, 0x6C, 0x6F)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getRepeatedStringSize(1)).toEqual(1); - expect(newAccessor.getRepeatedStringElement(1, 0)).toEqual('hello'); - }); -}); - -describe('Kernel repeated -> optional compatibility', () => { - it('is maintained for unpacked scalars', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.addUnpackedInt32Element(1, 0); - oldAccessor.addUnpackedInt32Element(1, 1); - const serializedData = oldAccessor.serialize(); - expect(serializedData).toEqual(createArrayBuffer(0x8, 0x0, 0x8, 0x1)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getInt32WithDefault(1)).toEqual(1); - expect(newAccessor.serialize()).toEqual(serializedData); - }); - - // repeated -> optional transformation is not supported for packed fields yet: - // go/proto-schema-repeated - it('is not maintained for packed scalars', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.addPackedInt32Element(1, 0); - oldAccessor.addPackedInt32Element(1, 1); - const serializedData = oldAccessor.serialize(); - expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x0, 0x1)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - if (CHECK_CRITICAL_STATE) { - expect(() => newAccessor.getInt32WithDefault(1)).toThrow(); - } - }); - - it('is maintained for messages', () => { - const message1 = new TestMessage(Kernel.createEmpty()); - message1.setInt32(1, 1); - const message2 = new TestMessage(Kernel.createEmpty()); - message2.setInt32(1, 2); - message2.setInt32(2, 3); - - const oldAccessor = Kernel.createEmpty(); - oldAccessor.addRepeatedMessageElement( - 1, message1, TestMessage.instanceCreator); - oldAccessor.addRepeatedMessageElement( - 1, message2, TestMessage.instanceCreator); - const serializedData = oldAccessor.serialize(); - expect(serializedData) - .toEqual(createArrayBuffer( - 0xA, 0x2, 0x8, 0x1, 0xA, 0x4, 0x8, 0x2, 0x10, 0x3)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - // Values from message1 and message2 have been merged - const newMessage = newAccessor.getMessage(1, TestMessage.instanceCreator); - expect(newMessage.getRepeatedInt32Size(1)).toEqual(2); - expect(newMessage.getRepeatedInt32Element(1, 0)).toEqual(1); - expect(newMessage.getRepeatedInt32Element(1, 1)).toEqual(2); - expect(newMessage.getInt32WithDefault(2)).toEqual(3); - expect(newMessage.serialize()) - .toEqual(createArrayBuffer(0x8, 0x1, 0x8, 0x2, 0x10, 0x3)); - }); - - it('is maintained for bytes', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.addRepeatedBytesElement( - 1, ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB))); - oldAccessor.addRepeatedBytesElement( - 1, ByteString.fromArrayBuffer(createArrayBuffer(0xC, 0xD))); - const serializedData = oldAccessor.serialize(); - expect(serializedData) - .toEqual(createArrayBuffer(0xA, 0x2, 0xA, 0xB, 0xA, 0x2, 0xC, 0xD)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getBytesWithDefault(1)) - .toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0xC, 0xD))); - expect(newAccessor.serialize()).toEqual(serializedData); - }); - - it('is maintained for strings', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.addRepeatedStringElement(1, 'hello'); - oldAccessor.addRepeatedStringElement(1, 'world'); - const serializedData = oldAccessor.serialize(); - expect(serializedData) - .toEqual(createArrayBuffer( - 0xA, 0x5, ...getCharacterCodes('hello'), 0xA, 0x5, - ...getCharacterCodes('world'))); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getStringWithDefault(1)).toEqual('world'); - expect(newAccessor.serialize()).toEqual(serializedData); - }); -}); - -describe('Type change', () => { - it('is supported for fixed32 -> sfixed32', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.setFixed32(1, 4294967295); - const serializedData = oldAccessor.serialize(); - expect(serializedData) - .toEqual(createArrayBuffer(0xD, 0xFF, 0xFF, 0xFF, 0xFF)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getSfixed32WithDefault(1)).toEqual(-1); - expect(newAccessor.serialize()).toEqual(serializedData); - }); - - it('is supported for sfixed32 -> fixed32', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.setSfixed32(1, -1); - const serializedData = oldAccessor.serialize(); - expect(serializedData) - .toEqual(createArrayBuffer(0xD, 0xFF, 0xFF, 0xFF, 0xFF)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getFixed32WithDefault(1)).toEqual(4294967295); - expect(newAccessor.serialize()).toEqual(serializedData); - }); - - it('is supported for fixed64 -> sfixed64', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.setFixed64(1, Int64.fromHexString('0xFFFFFFFFFFFFFFFF')); - const serializedData = oldAccessor.serialize(); - expect(serializedData) - .toEqual(createArrayBuffer( - 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(-1)); - expect(newAccessor.serialize()).toEqual(serializedData); - }); - - it('is supported for sfixed64 -> fixed64', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.setSfixed64(1, Int64.fromInt(-1)); - const serializedData = oldAccessor.serialize(); - expect(serializedData) - .toEqual(createArrayBuffer( - 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getFixed64WithDefault(1)) - .toEqual(Int64.fromHexString('0xFFFFFFFFFFFFFFFF')); - expect(newAccessor.serialize()).toEqual(serializedData); - }); - - it('is supported for bytes -> message', () => { - const oldAccessor = Kernel.createEmpty(); - oldAccessor.setBytes( - 1, ByteString.fromArrayBuffer(createArrayBuffer(0x8, 0x1))); - const serializedData = oldAccessor.serialize(); - expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - const message = newAccessor.getMessage(1, TestMessage.instanceCreator); - expect(message.getInt32WithDefault(1)).toEqual(1); - expect(message.serialize()).toEqual(createArrayBuffer(0x8, 0x1)); - expect(newAccessor.serialize()).toEqual(serializedData); - }); - - it('is supported for message -> bytes', () => { - const oldAccessor = Kernel.createEmpty(); - const message = new TestMessage(Kernel.createEmpty()); - message.setInt32(1, 1); - oldAccessor.setMessage(1, message); - const serializedData = oldAccessor.serialize(); - expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1)); - - const newAccessor = Kernel.fromArrayBuffer(serializedData); - expect(newAccessor.getBytesWithDefault(1)) - .toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0x8, 0x1))); - expect(newAccessor.serialize()).toEqual(serializedData); - }); -}); diff --git a/js/experimental/runtime/kernel/kernel_repeated_test.js b/js/experimental/runtime/kernel/kernel_repeated_test.js deleted file mode 100644 index 6a798b6c0..000000000 --- a/js/experimental/runtime/kernel/kernel_repeated_test.js +++ /dev/null @@ -1,7807 +0,0 @@ -/** - * @fileoverview Tests for repeated methods in kernel.js. - */ -goog.module('protobuf.runtime.KernelTest'); - -goog.setTestOnly(); - -const ByteString = goog.require('protobuf.ByteString'); -const Int64 = goog.require('protobuf.Int64'); -const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const Kernel = goog.require('protobuf.runtime.Kernel'); -const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); -// Note to the reader: -// Since the lazy accessor behavior changes with the checking level some of the -// tests in this file have to know which checking level is enable to make -// correct assertions. -const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); - -/** - * @param {...number} bytes - * @return {!ArrayBuffer} - */ -function createArrayBuffer(...bytes) { - return new Uint8Array(bytes).buffer; -} - -/** - * Expects the Iterable instance yield the same values as the expected array. - * @param {!Iterable} iterable - * @param {!Array} expected - * @template T - * TODO: Implement this as a custom matcher. - */ -function expectEqualToArray(iterable, expected) { - const array = Array.from(iterable); - expect(array).toEqual(expected); -} - -/** - * Expects the Iterable instance yield qualified values. - * @param {!Iterable} iterable - * @param {(function(T): boolean)=} verify - * @template T - */ -function expectQualifiedIterable(iterable, verify) { - if (verify) { - for (const value of iterable) { - expect(verify(value)).toBe(true); - } - } -} - -/** - * Expects the Iterable instance yield the same values as the expected array of - * messages. - * @param {!Iterable} iterable - * @param {!Array} expected - * @template T - * TODO: Implement this as a custom matcher. - */ -function expectEqualToMessageArray(iterable, expected) { - const array = Array.from(iterable); - expect(array.length).toEqual(expected.length); - for (let i = 0; i < array.length; i++) { - const value = array[i].getBoolWithDefault(1, false); - const expectedValue = expected[i].getBoolWithDefault(1, false); - expect(value).toBe(expectedValue); - } -} - -describe('Kernel for repeated boolean does', () => { - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - const list1 = accessor.getRepeatedBoolIterable(1); - const list2 = accessor.getRepeatedBoolIterable(1); - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - expect(accessor.getRepeatedBoolSize(1)).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const list1 = accessor.getRepeatedBoolIterable(1); - const list2 = accessor.getRepeatedBoolIterable(1); - expect(list1).not.toBe(list2); - }); - - it('return unpacked multibytes values from the input', () => { - const bytes = createArrayBuffer(0x08, 0x80, 0x01, 0x08, 0x80, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); - }); - - it('return for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - accessor.addUnpackedBoolElement(1, true); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); - accessor.addUnpackedBoolElement(1, false); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); - }); - - it('return for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - accessor.addUnpackedBoolIterable(1, [true]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); - accessor.addUnpackedBoolIterable(1, [false]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); - }); - - it('return for setting single unpacked value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00, 0x08, 0x01)); - accessor.setUnpackedBoolElement(1, 0, true); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, true]); - }); - - it('return for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - accessor.setUnpackedBoolIterable(1, [true]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); - accessor.setUnpackedBoolIterable(1, [false]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [false]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - accessor.addUnpackedBoolElement(1, true); - accessor.addUnpackedBoolElement(1, false); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - accessor.addUnpackedBoolIterable(1, [true, false]); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode for setting single unpacked value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x00, 0x01)); - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x01); - accessor.setUnpackedBoolElement(1, 0, true); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - accessor.setUnpackedBoolIterable(1, [true, false]); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('return packed values from the input', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); - }); - - it('ensure not the same instance returned for packed values', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const list1 = accessor.getRepeatedBoolIterable(1); - const list2 = accessor.getRepeatedBoolIterable(1); - expect(list1).not.toBe(list2); - }); - - it('return packed multibytes values from the input', () => { - const bytes = createArrayBuffer(0x0A, 0x04, 0x80, 0x01, 0x80, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); - }); - - it('return for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - accessor.addPackedBoolElement(1, true); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); - accessor.addPackedBoolElement(1, false); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); - }); - - it('return for adding packed values', () => { - const accessor = Kernel.createEmpty(); - accessor.addPackedBoolIterable(1, [true]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); - accessor.addPackedBoolIterable(1, [false]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); - }); - - it('return for setting single packed value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00, 0x08, 0x01)); - accessor.setPackedBoolElement(1, 0, true); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, true]); - }); - - it('return for setting packed values', () => { - const accessor = Kernel.createEmpty(); - accessor.setPackedBoolIterable(1, [true]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); - accessor.setPackedBoolIterable(1, [false]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [false]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - accessor.addPackedBoolElement(1, true); - accessor.addPackedBoolElement(1, false); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - accessor.addPackedBoolIterable(1, [true, false]); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode for setting single packed value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00, 0x08, 0x01)); - const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x01); - accessor.setPackedBoolElement(1, 0, true); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - accessor.setPackedBoolIterable(1, [true, false]); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('return combined values from the input', () => { - const bytes = - createArrayBuffer(0x08, 0x01, 0x0A, 0x02, 0x01, 0x00, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expectEqualToArray( - accessor.getRepeatedBoolIterable(1), [true, true, false, false]); - }); - - it('return the repeated field element from the input', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getRepeatedBoolElement( - /* fieldNumber= */ 1, /* index= */ 0)) - .toEqual(true); - expect(accessor.getRepeatedBoolElement( - /* fieldNumber= */ 1, /* index= */ 1)) - .toEqual(false); - }); - - it('return the size from the input', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getRepeatedBoolSize(1)).toEqual(2); - }); - - it('fail when getting unpacked bool value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedBoolIterable(1); - }).toThrowError('Expected wire type: 0 but found: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); - } - }); - - it('fail when adding unpacked bool values with number value', () => { - const accessor = Kernel.createEmpty(); - const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedBoolIterable(1, [fakeBoolean])) - .toThrowError('Must be a boolean, but got: 2'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedBoolIterable(1, [fakeBoolean]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [fakeBoolean]); - } - }); - - it('fail when adding single unpacked bool value with number value', () => { - const accessor = Kernel.createEmpty(); - const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedBoolElement(1, fakeBoolean)) - .toThrowError('Must be a boolean, but got: 2'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedBoolElement(1, fakeBoolean); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [fakeBoolean]); - } - }); - - it('fail when setting unpacked bool values with number value', () => { - const accessor = Kernel.createEmpty(); - const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedBoolIterable(1, [fakeBoolean])) - .toThrowError('Must be a boolean, but got: 2'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedBoolIterable(1, [fakeBoolean]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [fakeBoolean]); - } - }); - - it('fail when setting single unpacked bool value with number value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedBoolElement(1, 0, fakeBoolean)) - .toThrowError('Must be a boolean, but got: 2'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedBoolElement(1, 0, fakeBoolean); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [fakeBoolean]); - } - }); - - it('fail when adding packed bool values with number value', () => { - const accessor = Kernel.createEmpty(); - const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedBoolIterable(1, [fakeBoolean])) - .toThrowError('Must be a boolean, but got: 2'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedBoolIterable(1, [fakeBoolean]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [fakeBoolean]); - } - }); - - it('fail when adding single packed bool value with number value', () => { - const accessor = Kernel.createEmpty(); - const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedBoolElement(1, fakeBoolean)) - .toThrowError('Must be a boolean, but got: 2'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedBoolElement(1, fakeBoolean); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [fakeBoolean]); - } - }); - - it('fail when setting packed bool values with number value', () => { - const accessor = Kernel.createEmpty(); - const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedBoolIterable(1, [fakeBoolean])) - .toThrowError('Must be a boolean, but got: 2'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedBoolIterable(1, [fakeBoolean]); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [fakeBoolean]); - } - }); - - it('fail when setting single packed bool value with number value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedBoolElement(1, 0, fakeBoolean)) - .toThrowError('Must be a boolean, but got: 2'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedBoolElement(1, 0, fakeBoolean); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [fakeBoolean]); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedBoolElement(1, 1, true)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedBoolElement(1, 1, true); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [false, true]); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedBoolElement(1, 1, true)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedBoolElement(1, 1, true); - expectEqualToArray(accessor.getRepeatedBoolIterable(1), [false, true]); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedBoolElement( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedBoolElement( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated double does', () => { - const value1 = 1; - const value2 = 0; - - const unpackedValue1Value2 = createArrayBuffer( - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xF0, - 0x3F, // value1 - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - ); - const unpackedValue2Value1 = createArrayBuffer( - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xF0, - 0x3F, // value2 - ); - - const packedValue1Value2 = createArrayBuffer( - 0x0A, - 0x10, // tag - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xF0, - 0x3F, // value1 - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - ); - const packedValue2Value1 = createArrayBuffer( - 0x0A, - 0x10, // tag - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xF0, - 0x3F, // value2 - ); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedDoubleIterable(1); - const list2 = accessor.getRepeatedDoubleIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedDoubleSize(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedDoubleIterable(1); - const list2 = accessor.getRepeatedDoubleIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedDoubleElement(1, value1); - const list1 = accessor.getRepeatedDoubleIterable(1); - accessor.addUnpackedDoubleElement(1, value2); - const list2 = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedDoubleIterable(1, [value1]); - const list1 = accessor.getRepeatedDoubleIterable(1); - accessor.addUnpackedDoubleIterable(1, [value2]); - const list2 = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedDoubleElement(1, 1, value1); - const list = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedDoubleIterable(1, [value1]); - const list = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedDoubleElement(1, value1); - accessor.addUnpackedDoubleElement(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedDoubleIterable(1, [value1]); - accessor.addUnpackedDoubleIterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedDoubleElement(1, 0, value2); - accessor.setUnpackedDoubleElement(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedDoubleIterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedDoubleIterable(1); - const list2 = accessor.getRepeatedDoubleIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedDoubleElement(1, value1); - const list1 = accessor.getRepeatedDoubleIterable(1); - accessor.addPackedDoubleElement(1, value2); - const list2 = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedDoubleIterable(1, [value1]); - const list1 = accessor.getRepeatedDoubleIterable(1); - accessor.addPackedDoubleIterable(1, [value2]); - const list2 = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedDoubleElement(1, 1, value1); - const list = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedDoubleIterable(1, [value1]); - const list1 = accessor.getRepeatedDoubleIterable(1); - accessor.setPackedDoubleIterable(1, [value2]); - const list2 = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedDoubleElement(1, value1); - accessor.addPackedDoubleElement(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedDoubleIterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedDoubleElement(1, 0, value2); - accessor.setPackedDoubleElement(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedDoubleIterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xF0, - 0x3F, // value1 - 0x0A, - 0x10, // tag - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xF0, - 0x3F, // value1 - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - )); - - const list = accessor.getRepeatedDoubleIterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedDoubleElement( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedDoubleElement( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedDoubleSize(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked double value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedDoubleIterable(1); - }).toThrowError('Expected wire type: 1 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectEqualToArray( - accessor.getRepeatedDoubleIterable(1), [2.937446524422997e-306]); - } - }); - - it('fail when adding unpacked double values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedDoubleIterable(1, [fakeDouble])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedDoubleIterable(1, [fakeDouble]); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [fakeDouble]); - } - }); - - it('fail when adding single unpacked double value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedDoubleElement(1, fakeDouble)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedDoubleElement(1, fakeDouble); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [fakeDouble]); - } - }); - - it('fail when setting unpacked double values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedDoubleIterable(1, [fakeDouble])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedDoubleIterable(1, [fakeDouble]); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [fakeDouble]); - } - }); - - it('fail when setting single unpacked double value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedDoubleElement(1, 0, fakeDouble)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedDoubleElement(1, 0, fakeDouble); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [fakeDouble]); - } - }); - - it('fail when adding packed double values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedDoubleIterable(1, [fakeDouble])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedDoubleIterable(1, [fakeDouble]); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [fakeDouble]); - } - }); - - it('fail when adding single packed double value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedDoubleElement(1, fakeDouble)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedDoubleElement(1, fakeDouble); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [fakeDouble]); - } - }); - - it('fail when setting packed double values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedDoubleIterable(1, [fakeDouble])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedDoubleIterable(1, [fakeDouble]); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [fakeDouble]); - } - }); - - it('fail when setting single packed double value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedDoubleElement(1, 0, fakeDouble)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedDoubleElement(1, 0, fakeDouble); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [fakeDouble]); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedDoubleElement(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedDoubleElement(1, 1, 1); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [0, 1]); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedDoubleElement(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedDoubleElement(1, 1, 1); - expectEqualToArray(accessor.getRepeatedDoubleIterable(1), [0, 1]); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedDoubleElement( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedDoubleElement( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated fixed32 does', () => { - const value1 = 1; - const value2 = 0; - - const unpackedValue1Value2 = createArrayBuffer( - 0x0D, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00); - const unpackedValue2Value1 = createArrayBuffer( - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x01, 0x00, 0x00, 0x00); - - const packedValue1Value2 = createArrayBuffer( - 0x0A, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const packedValue2Value1 = createArrayBuffer( - 0x0A, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedFixed32Iterable(1); - const list2 = accessor.getRepeatedFixed32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedFixed32Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedFixed32Iterable(1); - const list2 = accessor.getRepeatedFixed32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFixed32Element(1, value1); - const list1 = accessor.getRepeatedFixed32Iterable(1); - accessor.addUnpackedFixed32Element(1, value2); - const list2 = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFixed32Iterable(1, [value1]); - const list1 = accessor.getRepeatedFixed32Iterable(1); - accessor.addUnpackedFixed32Iterable(1, [value2]); - const list2 = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedFixed32Element(1, 1, value1); - const list = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedFixed32Iterable(1, [value1]); - const list = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFixed32Element(1, value1); - accessor.addUnpackedFixed32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFixed32Iterable(1, [value1]); - accessor.addUnpackedFixed32Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedFixed32Element(1, 0, value2); - accessor.setUnpackedFixed32Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedFixed32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedFixed32Iterable(1); - const list2 = accessor.getRepeatedFixed32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFixed32Element(1, value1); - const list1 = accessor.getRepeatedFixed32Iterable(1); - accessor.addPackedFixed32Element(1, value2); - const list2 = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFixed32Iterable(1, [value1]); - const list1 = accessor.getRepeatedFixed32Iterable(1); - accessor.addPackedFixed32Iterable(1, [value2]); - const list2 = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedFixed32Element(1, 1, value1); - const list = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedFixed32Iterable(1, [value1]); - const list1 = accessor.getRepeatedFixed32Iterable(1); - accessor.setPackedFixed32Iterable(1, [value2]); - const list2 = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFixed32Element(1, value1); - accessor.addPackedFixed32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFixed32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedFixed32Element(1, 0, value2); - accessor.setPackedFixed32Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedFixed32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x0D, - 0x01, - 0x00, - 0x00, - 0x00, // value1 - 0x0A, - 0x08, // tag - 0x01, - 0x00, - 0x00, - 0x00, // value1 - 0x00, - 0x00, - 0x00, - 0x00, // value2 - 0x0D, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - )); - - const list = accessor.getRepeatedFixed32Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedFixed32Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedFixed32Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedFixed32Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked fixed32 value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedFixed32Iterable(1); - }).toThrowError('Expected wire type: 5 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedFixed32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when adding unpacked fixed32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedFixed32Iterable(1, [fakeFixed32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedFixed32Iterable(1, [fakeFixed32]); - expectQualifiedIterable(accessor.getRepeatedFixed32Iterable(1)); - } - }); - - it('fail when adding single unpacked fixed32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedFixed32Element(1, fakeFixed32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedFixed32Element(1, fakeFixed32); - expectQualifiedIterable(accessor.getRepeatedFixed32Iterable(1)); - } - }); - - it('fail when setting unpacked fixed32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedFixed32Iterable(1, [fakeFixed32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedFixed32Iterable(1, [fakeFixed32]); - expectQualifiedIterable(accessor.getRepeatedFixed32Iterable(1)); - } - }); - - it('fail when setting single unpacked fixed32 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); - const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedFixed32Element(1, 0, fakeFixed32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedFixed32Element(1, 0, fakeFixed32); - expectQualifiedIterable( - accessor.getRepeatedFixed32Iterable(1), - ); - } - }); - - it('fail when adding packed fixed32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedFixed32Iterable(1, [fakeFixed32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedFixed32Iterable(1, [fakeFixed32]); - expectQualifiedIterable(accessor.getRepeatedFixed32Iterable(1)); - } - }); - - it('fail when adding single packed fixed32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedFixed32Element(1, fakeFixed32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedFixed32Element(1, fakeFixed32); - expectQualifiedIterable(accessor.getRepeatedFixed32Iterable(1)); - } - }); - - it('fail when setting packed fixed32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedFixed32Iterable(1, [fakeFixed32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedFixed32Iterable(1, [fakeFixed32]); - expectQualifiedIterable(accessor.getRepeatedFixed32Iterable(1)); - } - }); - - it('fail when setting single packed fixed32 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedFixed32Element(1, 0, fakeFixed32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedFixed32Element(1, 0, fakeFixed32); - expectQualifiedIterable(accessor.getRepeatedFixed32Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer( - createArrayBuffer(0x0A, 0x04, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedFixed32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedFixed32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedFixed32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedFixed32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedFixed32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedFixed32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedFixed32Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedFixed32Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated fixed64 does', () => { - const value1 = Int64.fromInt(1); - const value2 = Int64.fromInt(0); - - const unpackedValue1Value2 = createArrayBuffer( - 0x09, - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - ); - const unpackedValue2Value1 = createArrayBuffer( - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - 0x09, - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - ); - - const packedValue1Value2 = createArrayBuffer( - 0x0A, - 0x10, // tag - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - ); - const packedValue2Value1 = createArrayBuffer( - 0x0A, - 0x10, // tag - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - ); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedFixed64Iterable(1); - const list2 = accessor.getRepeatedFixed64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedFixed64Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedFixed64Iterable(1); - const list2 = accessor.getRepeatedFixed64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFixed64Element(1, value1); - const list1 = accessor.getRepeatedFixed64Iterable(1); - accessor.addUnpackedFixed64Element(1, value2); - const list2 = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFixed64Iterable(1, [value1]); - const list1 = accessor.getRepeatedFixed64Iterable(1); - accessor.addUnpackedFixed64Iterable(1, [value2]); - const list2 = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedFixed64Element(1, 1, value1); - const list = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedFixed64Iterable(1, [value1]); - const list = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFixed64Element(1, value1); - accessor.addUnpackedFixed64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFixed64Iterable(1, [value1]); - accessor.addUnpackedFixed64Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedFixed64Element(1, 0, value2); - accessor.setUnpackedFixed64Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedFixed64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedFixed64Iterable(1); - const list2 = accessor.getRepeatedFixed64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFixed64Element(1, value1); - const list1 = accessor.getRepeatedFixed64Iterable(1); - accessor.addPackedFixed64Element(1, value2); - const list2 = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFixed64Iterable(1, [value1]); - const list1 = accessor.getRepeatedFixed64Iterable(1); - accessor.addPackedFixed64Iterable(1, [value2]); - const list2 = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedFixed64Element(1, 1, value1); - const list = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedFixed64Iterable(1, [value1]); - const list1 = accessor.getRepeatedFixed64Iterable(1); - accessor.setPackedFixed64Iterable(1, [value2]); - const list2 = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFixed64Element(1, value1); - accessor.addPackedFixed64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFixed64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedFixed64Element(1, 0, value2); - accessor.setPackedFixed64Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedFixed64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value1 - 0x0A, 0x10, // tag - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value1 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value2 - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // value2 - )); - - const list = accessor.getRepeatedFixed64Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedFixed64Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedFixed64Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedFixed64Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked fixed64 value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedFixed64Iterable(1); - }).toThrowError('Expected wire type: 1 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedFixed64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when adding unpacked fixed64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedFixed64Iterable(1, [fakeFixed64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedFixed64Iterable(1, [fakeFixed64]); - expectQualifiedIterable(accessor.getRepeatedFixed64Iterable(1)); - } - }); - - it('fail when adding single unpacked fixed64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedFixed64Element(1, fakeFixed64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedFixed64Element(1, fakeFixed64); - expectQualifiedIterable(accessor.getRepeatedFixed64Iterable(1)); - } - }); - - it('fail when setting unpacked fixed64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedFixed64Iterable(1, [fakeFixed64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedFixed64Iterable(1, [fakeFixed64]); - expectQualifiedIterable(accessor.getRepeatedFixed64Iterable(1)); - } - }); - - it('fail when setting single unpacked fixed64 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedFixed64Element(1, 0, fakeFixed64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedFixed64Element(1, 0, fakeFixed64); - expectQualifiedIterable(accessor.getRepeatedFixed64Iterable(1)); - } - }); - - it('fail when adding packed fixed64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedFixed64Iterable(1, [fakeFixed64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedFixed64Iterable(1, [fakeFixed64]); - expectQualifiedIterable(accessor.getRepeatedFixed64Iterable(1)); - } - }); - - it('fail when adding single packed fixed64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedFixed64Element(1, fakeFixed64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedFixed64Element(1, fakeFixed64); - expectQualifiedIterable(accessor.getRepeatedFixed64Iterable(1)); - } - }); - - it('fail when setting packed fixed64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedFixed64Iterable(1, [fakeFixed64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedFixed64Iterable(1, [fakeFixed64]); - expectQualifiedIterable(accessor.getRepeatedFixed64Iterable(1)); - } - }); - - it('fail when setting single packed fixed64 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedFixed64Element(1, 0, fakeFixed64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedFixed64Element(1, 0, fakeFixed64); - expectQualifiedIterable(accessor.getRepeatedFixed64Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedFixed64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedFixed64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedFixed64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedFixed64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedFixed64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedFixed64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedFixed64Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedFixed64Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated float does', () => { - const value1 = 1.6; - const value1Float = Math.fround(1.6); - const value2 = 0; - - const unpackedValue1Value2 = createArrayBuffer( - 0x0D, 0xCD, 0xCC, 0xCC, 0x3F, 0x0D, 0x00, 0x00, 0x00, 0x00); - const unpackedValue2Value1 = createArrayBuffer( - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xCD, 0xCC, 0xCC, 0x3F); - - const packedValue1Value2 = createArrayBuffer( - 0x0A, 0x08, 0xCD, 0xCC, 0xCC, 0x3F, 0x00, 0x00, 0x00, 0x00); - const packedValue2Value1 = createArrayBuffer( - 0x0A, 0x08, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xCC, 0xCC, 0x3F); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedFloatIterable(1); - const list2 = accessor.getRepeatedFloatIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedFloatSize(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list, [value1Float, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedFloatIterable(1); - const list2 = accessor.getRepeatedFloatIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFloatElement(1, value1); - const list1 = accessor.getRepeatedFloatIterable(1); - accessor.addUnpackedFloatElement(1, value2); - const list2 = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list1, [value1Float]); - expectEqualToArray(list2, [value1Float, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFloatIterable(1, [value1]); - const list1 = accessor.getRepeatedFloatIterable(1); - accessor.addUnpackedFloatIterable(1, [value2]); - const list2 = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list1, [value1Float]); - expectEqualToArray(list2, [value1Float, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedFloatElement(1, 1, value1); - const list = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list, [value1Float, value1Float]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedFloatIterable(1, [value1]); - const list = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list, [value1Float]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFloatElement(1, value1); - accessor.addUnpackedFloatElement(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedFloatIterable(1, [value1]); - accessor.addUnpackedFloatIterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedFloatElement(1, 0, value2); - accessor.setUnpackedFloatElement(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedFloatIterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list, [value1Float, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedFloatIterable(1); - const list2 = accessor.getRepeatedFloatIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFloatElement(1, value1); - const list1 = accessor.getRepeatedFloatIterable(1); - accessor.addPackedFloatElement(1, value2); - const list2 = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list1, [value1Float]); - expectEqualToArray(list2, [value1Float, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFloatIterable(1, [value1]); - const list1 = accessor.getRepeatedFloatIterable(1); - accessor.addPackedFloatIterable(1, [value2]); - const list2 = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list1, [value1Float]); - expectEqualToArray(list2, [value1Float, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedFloatElement(1, 1, value1); - const list = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list, [value1Float, value1Float]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedFloatIterable(1, [value1]); - const list1 = accessor.getRepeatedFloatIterable(1); - accessor.setPackedFloatIterable(1, [value2]); - const list2 = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list1, [value1Float]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFloatElement(1, value1); - accessor.addPackedFloatElement(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedFloatIterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedFloatElement(1, 0, value2); - accessor.setPackedFloatElement(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedFloatIterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x0D, - 0xCD, - 0xCC, - 0xCC, - 0x3F, // value1 - 0x0A, - 0x08, // tag - 0xCD, - 0xCC, - 0xCC, - 0x3F, // value1 - 0x00, - 0x00, - 0x00, - 0x00, // value2 - 0x0D, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - )); - - const list = accessor.getRepeatedFloatIterable(1); - - expectEqualToArray(list, [value1Float, value1Float, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedFloatElement( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedFloatElement( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1Float); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedFloatSize(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked float value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedFloatIterable(1); - }).toThrowError('Expected wire type: 5 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedFloatIterable(1), - (value) => typeof value === 'number'); - } - }); - - it('fail when adding unpacked float values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedFloatIterable(1, [fakeFloat])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedFloatIterable(1, [fakeFloat]); - expectQualifiedIterable(accessor.getRepeatedFloatIterable(1)); - } - }); - - it('fail when adding single unpacked float value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedFloatElement(1, fakeFloat)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedFloatElement(1, fakeFloat); - expectQualifiedIterable(accessor.getRepeatedFloatIterable(1)); - } - }); - - it('fail when setting unpacked float values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedFloatIterable(1, [fakeFloat])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedFloatIterable(1, [fakeFloat]); - expectQualifiedIterable(accessor.getRepeatedFloatIterable(1)); - } - }); - - it('fail when setting single unpacked float value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); - const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedFloatElement(1, 0, fakeFloat)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedFloatElement(1, 0, fakeFloat); - expectQualifiedIterable(accessor.getRepeatedFloatIterable(1)); - } - }); - - it('fail when adding packed float values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedFloatIterable(1, [fakeFloat])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedFloatIterable(1, [fakeFloat]); - expectQualifiedIterable(accessor.getRepeatedFloatIterable(1)); - } - }); - - it('fail when adding single packed float value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedFloatElement(1, fakeFloat)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedFloatElement(1, fakeFloat); - expectQualifiedIterable(accessor.getRepeatedFloatIterable(1)); - } - }); - - it('fail when setting packed float values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedFloatIterable(1, [fakeFloat])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedFloatIterable(1, [fakeFloat]); - expectQualifiedIterable(accessor.getRepeatedFloatIterable(1)); - } - }); - - it('fail when setting single packed float value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedFloatElement(1, 0, fakeFloat)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedFloatElement(1, 0, fakeFloat); - expectQualifiedIterable(accessor.getRepeatedFloatIterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedFloatElement(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedFloatElement(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedFloatIterable(1), - (value) => typeof value === 'number'); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedFloatElement(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedFloatElement(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedFloatIterable(1), - (value) => typeof value === 'number'); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedFloatElement( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedFloatElement( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated int32 does', () => { - const value1 = 1; - const value2 = 0; - - const unpackedValue1Value2 = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const unpackedValue2Value1 = createArrayBuffer(0x08, 0x00, 0x08, 0x01); - - const packedValue1Value2 = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedInt32Iterable(1); - const list2 = accessor.getRepeatedInt32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedInt32Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedInt32Iterable(1); - const list2 = accessor.getRepeatedInt32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedInt32Element(1, value1); - const list1 = accessor.getRepeatedInt32Iterable(1); - accessor.addUnpackedInt32Element(1, value2); - const list2 = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedInt32Iterable(1, [value1]); - const list1 = accessor.getRepeatedInt32Iterable(1); - accessor.addUnpackedInt32Iterable(1, [value2]); - const list2 = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedInt32Element(1, 1, value1); - const list = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedInt32Iterable(1, [value1]); - const list = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedInt32Element(1, value1); - accessor.addUnpackedInt32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedInt32Iterable(1, [value1]); - accessor.addUnpackedInt32Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedInt32Element(1, 0, value2); - accessor.setUnpackedInt32Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedInt32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedInt32Iterable(1); - const list2 = accessor.getRepeatedInt32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedInt32Element(1, value1); - const list1 = accessor.getRepeatedInt32Iterable(1); - accessor.addPackedInt32Element(1, value2); - const list2 = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedInt32Iterable(1, [value1]); - const list1 = accessor.getRepeatedInt32Iterable(1); - accessor.addPackedInt32Iterable(1, [value2]); - const list2 = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedInt32Element(1, 1, value1); - const list = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedInt32Iterable(1, [value1]); - const list1 = accessor.getRepeatedInt32Iterable(1); - accessor.setPackedInt32Iterable(1, [value2]); - const list2 = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedInt32Element(1, value1); - accessor.addPackedInt32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedInt32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedInt32Element(1, 0, value2); - accessor.setPackedInt32Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedInt32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, - 0x01, // unpacked value1 - 0x0A, - 0x02, - 0x01, - 0x00, // packed value1 and value2 - 0x08, - 0x00, // unpacked value2 - )); - - const list = accessor.getRepeatedInt32Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedInt32Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedInt32Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedInt32Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked int32 value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedInt32Iterable(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedInt32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when adding unpacked int32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedInt32Iterable(1, [fakeInt32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedInt32Iterable(1, [fakeInt32]); - expectQualifiedIterable(accessor.getRepeatedInt32Iterable(1)); - } - }); - - it('fail when adding single unpacked int32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedInt32Element(1, fakeInt32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedInt32Element(1, fakeInt32); - expectQualifiedIterable(accessor.getRepeatedInt32Iterable(1)); - } - }); - - it('fail when setting unpacked int32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedInt32Iterable(1, [fakeInt32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedInt32Iterable(1, [fakeInt32]); - expectQualifiedIterable(accessor.getRepeatedInt32Iterable(1)); - } - }); - - it('fail when setting single unpacked int32 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedInt32Element(1, 0, fakeInt32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedInt32Element(1, 0, fakeInt32); - expectQualifiedIterable( - accessor.getRepeatedInt32Iterable(1), - ); - } - }); - - it('fail when adding packed int32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedInt32Iterable(1, [fakeInt32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedInt32Iterable(1, [fakeInt32]); - expectQualifiedIterable(accessor.getRepeatedInt32Iterable(1)); - } - }); - - it('fail when adding single packed int32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedInt32Element(1, fakeInt32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedInt32Element(1, fakeInt32); - expectQualifiedIterable(accessor.getRepeatedInt32Iterable(1)); - } - }); - - it('fail when setting packed int32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedInt32Iterable(1, [fakeInt32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedInt32Iterable(1, [fakeInt32]); - expectQualifiedIterable(accessor.getRepeatedInt32Iterable(1)); - } - }); - - it('fail when setting single packed int32 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedInt32Element(1, 0, fakeInt32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedInt32Element(1, 0, fakeInt32); - expectQualifiedIterable(accessor.getRepeatedInt32Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedInt32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedInt32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedInt32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedInt32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedInt32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedInt32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedInt32Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedInt32Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated int64 does', () => { - const value1 = Int64.fromInt(1); - const value2 = Int64.fromInt(0); - - const unpackedValue1Value2 = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const unpackedValue2Value1 = createArrayBuffer(0x08, 0x00, 0x08, 0x01); - - const packedValue1Value2 = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedInt64Iterable(1); - const list2 = accessor.getRepeatedInt64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedInt64Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedInt64Iterable(1); - const list2 = accessor.getRepeatedInt64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedInt64Element(1, value1); - const list1 = accessor.getRepeatedInt64Iterable(1); - accessor.addUnpackedInt64Element(1, value2); - const list2 = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedInt64Iterable(1, [value1]); - const list1 = accessor.getRepeatedInt64Iterable(1); - accessor.addUnpackedInt64Iterable(1, [value2]); - const list2 = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedInt64Element(1, 1, value1); - const list = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedInt64Iterable(1, [value1]); - const list = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedInt64Element(1, value1); - accessor.addUnpackedInt64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedInt64Iterable(1, [value1]); - accessor.addUnpackedInt64Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedInt64Element(1, 0, value2); - accessor.setUnpackedInt64Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedInt64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedInt64Iterable(1); - const list2 = accessor.getRepeatedInt64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedInt64Element(1, value1); - const list1 = accessor.getRepeatedInt64Iterable(1); - accessor.addPackedInt64Element(1, value2); - const list2 = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedInt64Iterable(1, [value1]); - const list1 = accessor.getRepeatedInt64Iterable(1); - accessor.addPackedInt64Iterable(1, [value2]); - const list2 = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedInt64Element(1, 1, value1); - const list = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedInt64Iterable(1, [value1]); - const list1 = accessor.getRepeatedInt64Iterable(1); - accessor.setPackedInt64Iterable(1, [value2]); - const list2 = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedInt64Element(1, value1); - accessor.addPackedInt64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedInt64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedInt64Element(1, 0, value2); - accessor.setPackedInt64Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedInt64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, - 0x01, // unpacked value1 - 0x0A, - 0x02, - 0x01, - 0x00, // packed value1 and value2 - 0x08, - 0x00, // unpacked value2 - )); - - const list = accessor.getRepeatedInt64Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedInt64Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedInt64Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedInt64Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked int64 value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedInt64Iterable(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedInt64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when adding unpacked int64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedInt64Iterable(1, [fakeInt64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedInt64Iterable(1, [fakeInt64]); - expectQualifiedIterable(accessor.getRepeatedInt64Iterable(1)); - } - }); - - it('fail when adding single unpacked int64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedInt64Element(1, fakeInt64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedInt64Element(1, fakeInt64); - expectQualifiedIterable(accessor.getRepeatedInt64Iterable(1)); - } - }); - - it('fail when setting unpacked int64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedInt64Iterable(1, [fakeInt64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedInt64Iterable(1, [fakeInt64]); - expectQualifiedIterable(accessor.getRepeatedInt64Iterable(1)); - } - }); - - it('fail when setting single unpacked int64 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedInt64Element(1, 0, fakeInt64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedInt64Element(1, 0, fakeInt64); - expectQualifiedIterable(accessor.getRepeatedInt64Iterable(1)); - } - }); - - it('fail when adding packed int64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedInt64Iterable(1, [fakeInt64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedInt64Iterable(1, [fakeInt64]); - expectQualifiedIterable(accessor.getRepeatedInt64Iterable(1)); - } - }); - - it('fail when adding single packed int64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedInt64Element(1, fakeInt64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedInt64Element(1, fakeInt64); - expectQualifiedIterable(accessor.getRepeatedInt64Iterable(1)); - } - }); - - it('fail when setting packed int64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedInt64Iterable(1, [fakeInt64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedInt64Iterable(1, [fakeInt64]); - expectQualifiedIterable(accessor.getRepeatedInt64Iterable(1)); - } - }); - - it('fail when setting single packed int64 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedInt64Element(1, 0, fakeInt64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedInt64Element(1, 0, fakeInt64); - expectQualifiedIterable(accessor.getRepeatedInt64Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedInt64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedInt64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedInt64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedInt64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedInt64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedInt64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedInt64Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedInt64Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated sfixed32 does', () => { - const value1 = 1; - const value2 = 0; - - const unpackedValue1Value2 = createArrayBuffer( - 0x0D, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00); - const unpackedValue2Value1 = createArrayBuffer( - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x01, 0x00, 0x00, 0x00); - - const packedValue1Value2 = createArrayBuffer( - 0x0A, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const packedValue2Value1 = createArrayBuffer( - 0x0A, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedSfixed32Iterable(1); - const list2 = accessor.getRepeatedSfixed32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedSfixed32Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedSfixed32Iterable(1); - const list2 = accessor.getRepeatedSfixed32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSfixed32Element(1, value1); - const list1 = accessor.getRepeatedSfixed32Iterable(1); - accessor.addUnpackedSfixed32Element(1, value2); - const list2 = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSfixed32Iterable(1, [value1]); - const list1 = accessor.getRepeatedSfixed32Iterable(1); - accessor.addUnpackedSfixed32Iterable(1, [value2]); - const list2 = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedSfixed32Element(1, 1, value1); - const list = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedSfixed32Iterable(1, [value1]); - const list = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSfixed32Element(1, value1); - accessor.addUnpackedSfixed32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSfixed32Iterable(1, [value1]); - accessor.addUnpackedSfixed32Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedSfixed32Element(1, 0, value2); - accessor.setUnpackedSfixed32Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedSfixed32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedSfixed32Iterable(1); - const list2 = accessor.getRepeatedSfixed32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSfixed32Element(1, value1); - const list1 = accessor.getRepeatedSfixed32Iterable(1); - accessor.addPackedSfixed32Element(1, value2); - const list2 = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSfixed32Iterable(1, [value1]); - const list1 = accessor.getRepeatedSfixed32Iterable(1); - accessor.addPackedSfixed32Iterable(1, [value2]); - const list2 = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedSfixed32Element(1, 1, value1); - const list = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedSfixed32Iterable(1, [value1]); - const list1 = accessor.getRepeatedSfixed32Iterable(1); - accessor.setPackedSfixed32Iterable(1, [value2]); - const list2 = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSfixed32Element(1, value1); - accessor.addPackedSfixed32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSfixed32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedSfixed32Element(1, 0, value2); - accessor.setPackedSfixed32Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedSfixed32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x0D, - 0x01, - 0x00, - 0x00, - 0x00, // value1 - 0x0A, - 0x08, // tag - 0x01, - 0x00, - 0x00, - 0x00, // value1 - 0x00, - 0x00, - 0x00, - 0x00, // value2 - 0x0D, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - )); - - const list = accessor.getRepeatedSfixed32Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedSfixed32Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedSfixed32Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedSfixed32Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked sfixed32 value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedSfixed32Iterable(1); - }).toThrowError('Expected wire type: 5 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedSfixed32Iterable(1), - (value) => typeof value === 'number'); - } - }); - - it('fail when adding unpacked sfixed32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedSfixed32Iterable(1, [fakeSfixed32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedSfixed32Iterable(1, [fakeSfixed32]); - expectQualifiedIterable(accessor.getRepeatedSfixed32Iterable(1)); - } - }); - - it('fail when adding single unpacked sfixed32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedSfixed32Element(1, fakeSfixed32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedSfixed32Element(1, fakeSfixed32); - expectQualifiedIterable(accessor.getRepeatedSfixed32Iterable(1)); - } - }); - - it('fail when setting unpacked sfixed32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSfixed32Iterable(1, [fakeSfixed32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSfixed32Iterable(1, [fakeSfixed32]); - expectQualifiedIterable(accessor.getRepeatedSfixed32Iterable(1)); - } - }); - - it('fail when setting single unpacked sfixed32 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); - const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSfixed32Element(1, 0, fakeSfixed32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSfixed32Element(1, 0, fakeSfixed32); - expectQualifiedIterable(accessor.getRepeatedSfixed32Iterable(1)); - } - }); - - it('fail when adding packed sfixed32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedSfixed32Iterable(1, [fakeSfixed32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedSfixed32Iterable(1, [fakeSfixed32]); - expectQualifiedIterable(accessor.getRepeatedSfixed32Iterable(1)); - } - }); - - it('fail when adding single packed sfixed32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedSfixed32Element(1, fakeSfixed32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedSfixed32Element(1, fakeSfixed32); - expectQualifiedIterable(accessor.getRepeatedSfixed32Iterable(1)); - } - }); - - it('fail when setting packed sfixed32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSfixed32Iterable(1, [fakeSfixed32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSfixed32Iterable(1, [fakeSfixed32]); - expectQualifiedIterable(accessor.getRepeatedSfixed32Iterable(1)); - } - }); - - it('fail when setting single packed sfixed32 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSfixed32Element(1, 0, fakeSfixed32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSfixed32Element(1, 0, fakeSfixed32); - expectQualifiedIterable(accessor.getRepeatedSfixed32Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSfixed32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSfixed32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedSfixed32Iterable(1), - (value) => typeof value === 'number'); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSfixed32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSfixed32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedSfixed32Iterable(1), - (value) => typeof value === 'number'); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedSfixed32Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedSfixed32Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated sfixed64 does', () => { - const value1 = Int64.fromInt(1); - const value2 = Int64.fromInt(0); - - const unpackedValue1Value2 = createArrayBuffer( - 0x09, - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - ); - const unpackedValue2Value1 = createArrayBuffer( - 0x09, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - 0x09, - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - ); - - const packedValue1Value2 = createArrayBuffer( - 0x0A, - 0x10, // tag - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - ); - const packedValue2Value1 = createArrayBuffer( - 0x0A, - 0x10, // tag - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value2 - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // value1 - ); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedSfixed64Iterable(1); - const list2 = accessor.getRepeatedSfixed64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedSfixed64Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedSfixed64Iterable(1); - const list2 = accessor.getRepeatedSfixed64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSfixed64Element(1, value1); - const list1 = accessor.getRepeatedSfixed64Iterable(1); - accessor.addUnpackedSfixed64Element(1, value2); - const list2 = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSfixed64Iterable(1, [value1]); - const list1 = accessor.getRepeatedSfixed64Iterable(1); - accessor.addUnpackedSfixed64Iterable(1, [value2]); - const list2 = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedSfixed64Element(1, 1, value1); - const list = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedSfixed64Iterable(1, [value1]); - const list = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSfixed64Element(1, value1); - accessor.addUnpackedSfixed64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSfixed64Iterable(1, [value1]); - accessor.addUnpackedSfixed64Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedSfixed64Element(1, 0, value2); - accessor.setUnpackedSfixed64Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedSfixed64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedSfixed64Iterable(1); - const list2 = accessor.getRepeatedSfixed64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSfixed64Element(1, value1); - const list1 = accessor.getRepeatedSfixed64Iterable(1); - accessor.addPackedSfixed64Element(1, value2); - const list2 = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSfixed64Iterable(1, [value1]); - const list1 = accessor.getRepeatedSfixed64Iterable(1); - accessor.addPackedSfixed64Iterable(1, [value2]); - const list2 = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedSfixed64Element(1, 1, value1); - const list = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedSfixed64Iterable(1, [value1]); - const list1 = accessor.getRepeatedSfixed64Iterable(1); - accessor.setPackedSfixed64Iterable(1, [value2]); - const list2 = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSfixed64Element(1, value1); - accessor.addPackedSfixed64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSfixed64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedSfixed64Element(1, 0, value2); - accessor.setPackedSfixed64Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedSfixed64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value1 - 0x0A, 0x10, // tag - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value1 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value2 - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // value2 - )); - - const list = accessor.getRepeatedSfixed64Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedSfixed64Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedSfixed64Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedSfixed64Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked sfixed64 value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedSfixed64Iterable(1); - }).toThrowError('Expected wire type: 1 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedSfixed64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when adding unpacked sfixed64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedSfixed64Iterable(1, [fakeSfixed64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedSfixed64Iterable(1, [fakeSfixed64]); - expectQualifiedIterable(accessor.getRepeatedSfixed64Iterable(1)); - } - }); - - it('fail when adding single unpacked sfixed64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedSfixed64Element(1, fakeSfixed64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedSfixed64Element(1, fakeSfixed64); - expectQualifiedIterable(accessor.getRepeatedSfixed64Iterable(1)); - } - }); - - it('fail when setting unpacked sfixed64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSfixed64Iterable(1, [fakeSfixed64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSfixed64Iterable(1, [fakeSfixed64]); - expectQualifiedIterable(accessor.getRepeatedSfixed64Iterable(1)); - } - }); - - it('fail when setting single unpacked sfixed64 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSfixed64Element(1, 0, fakeSfixed64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSfixed64Element(1, 0, fakeSfixed64); - expectQualifiedIterable(accessor.getRepeatedSfixed64Iterable(1)); - } - }); - - it('fail when adding packed sfixed64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedSfixed64Iterable(1, [fakeSfixed64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedSfixed64Iterable(1, [fakeSfixed64]); - expectQualifiedIterable(accessor.getRepeatedSfixed64Iterable(1)); - } - }); - - it('fail when adding single packed sfixed64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedSfixed64Element(1, fakeSfixed64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedSfixed64Element(1, fakeSfixed64); - expectQualifiedIterable(accessor.getRepeatedSfixed64Iterable(1)); - } - }); - - it('fail when setting packed sfixed64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSfixed64Iterable(1, [fakeSfixed64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSfixed64Iterable(1, [fakeSfixed64]); - expectQualifiedIterable(accessor.getRepeatedSfixed64Iterable(1)); - } - }); - - it('fail when setting single packed sfixed64 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSfixed64Element(1, 0, fakeSfixed64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSfixed64Element(1, 0, fakeSfixed64); - expectQualifiedIterable(accessor.getRepeatedSfixed64Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSfixed64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSfixed64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedSfixed64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSfixed64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSfixed64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedSfixed64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedSfixed64Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedSfixed64Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated sint32 does', () => { - const value1 = -1; - const value2 = 0; - - const unpackedValue1Value2 = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const unpackedValue2Value1 = createArrayBuffer(0x08, 0x00, 0x08, 0x01); - - const packedValue1Value2 = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedSint32Iterable(1); - const list2 = accessor.getRepeatedSint32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedSint32Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedSint32Iterable(1); - const list2 = accessor.getRepeatedSint32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSint32Element(1, value1); - const list1 = accessor.getRepeatedSint32Iterable(1); - accessor.addUnpackedSint32Element(1, value2); - const list2 = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSint32Iterable(1, [value1]); - const list1 = accessor.getRepeatedSint32Iterable(1); - accessor.addUnpackedSint32Iterable(1, [value2]); - const list2 = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedSint32Element(1, 1, value1); - const list = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedSint32Iterable(1, [value1]); - const list = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSint32Element(1, value1); - accessor.addUnpackedSint32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSint32Iterable(1, [value1]); - accessor.addUnpackedSint32Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedSint32Element(1, 0, value2); - accessor.setUnpackedSint32Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedSint32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedSint32Iterable(1); - const list2 = accessor.getRepeatedSint32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSint32Element(1, value1); - const list1 = accessor.getRepeatedSint32Iterable(1); - accessor.addPackedSint32Element(1, value2); - const list2 = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSint32Iterable(1, [value1]); - const list1 = accessor.getRepeatedSint32Iterable(1); - accessor.addPackedSint32Iterable(1, [value2]); - const list2 = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedSint32Element(1, 1, value1); - const list = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedSint32Iterable(1, [value1]); - const list1 = accessor.getRepeatedSint32Iterable(1); - accessor.setPackedSint32Iterable(1, [value2]); - const list2 = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSint32Element(1, value1); - accessor.addPackedSint32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSint32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedSint32Element(1, 0, value2); - accessor.setPackedSint32Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedSint32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, - 0x01, // unpacked value1 - 0x0A, - 0x02, - 0x01, - 0x00, // packed value1 and value2 - 0x08, - 0x00, // unpacked value2 - )); - - const list = accessor.getRepeatedSint32Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedSint32Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedSint32Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedSint32Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked sint32 value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedSint32Iterable(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedSint32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when adding unpacked sint32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedSint32Iterable(1, [fakeSint32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedSint32Iterable(1, [fakeSint32]); - expectQualifiedIterable(accessor.getRepeatedSint32Iterable(1)); - } - }); - - it('fail when adding single unpacked sint32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedSint32Element(1, fakeSint32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedSint32Element(1, fakeSint32); - expectQualifiedIterable(accessor.getRepeatedSint32Iterable(1)); - } - }); - - it('fail when setting unpacked sint32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSint32Iterable(1, [fakeSint32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSint32Iterable(1, [fakeSint32]); - expectQualifiedIterable(accessor.getRepeatedSint32Iterable(1)); - } - }); - - it('fail when setting single unpacked sint32 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSint32Element(1, 0, fakeSint32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSint32Element(1, 0, fakeSint32); - expectQualifiedIterable( - accessor.getRepeatedSint32Iterable(1), - ); - } - }); - - it('fail when adding packed sint32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedSint32Iterable(1, [fakeSint32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedSint32Iterable(1, [fakeSint32]); - expectQualifiedIterable(accessor.getRepeatedSint32Iterable(1)); - } - }); - - it('fail when adding single packed sint32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedSint32Element(1, fakeSint32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedSint32Element(1, fakeSint32); - expectQualifiedIterable(accessor.getRepeatedSint32Iterable(1)); - } - }); - - it('fail when setting packed sint32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSint32Iterable(1, [fakeSint32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSint32Iterable(1, [fakeSint32]); - expectQualifiedIterable(accessor.getRepeatedSint32Iterable(1)); - } - }); - - it('fail when setting single packed sint32 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSint32Element(1, 0, fakeSint32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSint32Element(1, 0, fakeSint32); - expectQualifiedIterable(accessor.getRepeatedSint32Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSint32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSint32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedSint32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSint32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSint32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedSint32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedSint32Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedSint32Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated sint64 does', () => { - const value1 = Int64.fromInt(-1); - const value2 = Int64.fromInt(0); - - const unpackedValue1Value2 = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const unpackedValue2Value1 = createArrayBuffer(0x08, 0x00, 0x08, 0x01); - - const packedValue1Value2 = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedSint64Iterable(1); - const list2 = accessor.getRepeatedSint64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedSint64Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedSint64Iterable(1); - const list2 = accessor.getRepeatedSint64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSint64Element(1, value1); - const list1 = accessor.getRepeatedSint64Iterable(1); - accessor.addUnpackedSint64Element(1, value2); - const list2 = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSint64Iterable(1, [value1]); - const list1 = accessor.getRepeatedSint64Iterable(1); - accessor.addUnpackedSint64Iterable(1, [value2]); - const list2 = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedSint64Element(1, 1, value1); - const list = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedSint64Iterable(1, [value1]); - const list = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSint64Element(1, value1); - accessor.addUnpackedSint64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedSint64Iterable(1, [value1]); - accessor.addUnpackedSint64Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedSint64Element(1, 0, value2); - accessor.setUnpackedSint64Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedSint64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedSint64Iterable(1); - const list2 = accessor.getRepeatedSint64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSint64Element(1, value1); - const list1 = accessor.getRepeatedSint64Iterable(1); - accessor.addPackedSint64Element(1, value2); - const list2 = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSint64Iterable(1, [value1]); - const list1 = accessor.getRepeatedSint64Iterable(1); - accessor.addPackedSint64Iterable(1, [value2]); - const list2 = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedSint64Element(1, 1, value1); - const list = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedSint64Iterable(1, [value1]); - const list1 = accessor.getRepeatedSint64Iterable(1); - accessor.setPackedSint64Iterable(1, [value2]); - const list2 = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSint64Element(1, value1); - accessor.addPackedSint64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedSint64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedSint64Element(1, 0, value2); - accessor.setPackedSint64Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedSint64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, - 0x01, // unpacked value1 - 0x0A, - 0x02, - 0x01, - 0x00, // packed value1 and value2 - 0x08, - 0x00, // unpacked value2 - )); - - const list = accessor.getRepeatedSint64Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedSint64Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedSint64Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedSint64Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked sint64 value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedSint64Iterable(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedSint64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when adding unpacked sint64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedSint64Iterable(1, [fakeSint64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedSint64Iterable(1, [fakeSint64]); - expectQualifiedIterable(accessor.getRepeatedSint64Iterable(1)); - } - }); - - it('fail when adding single unpacked sint64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedSint64Element(1, fakeSint64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedSint64Element(1, fakeSint64); - expectQualifiedIterable(accessor.getRepeatedSint64Iterable(1)); - } - }); - - it('fail when setting unpacked sint64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSint64Iterable(1, [fakeSint64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSint64Iterable(1, [fakeSint64]); - expectQualifiedIterable(accessor.getRepeatedSint64Iterable(1)); - } - }); - - it('fail when setting single unpacked sint64 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSint64Element(1, 0, fakeSint64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSint64Element(1, 0, fakeSint64); - expectQualifiedIterable(accessor.getRepeatedSint64Iterable(1)); - } - }); - - it('fail when adding packed sint64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedSint64Iterable(1, [fakeSint64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedSint64Iterable(1, [fakeSint64]); - expectQualifiedIterable(accessor.getRepeatedSint64Iterable(1)); - } - }); - - it('fail when adding single packed sint64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedSint64Element(1, fakeSint64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedSint64Element(1, fakeSint64); - expectQualifiedIterable(accessor.getRepeatedSint64Iterable(1)); - } - }); - - it('fail when setting packed sint64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSint64Iterable(1, [fakeSint64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSint64Iterable(1, [fakeSint64]); - expectQualifiedIterable(accessor.getRepeatedSint64Iterable(1)); - } - }); - - it('fail when setting single packed sint64 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSint64Element(1, 0, fakeSint64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSint64Element(1, 0, fakeSint64); - expectQualifiedIterable(accessor.getRepeatedSint64Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedSint64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedSint64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedSint64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedSint64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedSint64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedSint64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedSint64Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedSint64Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated uint32 does', () => { - const value1 = 1; - const value2 = 0; - - const unpackedValue1Value2 = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const unpackedValue2Value1 = createArrayBuffer(0x08, 0x00, 0x08, 0x01); - - const packedValue1Value2 = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedUint32Iterable(1); - const list2 = accessor.getRepeatedUint32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedUint32Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedUint32Iterable(1); - const list2 = accessor.getRepeatedUint32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedUint32Element(1, value1); - const list1 = accessor.getRepeatedUint32Iterable(1); - accessor.addUnpackedUint32Element(1, value2); - const list2 = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedUint32Iterable(1, [value1]); - const list1 = accessor.getRepeatedUint32Iterable(1); - accessor.addUnpackedUint32Iterable(1, [value2]); - const list2 = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedUint32Element(1, 1, value1); - const list = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedUint32Iterable(1, [value1]); - const list = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedUint32Element(1, value1); - accessor.addUnpackedUint32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedUint32Iterable(1, [value1]); - accessor.addUnpackedUint32Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedUint32Element(1, 0, value2); - accessor.setUnpackedUint32Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedUint32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedUint32Iterable(1); - const list2 = accessor.getRepeatedUint32Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedUint32Element(1, value1); - const list1 = accessor.getRepeatedUint32Iterable(1); - accessor.addPackedUint32Element(1, value2); - const list2 = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedUint32Iterable(1, [value1]); - const list1 = accessor.getRepeatedUint32Iterable(1); - accessor.addPackedUint32Iterable(1, [value2]); - const list2 = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedUint32Element(1, 1, value1); - const list = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedUint32Iterable(1, [value1]); - const list1 = accessor.getRepeatedUint32Iterable(1); - accessor.setPackedUint32Iterable(1, [value2]); - const list2 = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedUint32Element(1, value1); - accessor.addPackedUint32Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedUint32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedUint32Element(1, 0, value2); - accessor.setPackedUint32Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedUint32Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, - 0x01, // unpacked value1 - 0x0A, - 0x02, - 0x01, - 0x00, // packed value1 and value2 - 0x08, - 0x00, // unpacked value2 - )); - - const list = accessor.getRepeatedUint32Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedUint32Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedUint32Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedUint32Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked uint32 value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedUint32Iterable(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedUint32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when adding unpacked uint32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedUint32Iterable(1, [fakeUint32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedUint32Iterable(1, [fakeUint32]); - expectQualifiedIterable(accessor.getRepeatedUint32Iterable(1)); - } - }); - - it('fail when adding single unpacked uint32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedUint32Element(1, fakeUint32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedUint32Element(1, fakeUint32); - expectQualifiedIterable(accessor.getRepeatedUint32Iterable(1)); - } - }); - - it('fail when setting unpacked uint32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedUint32Iterable(1, [fakeUint32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedUint32Iterable(1, [fakeUint32]); - expectQualifiedIterable(accessor.getRepeatedUint32Iterable(1)); - } - }); - - it('fail when setting single unpacked uint32 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedUint32Element(1, 0, fakeUint32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedUint32Element(1, 0, fakeUint32); - expectQualifiedIterable( - accessor.getRepeatedUint32Iterable(1), - ); - } - }); - - it('fail when adding packed uint32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedUint32Iterable(1, [fakeUint32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedUint32Iterable(1, [fakeUint32]); - expectQualifiedIterable(accessor.getRepeatedUint32Iterable(1)); - } - }); - - it('fail when adding single packed uint32 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedUint32Element(1, fakeUint32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedUint32Element(1, fakeUint32); - expectQualifiedIterable(accessor.getRepeatedUint32Iterable(1)); - } - }); - - it('fail when setting packed uint32 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedUint32Iterable(1, [fakeUint32])) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedUint32Iterable(1, [fakeUint32]); - expectQualifiedIterable(accessor.getRepeatedUint32Iterable(1)); - } - }); - - it('fail when setting single packed uint32 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedUint32Element(1, 0, fakeUint32)) - .toThrowError('Must be a number, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedUint32Element(1, 0, fakeUint32); - expectQualifiedIterable(accessor.getRepeatedUint32Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedUint32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedUint32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedUint32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedUint32Element(1, 1, 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedUint32Element(1, 1, 1); - expectQualifiedIterable( - accessor.getRepeatedUint32Iterable(1), - (value) => Number.isInteger(value)); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedUint32Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedUint32Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated uint64 does', () => { - const value1 = Int64.fromInt(1); - const value2 = Int64.fromInt(0); - - const unpackedValue1Value2 = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const unpackedValue2Value1 = createArrayBuffer(0x08, 0x00, 0x08, 0x01); - - const packedValue1Value2 = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedUint64Iterable(1); - const list2 = accessor.getRepeatedUint64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedUint64Size(1); - - expect(size).toEqual(0); - }); - - it('return unpacked values from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for unpacked values', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const list1 = accessor.getRepeatedUint64Iterable(1); - const list2 = accessor.getRepeatedUint64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedUint64Element(1, value1); - const list1 = accessor.getRepeatedUint64Iterable(1); - accessor.addUnpackedUint64Element(1, value2); - const list2 = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedUint64Iterable(1, [value1]); - const list1 = accessor.getRepeatedUint64Iterable(1); - accessor.addUnpackedUint64Iterable(1, [value2]); - const list2 = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - accessor.setUnpackedUint64Element(1, 1, value1); - const list = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedUint64Iterable(1, [value1]); - const list = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single unpacked value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedUint64Element(1, value1); - accessor.addUnpackedUint64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for adding unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedUint64Iterable(1, [value1]); - accessor.addUnpackedUint64Iterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('encode for setting single unpacked value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setUnpackedUint64Element(1, 0, value2); - accessor.setUnpackedUint64Element(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue2Value1); - }); - - it('encode for setting unpacked values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setUnpackedUint64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(unpackedValue1Value2); - }); - - it('return packed values from the input', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for packed values', () => { - const accessor = Kernel.fromArrayBuffer(packedValue1Value2); - - const list1 = accessor.getRepeatedUint64Iterable(1); - const list2 = accessor.getRepeatedUint64Iterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedUint64Element(1, value1); - const list1 = accessor.getRepeatedUint64Iterable(1); - accessor.addPackedUint64Element(1, value2); - const list2 = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedUint64Iterable(1, [value1]); - const list1 = accessor.getRepeatedUint64Iterable(1); - accessor.addPackedUint64Iterable(1, [value2]); - const list2 = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedUint64Element(1, 1, value1); - const list = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedUint64Iterable(1, [value1]); - const list1 = accessor.getRepeatedUint64Iterable(1); - accessor.setPackedUint64Iterable(1, [value2]); - const list2 = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value2]); - }); - - it('encode for adding single packed value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedUint64Element(1, value1); - accessor.addPackedUint64Element(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for adding packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addPackedUint64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('encode for setting single packed value', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - accessor.setPackedUint64Element(1, 0, value2); - accessor.setPackedUint64Element(1, 1, value1); - - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue2Value1); - }); - - it('encode for setting packed values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setPackedUint64Iterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(packedValue1Value2); - }); - - it('return combined values from the input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, - 0x01, // unpacked value1 - 0x0A, - 0x02, - 0x01, - 0x00, // packed value1 and value2 - 0x08, - 0x00, // unpacked value2 - )); - - const list = accessor.getRepeatedUint64Iterable(1); - - expectEqualToArray(list, [value1, value1, value2, value2]); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const result1 = accessor.getRepeatedUint64Element( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedUint64Element( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); - - const size = accessor.getRepeatedUint64Size(1); - - expect(size).toEqual(2); - }); - - it('fail when getting unpacked uint64 value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedUint64Iterable(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedUint64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when adding unpacked uint64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedUint64Iterable(1, [fakeUint64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedUint64Iterable(1, [fakeUint64]); - expectQualifiedIterable(accessor.getRepeatedUint64Iterable(1)); - } - }); - - it('fail when adding single unpacked uint64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addUnpackedUint64Element(1, fakeUint64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addUnpackedUint64Element(1, fakeUint64); - expectQualifiedIterable(accessor.getRepeatedUint64Iterable(1)); - } - }); - - it('fail when setting unpacked uint64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedUint64Iterable(1, [fakeUint64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedUint64Iterable(1, [fakeUint64]); - expectQualifiedIterable(accessor.getRepeatedUint64Iterable(1)); - } - }); - - it('fail when setting single unpacked uint64 value with null value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); - const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedUint64Element(1, 0, fakeUint64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedUint64Element(1, 0, fakeUint64); - expectQualifiedIterable(accessor.getRepeatedUint64Iterable(1)); - } - }); - - it('fail when adding packed uint64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedUint64Iterable(1, [fakeUint64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedUint64Iterable(1, [fakeUint64]); - expectQualifiedIterable(accessor.getRepeatedUint64Iterable(1)); - } - }); - - it('fail when adding single packed uint64 value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addPackedUint64Element(1, fakeUint64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addPackedUint64Element(1, fakeUint64); - expectQualifiedIterable(accessor.getRepeatedUint64Iterable(1)); - } - }); - - it('fail when setting packed uint64 values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedUint64Iterable(1, [fakeUint64])) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedUint64Iterable(1, [fakeUint64]); - expectQualifiedIterable(accessor.getRepeatedUint64Iterable(1)); - } - }); - - it('fail when setting single packed uint64 value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedUint64Element(1, 0, fakeUint64)) - .toThrowError('Must be Int64 instance, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedUint64Element(1, 0, fakeUint64); - expectQualifiedIterable(accessor.getRepeatedUint64Iterable(1)); - } - }); - - it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setUnpackedUint64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setUnpackedUint64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedUint64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when setting single packed with out-of-bound index', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setPackedUint64Element(1, 1, Int64.fromInt(1))) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setPackedUint64Element(1, 1, Int64.fromInt(1)); - expectQualifiedIterable( - accessor.getRepeatedUint64Iterable(1), - (value) => value instanceof Int64); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedUint64Element( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedUint64Element( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated bytes does', () => { - const value1 = ByteString.fromArrayBuffer((createArrayBuffer(0x61))); - const value2 = ByteString.fromArrayBuffer((createArrayBuffer(0x62))); - - const repeatedValue1Value2 = createArrayBuffer( - 0x0A, - 0x01, - 0x61, // value1 - 0x0A, - 0x01, - 0x62, // value2 - ); - const repeatedValue2Value1 = createArrayBuffer( - 0x0A, - 0x01, - 0x62, // value2 - 0x0A, - 0x01, - 0x61, // value1 - ); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedBytesIterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedBytesIterable(1); - const list2 = accessor.getRepeatedBytesIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedBytesSize(1); - - expect(size).toEqual(0); - }); - - it('return values from the input', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - const list = accessor.getRepeatedBytesIterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for values', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - const list1 = accessor.getRepeatedBytesIterable(1); - const list2 = accessor.getRepeatedBytesIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addRepeatedBytesElement(1, value1); - const list1 = accessor.getRepeatedBytesIterable(1); - accessor.addRepeatedBytesElement(1, value2); - const list2 = accessor.getRepeatedBytesIterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addRepeatedBytesIterable(1, [value1]); - const list1 = accessor.getRepeatedBytesIterable(1); - accessor.addRepeatedBytesIterable(1, [value2]); - const list2 = accessor.getRepeatedBytesIterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single value', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - accessor.setRepeatedBytesElement(1, 1, value1); - const list = accessor.getRepeatedBytesIterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setRepeatedBytesIterable(1, [value1]); - const list = accessor.getRepeatedBytesIterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addRepeatedBytesElement(1, value1); - accessor.addRepeatedBytesElement(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(repeatedValue1Value2); - }); - - it('encode for adding values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addRepeatedBytesIterable(1, [value1]); - accessor.addRepeatedBytesIterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(repeatedValue1Value2); - }); - - it('encode for setting single value', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - accessor.setRepeatedBytesElement(1, 0, value2); - accessor.setRepeatedBytesElement(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(repeatedValue2Value1); - }); - - it('encode for setting values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setRepeatedBytesIterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(repeatedValue1Value2); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - const result1 = accessor.getRepeatedBytesElement( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedBytesElement( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - const size = accessor.getRepeatedBytesSize(1); - - expect(size).toEqual(2); - }); - - it('fail when getting bytes value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedBytesIterable(1); - }).toThrowError('Expected wire type: 2 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedBytesIterable(1), - (value) => value instanceof ByteString); - } - }); - - it('fail when adding bytes values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeBytes = /** @type {!ByteString} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addRepeatedBytesIterable(1, [fakeBytes])) - .toThrowError('Must be a ByteString, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addRepeatedBytesIterable(1, [fakeBytes]); - expectQualifiedIterable(accessor.getRepeatedBytesIterable(1)); - } - }); - - it('fail when adding single bytes value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeBytes = /** @type {!ByteString} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addRepeatedBytesElement(1, fakeBytes)) - .toThrowError('Must be a ByteString, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addRepeatedBytesElement(1, fakeBytes); - expectQualifiedIterable(accessor.getRepeatedBytesIterable(1)); - } - }); - - it('fail when setting bytes values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeBytes = /** @type {!ByteString} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setRepeatedBytesIterable(1, [fakeBytes])) - .toThrowError('Must be a ByteString, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedBytesIterable(1, [fakeBytes]); - expectQualifiedIterable(accessor.getRepeatedBytesIterable(1)); - } - }); - - it('fail when setting single bytes value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - const fakeBytes = /** @type {!ByteString} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setRepeatedBytesElement(1, 0, fakeBytes)) - .toThrowError('Must be a ByteString, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedBytesElement(1, 0, fakeBytes); - expectQualifiedIterable(accessor.getRepeatedBytesIterable(1)); - } - }); - - it('fail when setting single with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setRepeatedBytesElement(1, 1, value1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedBytesElement(1, 1, value1); - expectQualifiedIterable( - accessor.getRepeatedBytesIterable(1), - (value) => value instanceof ByteString); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedBytesElement( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedBytesElement( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated string does', () => { - const value1 = 'a'; - const value2 = 'b'; - - const repeatedValue1Value2 = createArrayBuffer( - 0x0A, - 0x01, - 0x61, // value1 - 0x0A, - 0x01, - 0x62, // value2 - ); - const repeatedValue2Value1 = createArrayBuffer( - 0x0A, - 0x01, - 0x62, // value2 - 0x0A, - 0x01, - 0x61, // value1 - ); - - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list = accessor.getRepeatedStringIterable(1); - - expectEqualToArray(list, []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const list1 = accessor.getRepeatedStringIterable(1); - const list2 = accessor.getRepeatedStringIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - - const size = accessor.getRepeatedStringSize(1); - - expect(size).toEqual(0); - }); - - it('return values from the input', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - const list = accessor.getRepeatedStringIterable(1); - - expectEqualToArray(list, [value1, value2]); - }); - - it('ensure not the same instance returned for values', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - const list1 = accessor.getRepeatedStringIterable(1); - const list2 = accessor.getRepeatedStringIterable(1); - - expect(list1).not.toBe(list2); - }); - - it('add single value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addRepeatedStringElement(1, value1); - const list1 = accessor.getRepeatedStringIterable(1); - accessor.addRepeatedStringElement(1, value2); - const list2 = accessor.getRepeatedStringIterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('add values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addRepeatedStringIterable(1, [value1]); - const list1 = accessor.getRepeatedStringIterable(1); - accessor.addRepeatedStringIterable(1, [value2]); - const list2 = accessor.getRepeatedStringIterable(1); - - expectEqualToArray(list1, [value1]); - expectEqualToArray(list2, [value1, value2]); - }); - - it('set a single value', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - accessor.setRepeatedStringElement(1, 1, value1); - const list = accessor.getRepeatedStringIterable(1); - - expectEqualToArray(list, [value1, value1]); - }); - - it('set values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setRepeatedStringIterable(1, [value1]); - const list = accessor.getRepeatedStringIterable(1); - - expectEqualToArray(list, [value1]); - }); - - it('encode for adding single value', () => { - const accessor = Kernel.createEmpty(); - - accessor.addRepeatedStringElement(1, value1); - accessor.addRepeatedStringElement(1, value2); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(repeatedValue1Value2); - }); - - it('encode for adding values', () => { - const accessor = Kernel.createEmpty(); - - accessor.addRepeatedStringIterable(1, [value1]); - accessor.addRepeatedStringIterable(1, [value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(repeatedValue1Value2); - }); - - it('encode for setting single value', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - accessor.setRepeatedStringElement(1, 0, value2); - accessor.setRepeatedStringElement(1, 1, value1); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(repeatedValue2Value1); - }); - - it('encode for setting values', () => { - const accessor = Kernel.createEmpty(); - - accessor.setRepeatedStringIterable(1, [value1, value2]); - const serialized = accessor.serialize(); - - expect(serialized).toEqual(repeatedValue1Value2); - }); - - it('return the repeated field element from the input', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - const result1 = accessor.getRepeatedStringElement( - /* fieldNumber= */ 1, /* index= */ 0); - const result2 = accessor.getRepeatedStringElement( - /* fieldNumber= */ 1, /* index= */ 1); - - expect(result1).toEqual(value1); - expect(result2).toEqual(value2); - }); - - it('return the size from the input', () => { - const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); - - const size = accessor.getRepeatedStringSize(1); - - expect(size).toEqual(2); - }); - - it('fail when getting string value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedStringIterable(1); - }).toThrowError('Expected wire type: 2 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expectQualifiedIterable( - accessor.getRepeatedStringIterable(1), - (value) => typeof value === 'string'); - } - }); - - it('fail when adding string values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeString = /** @type {string} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addRepeatedStringIterable(1, [fakeString])) - .toThrowError('Must be string, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addRepeatedStringIterable(1, [fakeString]); - expectQualifiedIterable(accessor.getRepeatedStringIterable(1)); - } - }); - - it('fail when adding single string value with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeString = /** @type {string} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.addRepeatedStringElement(1, fakeString)) - .toThrowError('Must be string, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addRepeatedStringElement(1, fakeString); - expectQualifiedIterable(accessor.getRepeatedStringIterable(1)); - } - }); - - it('fail when setting string values with null value', () => { - const accessor = Kernel.createEmpty(); - const fakeString = /** @type {string} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setRepeatedStringIterable(1, [fakeString])) - .toThrowError('Must be string, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedStringIterable(1, [fakeString]); - expectQualifiedIterable(accessor.getRepeatedStringIterable(1)); - } - }); - - it('fail when setting single string value with null value', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - const fakeString = /** @type {string} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setRepeatedStringElement(1, 0, fakeString)) - .toThrowError('Must be string, but got: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedStringElement(1, 0, fakeString); - expectQualifiedIterable(accessor.getRepeatedStringIterable(1)); - } - }); - - it('fail when setting single with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setRepeatedStringElement(1, 1, value1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedStringElement(1, 1, value1); - expectQualifiedIterable( - accessor.getRepeatedStringIterable(1), - (value) => typeof value === 'string'); - } - }); - - it('fail when getting element with out-of-range index', () => { - const accessor = Kernel.createEmpty(); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedStringElement( - /* fieldNumber= */ 1, /* index= */ 0); - }).toThrowError('Index out of bounds: index: 0 size: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getRepeatedStringElement( - /* fieldNumber= */ 1, /* index= */ 0)) - .toBe(undefined); - } - }); -}); - -describe('Kernel for repeated message does', () => { - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - expectEqualToArray( - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator), - []); - }); - - it('return empty accessor array for the empty input', () => { - const accessor = Kernel.createEmpty(); - expectEqualToArray(accessor.getRepeatedMessageAccessorIterable(1), []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - const list1 = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - const list2 = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - expect(accessor.getRepeatedMessageSize(1, TestMessage.instanceCreator)) - .toEqual(0); - }); - - it('return values from the input', () => { - const bytes1 = createArrayBuffer(0x08, 0x01); - const bytes2 = createArrayBuffer(0x08, 0x00); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expectEqualToMessageArray( - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator), - [msg1, msg2]); - }); - - it('ensure not the same array instance returned', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const list1 = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - const list2 = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - expect(list1).not.toBe(list2); - }); - - it('ensure the same array element returned for get iterable', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const list1 = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - const list2 = accessor.getRepeatedMessageIterable( - 1, TestMessage.instanceCreator, /* pivot= */ 0); - const array1 = Array.from(list1); - const array2 = Array.from(list2); - for (let i = 0; i < array1.length; i++) { - expect(array1[i]).toBe(array2[i]); - } - }); - - it('return accessors from the input', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const [accessor1, accessor2] = - [...accessor.getRepeatedMessageAccessorIterable(1)]; - expect(accessor1.getInt32WithDefault(1)).toEqual(1); - expect(accessor2.getInt32WithDefault(1)).toEqual(0); - }); - - it('return accessors from the input when pivot is set', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const [accessor1, accessor2] = - [...accessor.getRepeatedMessageAccessorIterable(1, /* pivot= */ 0)]; - expect(accessor1.getInt32WithDefault(1)).toEqual(1); - expect(accessor2.getInt32WithDefault(1)).toEqual(0); - }); - - it('return the repeated field element from the input', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg1 = accessor.getRepeatedMessageElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 0); - const msg2 = accessor.getRepeatedMessageElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 1, /* pivot= */ 0); - expect(msg1.getBoolWithDefault( - /* fieldNumber= */ 1, /* default= */ false)) - .toEqual(true); - expect(msg2.getBoolWithDefault( - /* fieldNumber= */ 1, /* default= */ false)) - .toEqual(false); - }); - - it('ensure the same array element returned', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg1 = accessor.getRepeatedMessageElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 0); - const msg2 = accessor.getRepeatedMessageElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 0); - expect(msg1).toBe(msg2); - }); - - it('return the size from the input', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getRepeatedMessageSize(1, TestMessage.instanceCreator)) - .toEqual(2); - }); - - it('encode repeated message from the input', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('add a single value', () => { - const accessor = Kernel.createEmpty(); - const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - - accessor.addRepeatedMessageElement(1, msg1, TestMessage.instanceCreator); - accessor.addRepeatedMessageElement(1, msg2, TestMessage.instanceCreator); - const result = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - - expect(Array.from(result)).toEqual([msg1, msg2]); - }); - - it('add values', () => { - const accessor = Kernel.createEmpty(); - const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - - accessor.addRepeatedMessageIterable(1, [msg1], TestMessage.instanceCreator); - accessor.addRepeatedMessageIterable(1, [msg2], TestMessage.instanceCreator); - const result = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - - expect(Array.from(result)).toEqual([msg1, msg2]); - }); - - it('set a single value', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); - - accessor.setRepeatedMessageElement( - /* fieldNumber= */ 1, submsg, TestMessage.instanceCreator, - /* index= */ 0); - const result = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - - expect(Array.from(result)).toEqual([submsg]); - }); - - it('write submessage changes made via getRepeatedMessagElement', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x05); - const expected = createArrayBuffer(0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const submsg = accessor.getRepeatedMessageElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 0); - expect(submsg.getInt32WithDefault(1, 0)).toEqual(5); - submsg.setInt32(1, 0); - - expect(accessor.serialize()).toEqual(expected); - }); - - it('set values', () => { - const accessor = Kernel.createEmpty(); - const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); - - accessor.setRepeatedMessageIterable(1, [submsg]); - const result = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - - expect(Array.from(result)).toEqual([submsg]); - }); - - it('encode for adding single value', () => { - const accessor = Kernel.createEmpty(); - const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - const expected = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - - accessor.addRepeatedMessageElement(1, msg1, TestMessage.instanceCreator); - accessor.addRepeatedMessageElement(1, msg2, TestMessage.instanceCreator); - const result = accessor.serialize(); - - expect(result).toEqual(expected); - }); - - it('encode for adding values', () => { - const accessor = Kernel.createEmpty(); - const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - const expected = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - - accessor.addRepeatedMessageIterable( - 1, [msg1, msg2], TestMessage.instanceCreator); - const result = accessor.serialize(); - - expect(result).toEqual(expected); - }); - - it('encode for setting single value', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); - const expected = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - - accessor.setRepeatedMessageElement( - /* fieldNumber= */ 1, submsg, TestMessage.instanceCreator, - /* index= */ 0); - const result = accessor.serialize(); - - expect(result).toEqual(expected); - }); - - it('encode for setting values', () => { - const accessor = Kernel.createEmpty(); - const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); - const expected = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - - accessor.setRepeatedMessageIterable(1, [submsg]); - const result = accessor.serialize(); - - expect(result).toEqual(expected); - }); - - it('get accessors from set values.', () => { - const accessor = Kernel.createEmpty(); - const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - - accessor.addRepeatedMessageIterable( - 1, [msg1, msg2], TestMessage.instanceCreator); - - const [accessor1, accessor2] = - [...accessor.getRepeatedMessageAccessorIterable(1)]; - expect(accessor1.getInt32WithDefault(1)).toEqual(1); - expect(accessor2.getInt32WithDefault(1)).toEqual(0); - - // Retrieved accessors are the exact same accessors as the added messages. - expect(accessor1).toBe( - (/** @type {!InternalMessage} */ (msg1)).internalGetKernel()); - expect(accessor2).toBe( - (/** @type {!InternalMessage} */ (msg2)).internalGetKernel()); - }); - - it('fail when getting message value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - }).toThrow(); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const [msg1] = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - expect(msg1.serialize()).toEqual(createArrayBuffer()); - } - }); - - it('fail when adding message values with wrong type value', () => { - const accessor = Kernel.createEmpty(); - const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect( - () => accessor.addRepeatedMessageIterable( - 1, [fakeValue], TestMessage.instanceCreator)) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addRepeatedMessageIterable( - 1, [fakeValue], TestMessage.instanceCreator); - const list = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - expect(Array.from(list)).toEqual([null]); - } - }); - - it('fail when adding single message value with wrong type value', () => { - const accessor = Kernel.createEmpty(); - const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect( - () => accessor.addRepeatedMessageElement( - 1, fakeValue, TestMessage.instanceCreator)) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addRepeatedMessageElement( - 1, fakeValue, TestMessage.instanceCreator); - const list = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - expect(Array.from(list)).toEqual([null]); - } - }); - - it('fail when setting message values with wrong type value', () => { - const accessor = Kernel.createEmpty(); - const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setRepeatedMessageIterable(1, [fakeValue])) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedMessageIterable(1, [fakeValue]); - const list = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - expect(Array.from(list)).toEqual([null]); - } - }); - - it('fail when setting single value with wrong type value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x00)); - const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect( - () => accessor.setRepeatedMessageElement( - /* fieldNumber= */ 1, fakeValue, TestMessage.instanceCreator, - /* index= */ 0)) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedMessageElement( - /* fieldNumber= */ 1, fakeValue, TestMessage.instanceCreator, - /* index= */ 0); - const list = - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); - expect(Array.from(list).length).toEqual(1); - } - }); - - it('fail when setting single value with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x00)); - const msg1 = - accessor.getRepeatedMessageElement(1, TestMessage.instanceCreator, 0); - const bytes2 = createArrayBuffer(0x08, 0x01); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - if (CHECK_CRITICAL_STATE) { - expect( - () => accessor.setRepeatedMessageElement( - /* fieldNumber= */ 1, msg2, TestMessage.instanceCreator, - /* index= */ 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedMessageElement( - /* fieldNumber= */ 1, msg2, TestMessage.instanceCreator, - /* index= */ 1); - expectEqualToArray( - accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator), - [msg1, msg2]); - } - }); -}); - -describe('Kernel for repeated groups does', () => { - it('return empty array for the empty input', () => { - const accessor = Kernel.createEmpty(); - expectEqualToArray( - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator), []); - }); - - it('ensure not the same instance returned for the empty input', () => { - const accessor = Kernel.createEmpty(); - const list1 = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - const list2 = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - expect(list1).not.toBe(list2); - }); - - it('return size for the empty input', () => { - const accessor = Kernel.createEmpty(); - expect(accessor.getRepeatedGroupSize(1, TestMessage.instanceCreator)) - .toEqual(0); - }); - - it('return values from the input', () => { - const bytes1 = createArrayBuffer(0x08, 0x01); - const bytes2 = createArrayBuffer(0x08, 0x02); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - - const bytes = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - expectEqualToMessageArray( - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator), - [msg1, msg2]); - }); - - it('ensure not the same array instance returned', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const list1 = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - const list2 = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - expect(list1).not.toBe(list2); - }); - - it('ensure the same array element returned for get iterable', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const list1 = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - const list2 = accessor.getRepeatedGroupIterable( - 1, TestMessage.instanceCreator, /* pivot= */ 0); - const array1 = Array.from(list1); - const array2 = Array.from(list2); - for (let i = 0; i < array1.length; i++) { - expect(array1[i]).toBe(array2[i]); - } - }); - - it('return accessors from the input', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const [accessor1, accessor2] = - [...accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator)]; - expect(accessor1.getInt32WithDefault(1)).toEqual(1); - expect(accessor2.getInt32WithDefault(1)).toEqual(2); - }); - - it('return accessors from the input when pivot is set', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const [accessor1, accessor2] = [...accessor.getRepeatedGroupIterable( - 1, TestMessage.instanceCreator, /* pivot= */ 0)]; - expect(accessor1.getInt32WithDefault(1)).toEqual(1); - expect(accessor2.getInt32WithDefault(1)).toEqual(2); - }); - - it('return the repeated field element from the input', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg1 = accessor.getRepeatedGroupElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 0); - const msg2 = accessor.getRepeatedGroupElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 1, /* pivot= */ 0); - expect(msg1.getInt32WithDefault( - /* fieldNumber= */ 1, /* default= */ 0)) - .toEqual(1); - expect(msg2.getInt32WithDefault( - /* fieldNumber= */ 1, /* default= */ 0)) - .toEqual(2); - }); - - it('ensure the same array element returned', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg1 = accessor.getRepeatedGroupElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 0); - const msg2 = accessor.getRepeatedGroupElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 0); - expect(msg1).toBe(msg2); - }); - - it('return the size from the input', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getRepeatedGroupSize(1, TestMessage.instanceCreator)) - .toEqual(2); - }); - - it('encode repeated message from the input', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('add a single value', () => { - const accessor = Kernel.createEmpty(); - const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const bytes2 = createArrayBuffer(0x08, 0x02); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - - accessor.addRepeatedGroupElement(1, msg1, TestMessage.instanceCreator); - accessor.addRepeatedGroupElement(1, msg2, TestMessage.instanceCreator); - const result = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - - expect(Array.from(result)).toEqual([msg1, msg2]); - }); - - it('add values', () => { - const accessor = Kernel.createEmpty(); - const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const bytes2 = createArrayBuffer(0x08, 0x02); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - - accessor.addRepeatedGroupIterable(1, [msg1], TestMessage.instanceCreator); - accessor.addRepeatedGroupIterable(1, [msg2], TestMessage.instanceCreator); - const result = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - - expect(Array.from(result)).toEqual([msg1, msg2]); - }); - - it('set a single value', () => { - const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); - - accessor.setRepeatedGroupElement( - /* fieldNumber= */ 1, submsg, TestMessage.instanceCreator, - /* index= */ 0); - const result = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - - expect(Array.from(result)).toEqual([submsg]); - }); - - it('write submessage changes made via getRepeatedGroupElement', () => { - const bytes = createArrayBuffer(0x0B, 0x08, 0x05, 0x0C); - const expected = createArrayBuffer(0x0B, 0x08, 0x00, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const submsg = accessor.getRepeatedGroupElement( - /* fieldNumber= */ 1, TestMessage.instanceCreator, - /* index= */ 0); - expect(submsg.getInt32WithDefault(1, 0)).toEqual(5); - submsg.setInt32(1, 0); - - expect(accessor.serialize()).toEqual(expected); - }); - - it('set values', () => { - const accessor = Kernel.createEmpty(); - const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); - - accessor.setRepeatedGroupIterable(1, [submsg]); - const result = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - - expect(Array.from(result)).toEqual([submsg]); - }); - - it('encode for adding single value', () => { - const accessor = Kernel.createEmpty(); - const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - const expected = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x00, 0x0C); - - accessor.addRepeatedGroupElement(1, msg1, TestMessage.instanceCreator); - accessor.addRepeatedGroupElement(1, msg2, TestMessage.instanceCreator); - const result = accessor.serialize(); - - expect(result).toEqual(expected); - }); - - it('encode for adding values', () => { - const accessor = Kernel.createEmpty(); - const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); - const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - const expected = - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x00, 0x0C); - - accessor.addRepeatedGroupIterable( - 1, [msg1, msg2], TestMessage.instanceCreator); - const result = accessor.serialize(); - - expect(result).toEqual(expected); - }); - - it('encode for setting single value', () => { - const bytes = createArrayBuffer(0x0B, 0x08, 0x00, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); - const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); - - accessor.setRepeatedGroupElement( - /* fieldNumber= */ 1, submsg, TestMessage.instanceCreator, - /* index= */ 0); - const result = accessor.serialize(); - - expect(result).toEqual(expected); - }); - - it('encode for setting values', () => { - const accessor = Kernel.createEmpty(); - const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); - const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); - - accessor.setRepeatedGroupIterable(1, [submsg]); - const result = accessor.serialize(); - - expect(result).toEqual(expected); - }); - - it('fail when getting groups value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - - if (CHECK_CRITICAL_STATE) { - expect(() => { - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - }).toThrow(); - } - }); - - it('fail when adding group values with wrong type value', () => { - const accessor = Kernel.createEmpty(); - const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect( - () => accessor.addRepeatedGroupIterable( - 1, [fakeValue], TestMessage.instanceCreator)) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addRepeatedGroupIterable( - 1, [fakeValue], TestMessage.instanceCreator); - const list = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - expect(Array.from(list)).toEqual([null]); - } - }); - - it('fail when adding single group value with wrong type value', () => { - const accessor = Kernel.createEmpty(); - const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect( - () => accessor.addRepeatedGroupElement( - 1, fakeValue, TestMessage.instanceCreator)) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.addRepeatedGroupElement( - 1, fakeValue, TestMessage.instanceCreator); - const list = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - expect(Array.from(list)).toEqual([null]); - } - }); - - it('fail when setting message values with wrong type value', () => { - const accessor = Kernel.createEmpty(); - const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect(() => accessor.setRepeatedGroupIterable(1, [fakeValue])) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedGroupIterable(1, [fakeValue]); - const list = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - expect(Array.from(list)).toEqual([null]); - } - }); - - it('fail when setting single value with wrong type value', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0B, 0x08, 0x00, 0x0C)); - const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_STATE) { - expect( - () => accessor.setRepeatedGroupElement( - /* fieldNumber= */ 1, fakeValue, TestMessage.instanceCreator, - /* index= */ 0)) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedGroupElement( - /* fieldNumber= */ 1, fakeValue, TestMessage.instanceCreator, - /* index= */ 0); - const list = - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); - expect(Array.from(list).length).toEqual(1); - } - }); - - it('fail when setting single value with out-of-bound index', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0B, 0x08, 0x00, 0x0C)); - const msg1 = - accessor.getRepeatedGroupElement(1, TestMessage.instanceCreator, 0); - const bytes2 = createArrayBuffer(0x08, 0x01); - const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); - if (CHECK_CRITICAL_STATE) { - expect( - () => accessor.setRepeatedGroupElement( - /* fieldNumber= */ 1, msg2, TestMessage.instanceCreator, - /* index= */ 1)) - .toThrowError('Index out of bounds: index: 1 size: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setRepeatedGroupElement( - /* fieldNumber= */ 1, msg2, TestMessage.instanceCreator, - /* index= */ 1); - expectEqualToArray( - accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator), - [msg1, msg2]); - } - }); -}); diff --git a/js/experimental/runtime/kernel/kernel_test.js b/js/experimental/runtime/kernel/kernel_test.js deleted file mode 100644 index eba7c4a55..000000000 --- a/js/experimental/runtime/kernel/kernel_test.js +++ /dev/null @@ -1,2329 +0,0 @@ -/** - * @fileoverview Tests for kernel.js. - */ -goog.module('protobuf.runtime.KernelTest'); - -goog.setTestOnly(); - -const ByteString = goog.require('protobuf.ByteString'); -const Int64 = goog.require('protobuf.Int64'); -const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const Kernel = goog.require('protobuf.runtime.Kernel'); -const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); -// Note to the reader: -// Since the lazy accessor behavior changes with the checking level some of the -// tests in this file have to know which checking level is enable to make -// correct assertions. -const {CHECK_BOUNDS, CHECK_CRITICAL_STATE, CHECK_CRITICAL_TYPE, CHECK_TYPE, MAX_FIELD_NUMBER} = goog.require('protobuf.internal.checks'); - -/** - * @param {...number} bytes - * @return {!ArrayBuffer} - */ -function createArrayBuffer(...bytes) { - return new Uint8Array(bytes).buffer; -} - -describe('Kernel', () => { - it('encodes none for the empty input', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); - }); - - it('encodes and decodes max field number', () => { - const accessor = Kernel.fromArrayBuffer( - createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0x01)); - expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toBe(true); - accessor.setBool(MAX_FIELD_NUMBER, false); - expect(accessor.serialize()) - .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0x00)); - }); - - it('uses the default pivot point', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - expect(accessor.getPivot()).toBe(24); - }); - - it('makes the pivot point configurable', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0), 50); - expect(accessor.getPivot()).toBe(50); - }); -}); - -describe('Kernel hasFieldNumber', () => { - it('returns false for empty input', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - expect(accessor.hasFieldNumber(1)).toBe(false); - }); - - it('returns true for non-empty input', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.hasFieldNumber(1)).toBe(true); - }); - - it('returns false for empty array', () => { - const accessor = Kernel.createEmpty(); - accessor.setPackedBoolIterable(1, []); - expect(accessor.hasFieldNumber(1)).toBe(false); - }); - - it('returns true for non-empty array', () => { - const accessor = Kernel.createEmpty(); - accessor.setPackedBoolIterable(1, [true]); - expect(accessor.hasFieldNumber(1)).toBe(true); - }); - - it('updates value after write', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - expect(accessor.hasFieldNumber(1)).toBe(false); - accessor.setBool(1, false); - expect(accessor.hasFieldNumber(1)).toBe(true); - }); -}); - -describe('Kernel clear field does', () => { - it('clear the field set', () => { - const accessor = Kernel.createEmpty(); - accessor.setBool(1, true); - accessor.clearField(1); - - expect(accessor.hasFieldNumber(1)).toEqual(false); - expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); - expect(accessor.getBoolWithDefault(1)).toEqual(false); - }); - - it('clear the field decoded', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.clearField(1); - - expect(accessor.hasFieldNumber(1)).toEqual(false); - expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); - expect(accessor.getBoolWithDefault(1)).toEqual(false); - }); - - it('clear the field read', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getBoolWithDefault(1)).toEqual(true); - accessor.clearField(1); - - expect(accessor.hasFieldNumber(1)).toEqual(false); - expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); - expect(accessor.getBoolWithDefault(1)).toEqual(false); - }); - - it('clear set and copied fields without affecting the old', () => { - const accessor = Kernel.createEmpty(); - accessor.setBool(1, true); - - const clonedAccessor = accessor.shallowCopy(); - clonedAccessor.clearField(1); - - expect(accessor.hasFieldNumber(1)).toEqual(true); - expect(accessor.getBoolWithDefault(1)).toEqual(true); - expect(clonedAccessor.hasFieldNumber(1)).toEqual(false); - expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); - expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); - }); - - it('clear decoded and copied fields without affecting the old', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - - const clonedAccessor = accessor.shallowCopy(); - clonedAccessor.clearField(1); - - expect(accessor.hasFieldNumber(1)).toEqual(true); - expect(accessor.getBoolWithDefault(1)).toEqual(true); - expect(clonedAccessor.hasFieldNumber(1)).toEqual(false); - expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); - expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); - }); - - it('clear read and copied fields without affecting the old', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getBoolWithDefault(1)).toEqual(true); - - const clonedAccessor = accessor.shallowCopy(); - clonedAccessor.clearField(1); - - expect(accessor.hasFieldNumber(1)).toEqual(true); - expect(accessor.getBoolWithDefault(1)).toEqual(true); - expect(clonedAccessor.hasFieldNumber(1)).toEqual(false); - expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); - expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); - }); - - it('clear the max field number', () => { - const accessor = Kernel.createEmpty(); - accessor.setBool(MAX_FIELD_NUMBER, true); - - accessor.clearField(MAX_FIELD_NUMBER); - - expect(accessor.hasFieldNumber(MAX_FIELD_NUMBER)).toEqual(false); - expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(false); - }); -}); - -describe('Kernel shallow copy does', () => { - it('work for singular fields', () => { - const accessor = Kernel.createEmpty(); - accessor.setBool(1, true); - accessor.setBool(MAX_FIELD_NUMBER, true); - const clonedAccessor = accessor.shallowCopy(); - expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); - expect(clonedAccessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(true); - - accessor.setBool(1, false); - accessor.setBool(MAX_FIELD_NUMBER, false); - expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); - expect(clonedAccessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(true); - }); - - it('work for repeated fields', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedBoolIterable(2, [true, true]); - - const clonedAccessor = accessor.shallowCopy(); - - // Modify a repeated field after clone - accessor.addUnpackedBoolElement(2, true); - - const array = Array.from(clonedAccessor.getRepeatedBoolIterable(2)); - expect(array).toEqual([true, true]); - }); - - it('work for repeated fields', () => { - const accessor = Kernel.createEmpty(); - - accessor.addUnpackedBoolIterable(2, [true, true]); - - const clonedAccessor = accessor.shallowCopy(); - - // Modify a repeated field after clone - accessor.addUnpackedBoolElement(2, true); - - const array = Array.from(clonedAccessor.getRepeatedBoolIterable(2)); - expect(array).toEqual([true, true]); - }); - - it('return the correct bytes after serialization', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x10, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes, /* pivot= */ 1); - const clonedAccessor = accessor.shallowCopy(); - - accessor.setBool(1, false); - - expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); - expect(clonedAccessor.serialize()).toEqual(bytes); - }); -}); - -describe('Kernel for singular boolean does', () => { - it('return false for the empty input', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - expect(accessor.getBoolWithDefault( - /* fieldNumber= */ 1)) - .toBe(false); - }); - - it('return the value from the input', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getBoolWithDefault( - /* fieldNumber= */ 1)) - .toBe(true); - }); - - it('encode the value from the input', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode the value from the input after read', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.getBoolWithDefault( - /* fieldNumber= */ 1); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('return the value from multiple inputs', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getBoolWithDefault( - /* fieldNumber= */ 1)) - .toBe(false); - }); - - it('encode the value from multiple inputs', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode the value from multiple inputs after read', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.getBoolWithDefault(/* fieldNumber= */ 1); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('return the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setBool(1, true); - expect(accessor.getBoolWithDefault( - /* fieldNumber= */ 1)) - .toBe(true); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x08, 0x01); - accessor.setBool(1, true); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('return the bool value from cache', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getBoolWithDefault( - /* fieldNumber= */ 1)) - .toBe(true); - // Make sure the value is cached. - bytes[1] = 0x00; - expect(accessor.getBoolWithDefault( - /* fieldNumber= */ 1)) - .toBe(true); - }); - - it('fail when getting bool value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getBoolWithDefault(/* fieldNumber= */ 1); - }).toThrowError('Expected wire type: 0 but found: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getBoolWithDefault( - /* fieldNumber= */ 1)) - .toBe(true); - } - }); - - it('fail when setting bool value with out-of-range field number', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - if (CHECK_TYPE) { - expect(() => accessor.setBool(MAX_FIELD_NUMBER + 1, false)) - .toThrowError('Field number is out of range: 536870912'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setBool(MAX_FIELD_NUMBER + 1, false); - expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER + 1)).toBe(false); - } - }); - - it('fail when setting bool value with number value', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); - if (CHECK_CRITICAL_TYPE) { - expect(() => accessor.setBool(1, fakeBoolean)) - .toThrowError('Must be a boolean, but got: 2'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setBool(1, fakeBoolean); - expect(accessor.getBoolWithDefault( - /* fieldNumber= */ 1)) - .toBe(2); - } - }); -}); - -describe('Kernel for singular message does', () => { - it('return message from the input', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); - expect(msg.getBoolWithDefault(1, false)).toBe(true); - }); - - it('return message from the input when pivot is set', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes, /* pivot= */ 0); - const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); - expect(msg.getBoolWithDefault(1, false)).toBe(true); - }); - - it('encode message from the input', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode message from the input after read', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.getMessageOrNull(1, TestMessage.instanceCreator); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('return message from multiple inputs', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); - expect(msg.getBoolWithDefault(1, false)).toBe(true); - expect(msg.getBoolWithDefault(2, false)).toBe(true); - }); - - it('encode message from multiple inputs', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode message merged from multiple inputs after read', () => { - const bytes = - createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); - const expected = createArrayBuffer(0x0A, 0x04, 0x08, 0x01, 0x10, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.getMessageOrNull(1, TestMessage.instanceCreator); - expect(accessor.serialize()).toEqual(expected); - }); - - it('return null for generic accessor', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const accessor1 = accessor.getMessageAccessorOrNull(7); - expect(accessor1).toBe(null); - }); - - it('return null for generic accessor when pivot is set', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const accessor1 = accessor.getMessageAccessorOrNull(7, /* pivot= */ 0); - expect(accessor1).toBe(null); - }); - - it('return generic accessor from the input', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const accessor1 = accessor.getMessageAccessorOrNull(1); - expect(accessor1.getBoolWithDefault(1, false)).toBe(true); - // Second call returns a new instance, isn't cached. - const accessor2 = accessor.getMessageAccessorOrNull(1); - expect(accessor2.getBoolWithDefault(1, false)).toBe(true); - expect(accessor2).not.toBe(accessor1); - }); - - it('return generic accessor from the cached input', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const wrappedMessage = - accessor.getMessageOrNull(1, TestMessage.instanceCreator); - - // Returns accessor from the cached wrapper instance. - const accessor1 = accessor.getMessageAccessorOrNull(1); - expect(accessor1.getBoolWithDefault(1, false)).toBe(true); - expect(accessor1).toBe( - (/** @type {!InternalMessage} */ (wrappedMessage)).internalGetKernel()); - - // Second call returns exact same instance. - const accessor2 = accessor.getMessageAccessorOrNull(1); - expect(accessor2.getBoolWithDefault(1, false)).toBe(true); - expect(accessor2).toBe( - (/** @type {!InternalMessage} */ (wrappedMessage)).internalGetKernel()); - expect(accessor2).toBe(accessor1); - }); - - it('return message from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const subaccessor = Kernel.fromArrayBuffer(bytes); - const submsg1 = new TestMessage(subaccessor); - accessor.setMessage(1, submsg1); - const submsg2 = accessor.getMessage(1, TestMessage.instanceCreator); - expect(submsg1).toBe(submsg2); - }); - - it('encode message from setter', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const subaccessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const subsubaccessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); - const subsubmsg = new TestMessage(subsubaccessor); - subaccessor.setMessage(1, subsubmsg); - const submsg = new TestMessage(subaccessor); - accessor.setMessage(1, submsg); - const expected = createArrayBuffer(0x0A, 0x04, 0x0A, 0x02, 0x08, 0x01); - expect(accessor.serialize()).toEqual(expected); - }); - - it('encode message with multiple submessage from setter', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const subaccessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const subsubaccessor1 = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); - const subsubaccessor2 = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); - - const subsubmsg1 = new TestMessage(subsubaccessor1); - const subsubmsg2 = new TestMessage(subsubaccessor2); - - subaccessor.setMessage(1, subsubmsg1); - subaccessor.setMessage(2, subsubmsg2); - - const submsg = new TestMessage(subaccessor); - accessor.setMessage(1, submsg); - - const expected = createArrayBuffer( - 0x0A, 0x08, 0x0A, 0x02, 0x08, 0x01, 0x12, 0x02, 0x08, 0x02); - expect(accessor.serialize()).toEqual(expected); - }); - - it('leave hasFieldNumber unchanged after getMessageOrNull', () => { - const accessor = Kernel.createEmpty(); - expect(accessor.hasFieldNumber(1)).toBe(false); - expect(accessor.getMessageOrNull(1, TestMessage.instanceCreator)) - .toBe(null); - expect(accessor.hasFieldNumber(1)).toBe(false); - }); - - it('serialize changes to submessages made with getMessageOrNull', () => { - const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - const mutableSubMessage = - accessor.getMessageOrNull(1, TestMessage.instanceCreator); - mutableSubMessage.setInt32(1, 10); - const intTenBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x0A); - expect(accessor.serialize()).toEqual(intTenBytes); - }); - - it('serialize additions to submessages made with getMessageOrNull', () => { - const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - const mutableSubMessage = - accessor.getMessageOrNull(1, TestMessage.instanceCreator); - mutableSubMessage.setInt32(2, 3); - // Sub message contains the original field, plus the new one. - expect(accessor.serialize()) - .toEqual(createArrayBuffer(0x0A, 0x04, 0x08, 0x02, 0x10, 0x03)); - }); - - it('fail with getMessageOrNull if immutable message exist in cache', () => { - const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - - const readOnly = accessor.getMessage(1, TestMessage.instanceCreator); - if (CHECK_TYPE) { - expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) - .toThrow(); - } else { - const mutableSubMessage = - accessor.getMessageOrNull(1, TestMessage.instanceCreator); - // The instance returned by getMessageOrNull is the exact same instance. - expect(mutableSubMessage).toBe(readOnly); - - // Serializing the submessage does not write the changes - mutableSubMessage.setInt32(1, 0); - expect(accessor.serialize()).toEqual(intTwoBytes); - } - }); - - it('change hasFieldNumber after getMessageAttach', () => { - const accessor = Kernel.createEmpty(); - expect(accessor.hasFieldNumber(1)).toBe(false); - expect(accessor.getMessageAttach(1, TestMessage.instanceCreator)) - .not.toBe(null); - expect(accessor.hasFieldNumber(1)).toBe(true); - }); - - it('change hasFieldNumber after getMessageAttach when pivot is set', () => { - const accessor = Kernel.createEmpty(); - expect(accessor.hasFieldNumber(1)).toBe(false); - expect(accessor.getMessageAttach( - 1, TestMessage.instanceCreator, /* pivot= */ 1)) - .not.toBe(null); - expect(accessor.hasFieldNumber(1)).toBe(true); - }); - - it('serialize submessages made with getMessageAttach', () => { - const accessor = Kernel.createEmpty(); - const mutableSubMessage = - accessor.getMessageAttach(1, TestMessage.instanceCreator); - mutableSubMessage.setInt32(1, 10); - const intTenBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x0A); - expect(accessor.serialize()).toEqual(intTenBytes); - }); - - it('serialize additions to submessages using getMessageAttach', () => { - const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - const mutableSubMessage = - accessor.getMessageAttach(1, TestMessage.instanceCreator); - mutableSubMessage.setInt32(2, 3); - // Sub message contains the original field, plus the new one. - expect(accessor.serialize()) - .toEqual(createArrayBuffer(0x0A, 0x04, 0x08, 0x02, 0x10, 0x03)); - }); - - it('fail with getMessageAttach if immutable message exist in cache', () => { - const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - - const readOnly = accessor.getMessage(1, TestMessage.instanceCreator); - if (CHECK_TYPE) { - expect(() => accessor.getMessageAttach(1, TestMessage.instanceCreator)) - .toThrow(); - } else { - const mutableSubMessage = - accessor.getMessageAttach(1, TestMessage.instanceCreator); - // The instance returned by getMessageOrNull is the exact same instance. - expect(mutableSubMessage).toBe(readOnly); - - // Serializing the submessage does not write the changes - mutableSubMessage.setInt32(1, 0); - expect(accessor.serialize()).toEqual(intTwoBytes); - } - }); - - it('read default message return empty message with getMessage', () => { - const bytes = new ArrayBuffer(0); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getMessage(1, TestMessage.instanceCreator)).toBeTruthy(); - expect(accessor.getMessage(1, TestMessage.instanceCreator).serialize()) - .toEqual(bytes); - }); - - it('read default message return null with getMessageOrNull', () => { - const bytes = new ArrayBuffer(0); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getMessageOrNull(1, TestMessage.instanceCreator)) - .toBe(null); - }); - - it('read message preserve reference equality', () => { - const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg1 = accessor.getMessageOrNull(1, TestMessage.instanceCreator); - const msg2 = accessor.getMessageOrNull(1, TestMessage.instanceCreator); - const msg3 = accessor.getMessageAttach(1, TestMessage.instanceCreator); - expect(msg1).toBe(msg2); - expect(msg1).toBe(msg3); - }); - - it('fail when getting message with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); - expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) - .toThrow(); - }); - - it('fail when submessage has incomplete data', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); - expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) - .toThrow(); - }); - - it('fail when mutable submessage has incomplete data', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); - expect(() => accessor.getMessageAttach(1, TestMessage.instanceCreator)) - .toThrow(); - }); - - it('fail when getting message with null instance constructor', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x01)); - const nullMessage = /** @type {function(!Kernel):!TestMessage} */ - (/** @type {*} */ (null)); - expect(() => accessor.getMessageOrNull(1, nullMessage)).toThrow(); - }); - - it('fail when setting message value with null value', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const fakeMessage = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_TYPE) { - expect(() => accessor.setMessage(1, fakeMessage)) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setMessage(1, fakeMessage); - expect(accessor.getMessageOrNull( - /* fieldNumber= */ 1, TestMessage.instanceCreator)) - .toBeNull(); - } - }); -}); - -describe('Bytes access', () => { - const simpleByteString = ByteString.fromArrayBuffer(createArrayBuffer(1)); - - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getBytesWithDefault(1)).toEqual(ByteString.EMPTY); - }); - - it('returns the default from parameter', () => { - const defaultByteString = ByteString.fromArrayBuffer(createArrayBuffer(1)); - const returnValue = ByteString.fromArrayBuffer(createArrayBuffer(1)); - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getBytesWithDefault(1, defaultByteString)) - .toEqual(returnValue); - }); - - it('decodes value from wire', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x01)); - expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = Kernel.fromArrayBuffer( - createArrayBuffer(0x0A, 0x01, 0x00, 0x0A, 0x01, 0x01)); - expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); - }); - - it('fails when getting value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getBytesWithDefault(1); - }).toThrowError('Expected wire type: 2 but found: 1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const arrayBuffer = createArrayBuffer(1); - expect(accessor.getBytesWithDefault(1)) - .toEqual(ByteString.fromArrayBuffer(arrayBuffer)); - } - }); - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect( - () => Kernel.createEmpty().getBytesWithDefault(-1, simpleByteString)) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getBytesWithDefault(-1, simpleByteString)) - .toEqual(simpleByteString); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x0A, 0x01, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setBytes(1, simpleByteString); - expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x0A, 0x01, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x0A, 0x01, 0x01); - accessor.setBytes(1, simpleByteString); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = createArrayBuffer(0x0A, 0x01, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setBytes(-1, simpleByteString)) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setBytes(-1, simpleByteString); - expect(accessor.getBytesWithDefault(-1)).toEqual(simpleByteString); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setBytes( - 1, /** @type {!ByteString} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setBytes( - 1, /** @type {!ByteString} */ (/** @type {*} */ (null))); - expect(accessor.getBytesWithDefault(1)).toEqual(null); - } - }); -}); - -describe('Fixed32 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getFixed32WithDefault(1)).toEqual(0); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getFixed32WithDefault(1, 2)).toEqual(2); - }); - - it('decodes value from wire', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); - expect(accessor.getFixed32WithDefault(1)).toEqual(1); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); - expect(accessor.getFixed32WithDefault(1)).toEqual(2); - }); - - it('fails when getting value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getFixed32WithDefault(1); - }).toThrowError('Expected wire type: 5 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getFixed32WithDefault(1)).toEqual(8421504); - } - }); - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().getFixed32WithDefault(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getFixed32WithDefault(-1, 1)).toEqual(1); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setFixed32(1, 2); - expect(accessor.getFixed32WithDefault(1)).toEqual(2); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); - accessor.setFixed32(1, 0); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getFixed32WithDefault(1)).toBe(1); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getFixed32WithDefault(1)).toBe(1); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setFixed32(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setFixed32(-1, 1); - expect(accessor.getFixed32WithDefault(-1)).toEqual(1); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setFixed32( - 1, /** @type {number} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setFixed32(1, /** @type {number} */ (/** @type {*} */ (null))); - expect(accessor.getFixed32WithDefault(1)).toEqual(null); - } - }); - - it('throws in setter for negative value', () => { - if (CHECK_CRITICAL_TYPE) { - expect(() => Kernel.createEmpty().setFixed32(1, -1)).toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setFixed32(1, -1); - expect(accessor.getFixed32WithDefault(1)).toEqual(-1); - } - }); -}); - -describe('Fixed64 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(0)); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getFixed64WithDefault(1, Int64.fromInt(2))) - .toEqual(Int64.fromInt(2)); - }); - - it('decodes value from wire', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(2)); - }); - - if (CHECK_CRITICAL_STATE) { - it('fails when getting value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - expect(() => { - accessor.getFixed64WithDefault(1); - }).toThrow(); - }); - } - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect( - () => - Kernel.createEmpty().getFixed64WithDefault(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getFixed64WithDefault(-1, Int64.fromInt(1))) - .toEqual(Int64.fromInt(1)); - } - }); - - it('returns the value from setter', () => { - const bytes = - createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setFixed64(1, Int64.fromInt(2)); - expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(2)); - }); - - it('encode the value from setter', () => { - const bytes = - createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = - createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - accessor.setFixed64(1, Int64.fromInt(0)); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = - createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setFixed64(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setFixed64(-1, Int64.fromInt(1)); - expect(accessor.getFixed64WithDefault(-1)).toEqual(Int64.fromInt(1)); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setSfixed64( - 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setFixed64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); - expect(accessor.getFixed64WithDefault(1)).toEqual(null); - } - }); -}); - -describe('Float access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getFloatWithDefault(1)).toEqual(0); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getFloatWithDefault(1, 2)).toEqual(2); - }); - - it('decodes value from wire', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F)); - expect(accessor.getFloatWithDefault(1)).toEqual(1); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x0D, 0x00, 0x00, 0x80, 0x3F, 0x0D, 0x00, 0x00, 0x80, 0xBF)); - expect(accessor.getFloatWithDefault(1)).toEqual(-1); - }); - - if (CHECK_CRITICAL_STATE) { - it('fails when getting float value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F)); - expect(() => { - accessor.getFloatWithDefault(1); - }).toThrow(); - }); - } - - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().getFloatWithDefault(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getFloatWithDefault(-1, 1)).toEqual(1); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setFloat(1, 1.6); - expect(accessor.getFloatWithDefault(1)).toEqual(Math.fround(1.6)); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); - accessor.setFloat(1, 0); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns float value from cache', () => { - const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getFloatWithDefault(1)).toBe(1); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getFloatWithDefault(1)).toBe(1); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setFloat(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setFloat(-1, 1); - expect(accessor.getFloatWithDefault(-1)).toEqual(1); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setFloat( - 1, /** @type {number} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setFloat(1, /** @type {number} */ (/** @type {*} */ (null))); - expect(accessor.getFloatWithDefault(1)).toEqual(0); - } - }); - - it('throws in setter for value outside of float32 precision', () => { - if (CHECK_CRITICAL_TYPE) { - expect(() => Kernel.createEmpty().setFloat(1, Number.MAX_VALUE)) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setFloat(1, Number.MAX_VALUE); - expect(accessor.getFloatWithDefault(1)).toEqual(Infinity); - } - }); -}); - -describe('Int32 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getInt32WithDefault(1)).toEqual(0); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getInt32WithDefault(1, 2)).toEqual(2); - }); - - it('decodes value from wire', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); - expect(accessor.getInt32WithDefault(1)).toEqual(1); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); - expect(accessor.getInt32WithDefault(1)).toEqual(2); - }); - - it('fails when getting value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getInt32WithDefault(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getInt32WithDefault(1)).toEqual(0); - } - }); - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().getInt32WithDefault(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getInt32WithDefault(-1, 1)).toEqual(1); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setInt32(1, 2); - expect(accessor.getInt32WithDefault(1)).toEqual(2); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x08, 0x00); - accessor.setInt32(1, 0); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getInt32WithDefault(1)).toBe(1); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getInt32WithDefault(1)).toBe(1); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setInt32(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setInt32(-1, 1); - expect(accessor.getInt32WithDefault(-1)).toEqual(1); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setInt32( - 1, /** @type {number} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setInt32(1, /** @type {number} */ (/** @type {*} */ (null))); - expect(accessor.getInt32WithDefault(1)).toEqual(null); - } - }); -}); - -describe('Int64 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(0)); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getInt64WithDefault(1, Int64.fromInt(2))) - .toEqual(Int64.fromInt(2)); - }); - - it('decodes value from wire', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); - expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); - expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2)); - }); - - it('fails when getting value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getInt64WithDefault(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(0)); - } - }); - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect( - () => Kernel.createEmpty().getInt64WithDefault(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getInt64WithDefault(-1, Int64.fromInt(1))) - .toEqual(Int64.fromInt(1)); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setInt64(1, Int64.fromInt(2)); - expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2)); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x08, 0x00); - accessor.setInt64(1, Int64.fromInt(0)); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setInt64(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setInt64(-1, Int64.fromInt(1)); - expect(accessor.getInt64WithDefault(-1)).toEqual(Int64.fromInt(1)); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setInt64( - 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setInt64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); - expect(accessor.getInt64WithDefault(1)).toEqual(null); - } - }); -}); - -describe('Sfixed32 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getSfixed32WithDefault(1)).toEqual(0); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getSfixed32WithDefault(1, 2)).toEqual(2); - }); - - it('decodes value from wire', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); - expect(accessor.getSfixed32WithDefault(1)).toEqual(1); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); - expect(accessor.getSfixed32WithDefault(1)).toEqual(2); - }); - - it('fails when getting value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getSfixed32WithDefault(1); - }).toThrowError('Expected wire type: 5 but found: 0'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getSfixed32WithDefault(1)).toEqual(8421504); - } - }); - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().getSfixed32WithDefault(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getSfixed32WithDefault(-1, 1)).toEqual(1); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setSfixed32(1, 2); - expect(accessor.getSfixed32WithDefault(1)).toEqual(2); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); - accessor.setSfixed32(1, 0); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getSfixed32WithDefault(1)).toBe(1); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getSfixed32WithDefault(1)).toBe(1); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setSfixed32(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setSfixed32(-1, 1); - expect(accessor.getSfixed32WithDefault(-1)).toEqual(1); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setSfixed32( - 1, /** @type {number} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setSfixed32(1, /** @type {number} */ (/** @type {*} */ (null))); - expect(accessor.getSfixed32WithDefault(1)).toEqual(null); - } - }); -}); - -describe('Sfixed64 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(0)); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getSfixed64WithDefault(1, Int64.fromInt(2))) - .toEqual(Int64.fromInt(2)); - }); - - it('decodes value from wire', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(2)); - }); - - if (CHECK_CRITICAL_STATE) { - it('fails when getting value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - expect(() => { - accessor.getSfixed64WithDefault(1); - }).toThrow(); - }); - } - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect( - () => - Kernel.createEmpty().getSfixed64WithDefault(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getSfixed64WithDefault(-1, Int64.fromInt(1))) - .toEqual(Int64.fromInt(1)); - } - }); - - it('returns the value from setter', () => { - const bytes = - createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setSfixed64(1, Int64.fromInt(2)); - expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(2)); - }); - - it('encode the value from setter', () => { - const bytes = - createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = - createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - accessor.setSfixed64(1, Int64.fromInt(0)); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = - createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setSfixed64(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setSfixed64(-1, Int64.fromInt(1)); - expect(accessor.getSfixed64WithDefault(-1)).toEqual(Int64.fromInt(1)); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setSfixed64( - 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setSfixed64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); - expect(accessor.getSfixed64WithDefault(1)).toEqual(null); - } - }); -}); - -describe('Sint32 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getSint32WithDefault(1)).toEqual(0); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getSint32WithDefault(1, 2)).toEqual(2); - }); - - it('decodes value from wire', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); - expect(accessor.getSint32WithDefault(1)).toEqual(1); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x03, 0x08, 0x02)); - expect(accessor.getSint32WithDefault(1)).toEqual(1); - }); - - it('fails when getting value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getSint32WithDefault(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getSint32WithDefault(1)).toEqual(0); - } - }); - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().getSint32WithDefault(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getSint32WithDefault(-1, 1)).toEqual(1); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setSint32(1, 2); - expect(accessor.getSint32WithDefault(1)).toEqual(2); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x08, 0x00); - accessor.setSint32(1, 0); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = createArrayBuffer(0x08, 0x02); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getSint32WithDefault(1)).toBe(1); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getSint32WithDefault(1)).toBe(1); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setSint32(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setSint32(-1, 1); - expect(accessor.getSint32WithDefault(-1)).toEqual(1); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setSint32( - 1, /** @type {number} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setSint32(1, /** @type {number} */ (/** @type {*} */ (null))); - expect(accessor.getSint32WithDefault(1)).toEqual(null); - } - }); -}); - -describe('SInt64 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(0)); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getSint64WithDefault(1, Int64.fromInt(2))) - .toEqual(Int64.fromInt(2)); - }); - - it('decodes value from wire', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); - expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); - expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('fails when getting value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getSint64WithDefault(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(0)); - } - }); - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect( - () => Kernel.createEmpty().getSint64WithDefault(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getSint64WithDefault(-1, Int64.fromInt(1))) - .toEqual(Int64.fromInt(1)); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setSint64(1, Int64.fromInt(2)); - expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(2)); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x08, 0x00); - accessor.setSint64(1, Int64.fromInt(0)); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = createArrayBuffer(0x08, 0x02); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); - // Make sure the value is cached. - bytes[1] = 0x00; - expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setSint64(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setInt64(-1, Int64.fromInt(1)); - expect(accessor.getSint64WithDefault(-1)).toEqual(Int64.fromInt(1)); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setSint64( - 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setSint64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); - expect(accessor.getSint64WithDefault(1)).toEqual(null); - } - }); -}); - -describe('String access', () => { - it('returns empty string for the empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getStringWithDefault(1)).toEqual(''); - }); - - it('returns the default for the empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getStringWithDefault(1, 'bar')).toEqual('bar'); - }); - - it('decodes value from wire', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); - expect(accessor.getStringWithDefault(1)).toEqual('a'); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = Kernel.fromArrayBuffer( - createArrayBuffer(0x0A, 0x01, 0x60, 0x0A, 0x01, 0x61)); - expect(accessor.getStringWithDefault(1)).toEqual('a'); - }); - - if (CHECK_CRITICAL_STATE) { - it('fails when getting string value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02, 0x08, 0x08)); - expect(() => { - accessor.getStringWithDefault(1); - }).toThrow(); - }); - } - - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().getStringWithDefault(-1, 'a')) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getStringWithDefault(-1, 'a')).toEqual('a'); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x0A, 0x01, 0x61); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setString(1, 'b'); - expect(accessor.getStringWithDefault(1)).toEqual('b'); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x0A, 0x01, 0x61); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x0A, 0x01, 0x62); - accessor.setString(1, 'b'); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns string value from cache', () => { - const bytes = createArrayBuffer(0x0A, 0x01, 0x61); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getStringWithDefault(1)).toBe('a'); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getStringWithDefault(1)).toBe('a'); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_TYPE) { - expect(() => Kernel.createEmpty().setString(-1, 'a')) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setString(-1, 'a'); - expect(accessor.getStringWithDefault(-1)).toEqual('a'); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setString( - 1, /** @type {string} */ (/** @type {*} */ (null)))) - .toThrowError('Must be string, but got: null'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setString(1, /** @type {string} */ (/** @type {*} */ (null))); - expect(accessor.getStringWithDefault(1)).toEqual(null); - } - }); -}); - -describe('Uint32 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getUint32WithDefault(1)).toEqual(0); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getUint32WithDefault(1, 2)).toEqual(2); - }); - - it('decodes value from wire', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); - expect(accessor.getUint32WithDefault(1)).toEqual(1); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); - expect(accessor.getUint32WithDefault(1)).toEqual(2); - }); - - it('fails when getting value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getUint32WithDefault(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getUint32WithDefault(1)).toEqual(0); - } - }); - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().getUint32WithDefault(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getUint32WithDefault(-1, 1)).toEqual(1); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setUint32(1, 2); - expect(accessor.getUint32WithDefault(1)).toEqual(2); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x08, 0x00); - accessor.setUint32(1, 0); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getUint32WithDefault(1)).toBe(1); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getUint32WithDefault(1)).toBe(1); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setInt32(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setUint32(-1, 1); - expect(accessor.getUint32WithDefault(-1)).toEqual(1); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setUint32( - 1, /** @type {number} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setUint32(1, /** @type {number} */ (/** @type {*} */ (null))); - expect(accessor.getUint32WithDefault(1)).toEqual(null); - } - }); - - it('throws in setter for negative value', () => { - if (CHECK_CRITICAL_TYPE) { - expect(() => Kernel.createEmpty().setUint32(1, -1)).toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setUint32(1, -1); - expect(accessor.getUint32WithDefault(1)).toEqual(-1); - } - }); -}); - -describe('Uint64 access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(0)); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getUint64WithDefault(1, Int64.fromInt(2))) - .toEqual(Int64.fromInt(2)); - }); - - it('decodes value from wire', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); - expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('decodes value from wire with multiple values being present', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); - expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2)); - }); - - it('fails when getting value with other wire types', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); - if (CHECK_CRITICAL_TYPE) { - expect(() => { - accessor.getUint64WithDefault(1); - }).toThrowError('Expected wire type: 0 but found: 5'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(0)); - } - }); - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect( - () => Kernel.createEmpty().getUint64WithDefault(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getUint64WithDefault(-1, Int64.fromInt(1))) - .toEqual(Int64.fromInt(1)); - } - }); - - it('returns the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setUint64(1, Int64.fromInt(2)); - expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2)); - }); - - it('encode the value from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = createArrayBuffer(0x08, 0x00); - accessor.setUint64(1, Int64.fromInt(0)); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns value from cache', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setUint64(-1, Int64.fromInt(1))) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setUint64(-1, Int64.fromInt(1)); - expect(accessor.getUint64WithDefault(-1)).toEqual(Int64.fromInt(1)); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setUint64( - 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) - .toThrow(); - } else { - const accessor = Kernel.createEmpty(); - accessor.setUint64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); - expect(accessor.getUint64WithDefault(1)).toEqual(null); - } - }); -}); - -describe('Double access', () => { - it('returns default value for empty input', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getDoubleWithDefault(1)).toEqual(0); - }); - - it('returns the default from parameter', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); - expect(accessor.getDoubleWithDefault(1, 2)).toEqual(2); - }); - - it('decodes value from wire', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F)); - expect(accessor.getDoubleWithDefault(1)).toEqual(1); - }); - - - it('decodes value from wire with multiple values being present', () => { - const accessor = Kernel.fromArrayBuffer(createArrayBuffer( - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x09, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF)); - expect(accessor.getDoubleWithDefault(1)).toEqual(-1); - }); - - if (CHECK_CRITICAL_STATE) { - it('fails when getting double value with other wire types', () => { - const accessor = Kernel.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0xF0, 0x3F)); - expect(() => { - accessor.getDoubleWithDefault(1); - }).toThrow(); - }); - } - - - it('throws in getter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().getDoubleWithDefault(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - expect(Kernel.createEmpty().getDoubleWithDefault(-1, 1)).toEqual(1); - } - }); - - it('returns the value from setter', () => { - const bytes = - createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.setDouble(1, 2); - expect(accessor.getDoubleWithDefault(1)).toEqual(2); - }); - - it('encode the value from setter', () => { - const bytes = - createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); - const accessor = Kernel.fromArrayBuffer(bytes); - const newBytes = - createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - accessor.setDouble(1, 0); - expect(accessor.serialize()).toEqual(newBytes); - }); - - it('returns string value from cache', () => { - const bytes = - createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getDoubleWithDefault(1)).toBe(1); - // Make sure the value is cached. - bytes[2] = 0x00; - expect(accessor.getDoubleWithDefault(1)).toBe(1); - }); - - it('throws in setter for invalid fieldNumber', () => { - if (CHECK_BOUNDS) { - expect(() => Kernel.createEmpty().setDouble(-1, 1)) - .toThrowError('Field number is out of range: -1'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setDouble(-1, 1); - expect(accessor.getDoubleWithDefault(-1)).toEqual(1); - } - }); - - it('throws in setter for invalid value', () => { - if (CHECK_CRITICAL_TYPE) { - expect( - () => Kernel.createEmpty().setDouble( - 1, /** @type {number} */ (/** @type {*} */ (null)))) - .toThrowError('Must be a number, but got: null'); - } else { - const accessor = Kernel.createEmpty(); - accessor.setDouble(1, /** @type {number} */ (/** @type {*} */ (null))); - expect(accessor.getDoubleWithDefault(1)).toEqual(null); - } - }); -}); - -describe('Kernel for singular group does', () => { - it('return group from the input', () => { - const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg = accessor.getGroupOrNull(1, TestMessage.instanceCreator); - expect(msg.getBoolWithDefault(1, false)).toBe(true); - }); - - it('return group from the input when pivot is set', () => { - const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg = accessor.getGroupOrNull(1, TestMessage.instanceCreator, 0); - expect(msg.getBoolWithDefault(1, false)).toBe(true); - }); - - it('encode group from the input', () => { - const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode group from the input after read', () => { - const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.getGroupOrNull(1, TestMessage.instanceCreator); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('return last group from multiple inputs', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg = accessor.getGroupOrNull(1, TestMessage.instanceCreator); - expect(msg.getBoolWithDefault(1, false)).toBe(true); - }); - - it('removes duplicated group when serializing', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.getGroupOrNull(1, TestMessage.instanceCreator); - expect(accessor.serialize()) - .toEqual(createArrayBuffer(0x0B, 0x08, 0x01, 0x0C)); - }); - - it('encode group from multiple inputs', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.serialize()).toEqual(bytes); - }); - - it('encode group after read', () => { - const bytes = - createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); - const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - accessor.getGroupOrNull(1, TestMessage.instanceCreator); - expect(accessor.serialize()).toEqual(expected); - }); - - it('return group from setter', () => { - const bytes = createArrayBuffer(0x08, 0x01); - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const subaccessor = Kernel.fromArrayBuffer(bytes); - const submsg1 = new TestMessage(subaccessor); - accessor.setGroup(1, submsg1); - const submsg2 = accessor.getGroup(1, TestMessage.instanceCreator); - expect(submsg1).toBe(submsg2); - }); - - it('encode group from setter', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const subaccessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); - const submsg = new TestMessage(subaccessor); - accessor.setGroup(1, submsg); - const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); - expect(accessor.serialize()).toEqual(expected); - }); - - it('leave hasFieldNumber unchanged after getGroupOrNull', () => { - const accessor = Kernel.createEmpty(); - expect(accessor.hasFieldNumber(1)).toBe(false); - expect(accessor.getGroupOrNull(1, TestMessage.instanceCreator)).toBe(null); - expect(accessor.hasFieldNumber(1)).toBe(false); - }); - - it('serialize changes to subgroups made with getGroupsOrNull', () => { - const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - const mutableSubMessage = - accessor.getGroupOrNull(1, TestMessage.instanceCreator); - mutableSubMessage.setInt32(1, 10); - const intTenBytes = createArrayBuffer(0x0B, 0x08, 0x0A, 0x0C); - expect(accessor.serialize()).toEqual(intTenBytes); - }); - - it('serialize additions to subgroups made with getGroupOrNull', () => { - const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - const mutableSubMessage = - accessor.getGroupOrNull(1, TestMessage.instanceCreator); - mutableSubMessage.setInt32(2, 3); - // Sub group contains the original field, plus the new one. - expect(accessor.serialize()) - .toEqual(createArrayBuffer(0x0B, 0x08, 0x02, 0x10, 0x03, 0x0C)); - }); - - it('fail with getGroupOrNull if immutable group exist in cache', () => { - const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - - const readOnly = accessor.getGroup(1, TestMessage.instanceCreator); - if (CHECK_TYPE) { - expect(() => accessor.getGroupOrNull(1, TestMessage.instanceCreator)) - .toThrow(); - } else { - const mutableSubGropu = - accessor.getGroupOrNull(1, TestMessage.instanceCreator); - // The instance returned by getGroupOrNull is the exact same instance. - expect(mutableSubGropu).toBe(readOnly); - - // Serializing the subgroup does not write the changes - mutableSubGropu.setInt32(1, 0); - expect(accessor.serialize()).toEqual(intTwoBytes); - } - }); - - it('change hasFieldNumber after getGroupAttach', () => { - const accessor = Kernel.createEmpty(); - expect(accessor.hasFieldNumber(1)).toBe(false); - expect(accessor.getGroupAttach(1, TestMessage.instanceCreator)) - .not.toBe(null); - expect(accessor.hasFieldNumber(1)).toBe(true); - }); - - it('change hasFieldNumber after getGroupAttach when pivot is set', () => { - const accessor = Kernel.createEmpty(); - expect(accessor.hasFieldNumber(1)).toBe(false); - expect( - accessor.getGroupAttach(1, TestMessage.instanceCreator, /* pivot= */ 1)) - .not.toBe(null); - expect(accessor.hasFieldNumber(1)).toBe(true); - }); - - it('serialize subgroups made with getGroupAttach', () => { - const accessor = Kernel.createEmpty(); - const mutableSubGroup = - accessor.getGroupAttach(1, TestMessage.instanceCreator); - mutableSubGroup.setInt32(1, 10); - const intTenBytes = createArrayBuffer(0x0B, 0x08, 0x0A, 0x0C); - expect(accessor.serialize()).toEqual(intTenBytes); - }); - - it('serialize additions to subgroups using getMessageAttach', () => { - const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - const mutableSubGroup = - accessor.getGroupAttach(1, TestMessage.instanceCreator); - mutableSubGroup.setInt32(2, 3); - // Sub message contains the original field, plus the new one. - expect(accessor.serialize()) - .toEqual(createArrayBuffer(0x0B, 0x08, 0x02, 0x10, 0x03, 0x0C)); - }); - - it('fail with getGroupAttach if immutable message exist in cache', () => { - const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(intTwoBytes); - - const readOnly = accessor.getGroup(1, TestMessage.instanceCreator); - if (CHECK_TYPE) { - expect(() => accessor.getGroupAttach(1, TestMessage.instanceCreator)) - .toThrow(); - } else { - const mutableSubGroup = - accessor.getGroupAttach(1, TestMessage.instanceCreator); - // The instance returned by getMessageOrNull is the exact same instance. - expect(mutableSubGroup).toBe(readOnly); - - // Serializing the submessage does not write the changes - mutableSubGroup.setInt32(1, 0); - expect(accessor.serialize()).toEqual(intTwoBytes); - } - }); - - it('read default group return empty group with getGroup', () => { - const bytes = new ArrayBuffer(0); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getGroup(1, TestMessage.instanceCreator)).toBeTruthy(); - expect(accessor.getGroup(1, TestMessage.instanceCreator).serialize()) - .toEqual(bytes); - }); - - it('read default group return null with getGroupOrNull', () => { - const bytes = new ArrayBuffer(0); - const accessor = Kernel.fromArrayBuffer(bytes); - expect(accessor.getGroupOrNull(1, TestMessage.instanceCreator)).toBe(null); - }); - - it('read group preserve reference equality', () => { - const bytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg1 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); - const msg2 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); - const msg3 = accessor.getGroupAttach(1, TestMessage.instanceCreator); - expect(msg1).toBe(msg2); - expect(msg1).toBe(msg3); - }); - - it('fail when getting group with null instance constructor', () => { - const accessor = - Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x01)); - const nullMessage = /** @type {function(!Kernel):!TestMessage} */ - (/** @type {*} */ (null)); - expect(() => accessor.getGroupOrNull(1, nullMessage)).toThrow(); - }); - - it('fail when setting group value with null value', () => { - const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); - const fakeMessage = /** @type {!TestMessage} */ (/** @type {*} */ (null)); - if (CHECK_CRITICAL_TYPE) { - expect(() => accessor.setGroup(1, fakeMessage)) - .toThrowError('Given value is not a message instance: null'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - accessor.setMessage(1, fakeMessage); - expect(accessor.getGroupOrNull( - /* fieldNumber= */ 1, TestMessage.instanceCreator)) - .toBeNull(); - } - }); - - it('reads group in a longer buffer', () => { - const bytes = createArrayBuffer( - 0x12, 0x20, // 32 length delimited - 0x00, // random values for padding start - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, // random values for padding end - 0x0B, // Group tag - 0x08, 0x02, 0x0C); - const accessor = Kernel.fromArrayBuffer(bytes); - const msg1 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); - const msg2 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); - expect(msg1).toBe(msg2); - }); -}); diff --git a/js/experimental/runtime/kernel/message_set.js b/js/experimental/runtime/kernel/message_set.js deleted file mode 100644 index d66bace7b..000000000 --- a/js/experimental/runtime/kernel/message_set.js +++ /dev/null @@ -1,285 +0,0 @@ -/* -########################################################## -# # -# __ __ _____ _ _ _____ _ _ _____ # -# \ \ / /\ | __ \| \ | |_ _| \ | |/ ____| # -# \ \ /\ / / \ | |__) | \| | | | | \| | | __ # -# \ \/ \/ / /\ \ | _ /| . ` | | | | . ` | | |_ | # -# \ /\ / ____ \| | \ \| |\ |_| |_| |\ | |__| | # -# \/ \/_/ \_\_| \_\_| \_|_____|_| \_|\_____| # -# # -# # -########################################################## -# Do not use this class in your code. This class purely # -# exists to make proto code generation easier. # -########################################################## -*/ -goog.module('protobuf.runtime.MessageSet'); - -const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const Kernel = goog.require('protobuf.runtime.Kernel'); - -// These are the tags for the old MessageSet format, which was defined as: -// message MessageSet { -// repeated group Item = 1 { -// required uint32 type_id = 2; -// optional bytes message = 3; -// } -// } -/** @const {number} */ -const MSET_GROUP_FIELD_NUMBER = 1; -/** @const {number} */ -const MSET_TYPE_ID_FIELD_NUMBER = 2; -/** @const {number} */ -const MSET_MESSAGE_FIELD_NUMBER = 3; - -/** - * @param {!Kernel} kernel - * @return {!Map} - */ -function createItemMap(kernel) { - const itemMap = new Map(); - let totalCount = 0; - for (const item of kernel.getRepeatedGroupIterable( - MSET_GROUP_FIELD_NUMBER, Item.fromKernel)) { - itemMap.set(item.getTypeId(), item); - totalCount++; - } - - // Normalize the entries. - if (totalCount > itemMap.size) { - writeItemMap(kernel, itemMap); - } - return itemMap; -} - -/** - * @param {!Kernel} kernel - * @param {!Map} itemMap - */ -function writeItemMap(kernel, itemMap) { - kernel.setRepeatedGroupIterable(MSET_GROUP_FIELD_NUMBER, itemMap.values()); -} - -/** - * @implements {InternalMessage} - * @final - */ -class MessageSet { - /** - * @param {!Kernel} kernel - * @return {!MessageSet} - */ - static fromKernel(kernel) { - const itemMap = createItemMap(kernel); - return new MessageSet(kernel, itemMap); - } - - /** - * @return {!MessageSet} - */ - static createEmpty() { - return MessageSet.fromKernel(Kernel.createEmpty()); - } - - /** - * @param {!Kernel} kernel - * @param {!Map} itemMap - * @private - */ - constructor(kernel, itemMap) { - /** @const {!Kernel} @private */ - this.kernel_ = kernel; - /** @const {!Map} @private */ - this.itemMap_ = itemMap; - } - - - - // code helpers for code gen - - /** - * @param {number} typeId - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {?T} - * @template T - */ - getMessageOrNull(typeId, instanceCreator, pivot) { - const item = this.itemMap_.get(typeId); - return item ? item.getMessageOrNull(instanceCreator, pivot) : null; - } - - /** - * @param {number} typeId - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ - getMessageAttach(typeId, instanceCreator, pivot) { - let item = this.itemMap_.get(typeId); - if (item) { - return item.getMessageAttach(instanceCreator, pivot); - } - const message = instanceCreator(Kernel.createEmpty()); - this.setMessage(typeId, message); - return message; - } - - /** - * @param {number} typeId - * @param {number=} pivot - * @return {?Kernel} - */ - getMessageAccessorOrNull(typeId, pivot) { - const item = this.itemMap_.get(typeId); - return item ? item.getMessageAccessorOrNull(pivot) : null; - } - - - /** - * @param {number} typeId - */ - clearMessage(typeId) { - if (this.itemMap_.delete(typeId)) { - writeItemMap(this.kernel_, this.itemMap_); - } - } - - /** - * @param {number} typeId - * @return {boolean} - */ - hasMessage(typeId) { - return this.itemMap_.has(typeId); - } - - /** - * @param {number} typeId - * @param {!InternalMessage} value - */ - setMessage(typeId, value) { - const item = this.itemMap_.get(typeId); - if (item) { - item.setMessage(value); - } else { - this.itemMap_.set(typeId, Item.create(typeId, value)); - writeItemMap(this.kernel_, this.itemMap_); - } - } - - /** - * @return {!Kernel} - * @override - */ - internalGetKernel() { - return this.kernel_; - } -} - -/** - * @implements {InternalMessage} - * @final - */ -class Item { - /** - * @param {number} typeId - * @param {!InternalMessage} message - * @return {!Item} - */ - static create(typeId, message) { - const messageSet = Item.fromKernel(Kernel.createEmpty()); - messageSet.setTypeId_(typeId); - messageSet.setMessage(message); - return messageSet; - } - - - /** - * @param {!Kernel} kernel - * @return {!Item} - */ - static fromKernel(kernel) { - return new Item(kernel); - } - - /** - * @param {!Kernel} kernel - * @private - */ - constructor(kernel) { - /** @const {!Kernel} @private */ - this.kernel_ = kernel; - } - - /** - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ - getMessage(instanceCreator, pivot) { - return this.kernel_.getMessage( - MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot); - } - - /** - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {?T} - * @template T - */ - getMessageOrNull(instanceCreator, pivot) { - return this.kernel_.getMessageOrNull( - MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot); - } - - /** - * @param {function(!Kernel):T} instanceCreator - * @param {number=} pivot - * @return {T} - * @template T - */ - getMessageAttach(instanceCreator, pivot) { - return this.kernel_.getMessageAttach( - MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot); - } - - /** - * @param {number=} pivot - * @return {?Kernel} - */ - getMessageAccessorOrNull(pivot) { - return this.kernel_.getMessageAccessorOrNull( - MSET_MESSAGE_FIELD_NUMBER, pivot); - } - - /** @param {!InternalMessage} value */ - setMessage(value) { - this.kernel_.setMessage(MSET_MESSAGE_FIELD_NUMBER, value); - } - - /** @return {number} */ - getTypeId() { - return this.kernel_.getUint32WithDefault(MSET_TYPE_ID_FIELD_NUMBER); - } - - /** - * @param {number} value - * @private - */ - setTypeId_(value) { - this.kernel_.setUint32(MSET_TYPE_ID_FIELD_NUMBER, value); - } - - /** - * @return {!Kernel} - * @override - */ - internalGetKernel() { - return this.kernel_; - } -} - -exports = MessageSet; diff --git a/js/experimental/runtime/kernel/message_set_test.js b/js/experimental/runtime/kernel/message_set_test.js deleted file mode 100644 index 35e593501..000000000 --- a/js/experimental/runtime/kernel/message_set_test.js +++ /dev/null @@ -1,262 +0,0 @@ -/** - * @fileoverview Tests for message_set.js. - */ -goog.module('protobuf.runtime.MessageSetTest'); - -goog.setTestOnly(); - -const Kernel = goog.require('protobuf.runtime.Kernel'); -const MessageSet = goog.require('protobuf.runtime.MessageSet'); -const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); - -/** - * @param {...number} bytes - * @return {!ArrayBuffer} - */ -function createArrayBuffer(...bytes) { - return new Uint8Array(bytes).buffer; -} - -describe('MessageSet does', () => { - it('returns no messages for empty set', () => { - const messageSet = MessageSet.createEmpty(); - expect(messageSet.getMessageOrNull(12345, TestMessage.instanceCreator)) - .toBeNull(); - }); - - it('returns no kernel for empty set', () => { - const messageSet = MessageSet.createEmpty(); - expect(messageSet.getMessageAccessorOrNull(12345)).toBeNull(); - }); - - it('returns message that has been set', () => { - const messageSet = MessageSet.createEmpty(); - const message = TestMessage.createEmpty(); - messageSet.setMessage(12345, message); - expect(messageSet.getMessageOrNull(12345, TestMessage.instanceCreator)) - .toBe(message); - }); - - it('returns null for cleared message', () => { - const messageSet = MessageSet.createEmpty(); - const message = TestMessage.createEmpty(); - messageSet.setMessage(12345, message); - messageSet.clearMessage(12345); - expect(messageSet.getMessageAccessorOrNull(12345)).toBeNull(); - }); - - it('returns false for not present message', () => { - const messageSet = MessageSet.createEmpty(); - expect(messageSet.hasMessage(12345)).toBe(false); - }); - - it('returns true for present message', () => { - const messageSet = MessageSet.createEmpty(); - const message = TestMessage.createEmpty(); - messageSet.setMessage(12345, message); - expect(messageSet.hasMessage(12345)).toBe(true); - }); - - it('returns false for cleared message', () => { - const messageSet = MessageSet.createEmpty(); - const message = TestMessage.createEmpty(); - messageSet.setMessage(12345, message); - messageSet.clearMessage(12345); - expect(messageSet.hasMessage(12345)).toBe(false); - }); - - it('returns false for cleared message without it being present', () => { - const messageSet = MessageSet.createEmpty(); - messageSet.clearMessage(12345); - expect(messageSet.hasMessage(12345)).toBe(false); - }); - - const createMessageSet = () => { - const messageSet = MessageSet.createEmpty(); - const message = TestMessage.createEmpty(); - message.setInt32(1, 2); - messageSet.setMessage(12345, message); - - - const parsedKernel = - Kernel.fromArrayBuffer(messageSet.internalGetKernel().serialize()); - return MessageSet.fromKernel(parsedKernel); - }; - - it('pass through pivot for getMessageOrNull', () => { - const messageSet = createMessageSet(); - const message = - messageSet.getMessageOrNull(12345, TestMessage.instanceCreator, 2); - expect(message.internalGetKernel().getPivot()).toBe(2); - }); - - it('pass through pivot for getMessageAttach', () => { - const messageSet = createMessageSet(); - const message = - messageSet.getMessageAttach(12345, TestMessage.instanceCreator, 2); - expect(message.internalGetKernel().getPivot()).toBe(2); - }); - - it('pass through pivot for getMessageAccessorOrNull', () => { - const messageSet = createMessageSet(); - const kernel = messageSet.getMessageAccessorOrNull(12345, 2); - expect(kernel.getPivot()).toBe(2); - }); - - it('pick the last value in the stream', () => { - const arrayBuffer = createArrayBuffer( - 0x52, // Tag (field:10, length delimited) - 0x14, // Length of 20 bytes - 0x0B, // Start group fieldnumber 1 - 0x10, // Tag (field 2, varint) - 0xB9, // 12345 - 0x60, // 12345 - 0x1A, // Tag (field 3, length delimited) - 0x03, // length 3 - 0xA0, // Tag (fieldnumber 20, varint) - 0x01, // Tag (fieldnumber 20, varint) - 0x1E, // 30 - 0x0C, // Stop Group field number 1 - // second group - 0x0B, // Start group fieldnumber 1 - 0x10, // Tag (field 2, varint) - 0xB9, // 12345 - 0x60, // 12345 - 0x1A, // Tag (field 3, length delimited) - 0x03, // length 3 - 0xA0, // Tag (fieldnumber 20, varint) - 0x01, // Tag (fieldnumber 20, varint) - 0x01, // 1 - 0x0C // Stop Group field number 1 - ); - - const outerMessage = Kernel.fromArrayBuffer(arrayBuffer); - - const messageSet = outerMessage.getMessage(10, MessageSet.fromKernel); - - const message = - messageSet.getMessageOrNull(12345, TestMessage.instanceCreator); - expect(message.getInt32WithDefault(20)).toBe(1); - }); - - it('removes duplicates when read', () => { - const arrayBuffer = createArrayBuffer( - 0x52, // Tag (field:10, length delimited) - 0x14, // Length of 20 bytes - 0x0B, // Start group fieldnumber 1 - 0x10, // Tag (field 2, varint) - 0xB9, // 12345 - 0x60, // 12345 - 0x1A, // Tag (field 3, length delimited) - 0x03, // length 3 - 0xA0, // Tag (fieldnumber 20, varint) - 0x01, // Tag (fieldnumber 20, varint) - 0x1E, // 30 - 0x0C, // Stop Group field number 1 - // second group - 0x0B, // Start group fieldnumber 1 - 0x10, // Tag (field 2, varint) - 0xB9, // 12345 - 0x60, // 12345 - 0x1A, // Tag (field 3, length delimited) - 0x03, // length 3 - 0xA0, // Tag (fieldnumber 20, varint) - 0x01, // Tag (fieldnumber 20, varint) - 0x01, // 1 - 0x0C // Stop Group field number 1 - ); - - - const outerMessage = Kernel.fromArrayBuffer(arrayBuffer); - outerMessage.getMessageAttach(10, MessageSet.fromKernel); - - expect(outerMessage.serialize()) - .toEqual(createArrayBuffer( - 0x52, // Tag (field:10, length delimited) - 0x0A, // Length of 10 bytes - 0x0B, // Start group fieldnumber 1 - 0x10, // Tag (field 2, varint) - 0xB9, // 12345 - 0x60, // 12345 - 0x1A, // Tag (field 3, length delimited) - 0x03, // length 3 - 0xA0, // Tag (fieldnumber 20, varint) - 0x01, // Tag (fieldnumber 20, varint) - 0x01, // 1 - 0x0C // Stop Group field number 1 - )); - }); - - it('allow for large typeIds', () => { - const messageSet = MessageSet.createEmpty(); - const message = TestMessage.createEmpty(); - messageSet.setMessage(0xFFFFFFFE >>> 0, message); - expect(messageSet.hasMessage(0xFFFFFFFE >>> 0)).toBe(true); - }); -}); - -describe('Optional MessageSet does', () => { - // message Bar { - // optional MessageSet mset = 10; - //} - // - // message Foo { - // extend proto2.bridge.MessageSet { - // optional Foo message_set_extension = 12345; - // } - // optional int32 f20 = 20; - //} - - it('encode as a field', () => { - const fooMessage = Kernel.createEmpty(); - fooMessage.setInt32(20, 30); - - const messageSet = MessageSet.createEmpty(); - messageSet.setMessage(12345, TestMessage.instanceCreator(fooMessage)); - - const barMessage = Kernel.createEmpty(); - barMessage.setMessage(10, messageSet); - - expect(barMessage.serialize()) - .toEqual(createArrayBuffer( - 0x52, // Tag (field:10, length delimited) - 0x0A, // Length of 10 bytes - 0x0B, // Start group fieldnumber 1 - 0x10, // Tag (field 2, varint) - 0xB9, // 12345 - 0x60, // 12345 - 0x1A, // Tag (field 3, length delimited) - 0x03, // length 3 - 0xA0, // Tag (fieldnumber 20, varint) - 0x01, // Tag (fieldnumber 20, varint) - 0x1E, // 30 - 0x0C // Stop Group field number 1 - )); - }); - - it('deserializes', () => { - const fooMessage = Kernel.createEmpty(); - fooMessage.setInt32(20, 30); - - const messageSet = MessageSet.createEmpty(); - messageSet.setMessage(12345, TestMessage.instanceCreator(fooMessage)); - - - const barMessage = Kernel.createEmpty(); - barMessage.setMessage(10, messageSet); - - const arrayBuffer = barMessage.serialize(); - - const barMessageParsed = Kernel.fromArrayBuffer(arrayBuffer); - expect(barMessageParsed.hasFieldNumber(10)).toBe(true); - - const messageSetParsed = - barMessageParsed.getMessage(10, MessageSet.fromKernel); - - const fooMessageParsed = - messageSetParsed.getMessageOrNull(12345, TestMessage.instanceCreator) - .internalGetKernel(); - - expect(fooMessageParsed.getInt32WithDefault(20)).toBe(30); - }); -}); diff --git a/js/experimental/runtime/kernel/packed_bool_test_pairs.js b/js/experimental/runtime/kernel/packed_bool_test_pairs.js deleted file mode 100644 index e8dd2f4b6..000000000 --- a/js/experimental/runtime/kernel/packed_bool_test_pairs.js +++ /dev/null @@ -1,59 +0,0 @@ -goog.module('protobuf.binary.packedBoolTestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed bool values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, boolValues: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedBoolPairs() { - return [ - { - name: 'empty value', - boolValues: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - boolValues: [true], - bufferDecoder: createBufferDecoder(0x01, 0x01), - }, - { - name: 'single multi-bytes value', - boolValues: [true], - bufferDecoder: createBufferDecoder(0x02, 0x80, 0x01), - skip_writer: true, - }, - { - name: 'multiple values', - boolValues: [true, false], - bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00), - }, - { - name: 'multiple multi-bytes values', - boolValues: [true, false], - bufferDecoder: createBufferDecoder( - 0x0C, // length - 0x80, - 0x80, - 0x80, - 0x80, - 0x80, - 0x01, // true - 0x80, - 0x80, - 0x80, - 0x80, - 0x80, - 0x00, // false - ), - skip_writer: true, - }, - ]; -} - -exports = {getPackedBoolPairs}; diff --git a/js/experimental/runtime/kernel/packed_double_test_pairs.js b/js/experimental/runtime/kernel/packed_double_test_pairs.js deleted file mode 100644 index de2cb5510..000000000 --- a/js/experimental/runtime/kernel/packed_double_test_pairs.js +++ /dev/null @@ -1,52 +0,0 @@ -goog.module('protobuf.binary.packedDoubleTestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed double values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, doubleValues: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedDoublePairs() { - return [ - { - name: 'empty value', - doubleValues: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - doubleValues: [1], - bufferDecoder: createBufferDecoder( - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F), - }, - { - name: 'multiple values', - doubleValues: [1, 0], - bufferDecoder: createBufferDecoder( - 0x10, // length - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xF0, - 0x3F, // 1 - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // 0 - ), - }, - ]; -} - -exports = {getPackedDoublePairs}; diff --git a/js/experimental/runtime/kernel/packed_fixed32_test_pairs.js b/js/experimental/runtime/kernel/packed_fixed32_test_pairs.js deleted file mode 100644 index 5c8a54d1e..000000000 --- a/js/experimental/runtime/kernel/packed_fixed32_test_pairs.js +++ /dev/null @@ -1,34 +0,0 @@ -goog.module('protobuf.binary.packedFixed32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed fixed32 values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, fixed32Values: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedFixed32Pairs() { - return [ - { - name: 'empty value', - fixed32Values: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - fixed32Values: [1], - bufferDecoder: createBufferDecoder(0x04, 0x01, 0x00, 0x00, 0x00), - }, - { - name: 'multiple values', - fixed32Values: [1, 0], - bufferDecoder: createBufferDecoder( - 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - }, - ]; -} - -exports = {getPackedFixed32Pairs}; diff --git a/js/experimental/runtime/kernel/packed_float_test_pairs.js b/js/experimental/runtime/kernel/packed_float_test_pairs.js deleted file mode 100644 index 6d1204664..000000000 --- a/js/experimental/runtime/kernel/packed_float_test_pairs.js +++ /dev/null @@ -1,34 +0,0 @@ -goog.module('protobuf.binary.packedFloatTestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed float values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, floatValues: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedFloatPairs() { - return [ - { - name: 'empty value', - floatValues: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - floatValues: [1], - bufferDecoder: createBufferDecoder(0x04, 0x00, 0x00, 0x80, 0x3F), - }, - { - name: 'multiple values', - floatValues: [1, 0], - bufferDecoder: createBufferDecoder( - 0x08, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00), - }, - ]; -} - -exports = {getPackedFloatPairs}; diff --git a/js/experimental/runtime/kernel/packed_int32_test_pairs.js b/js/experimental/runtime/kernel/packed_int32_test_pairs.js deleted file mode 100644 index fbe5f40fb..000000000 --- a/js/experimental/runtime/kernel/packed_int32_test_pairs.js +++ /dev/null @@ -1,33 +0,0 @@ -goog.module('protobuf.binary.packedInt32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed int32 values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, int32Values: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedInt32Pairs() { - return [ - { - name: 'empty value', - int32Values: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - int32Values: [1], - bufferDecoder: createBufferDecoder(0x01, 0x01), - }, - { - name: 'multiple values', - int32Values: [1, 0], - bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00), - }, - ]; -} - -exports = {getPackedInt32Pairs}; diff --git a/js/experimental/runtime/kernel/packed_int64_test_pairs.js b/js/experimental/runtime/kernel/packed_int64_test_pairs.js deleted file mode 100644 index a6cf54e3c..000000000 --- a/js/experimental/runtime/kernel/packed_int64_test_pairs.js +++ /dev/null @@ -1,34 +0,0 @@ -goog.module('protobuf.binary.packedInt64TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const Int64 = goog.require('protobuf.Int64'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed int64 values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, int64Values: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedInt64Pairs() { - return [ - { - name: 'empty value', - int64Values: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - int64Values: [Int64.fromInt(1)], - bufferDecoder: createBufferDecoder(0x01, 0x01), - }, - { - name: 'multiple values', - int64Values: [Int64.fromInt(1), Int64.fromInt(0)], - bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00), - }, - ]; -} - -exports = {getPackedInt64Pairs}; diff --git a/js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js b/js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js deleted file mode 100644 index d6daa7964..000000000 --- a/js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js +++ /dev/null @@ -1,34 +0,0 @@ -goog.module('protobuf.binary.packedSfixed32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed sfixed32 values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, sfixed32Values: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedSfixed32Pairs() { - return [ - { - name: 'empty value', - sfixed32Values: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - sfixed32Values: [1], - bufferDecoder: createBufferDecoder(0x04, 0x01, 0x00, 0x00, 0x00), - }, - { - name: 'multiple values', - sfixed32Values: [1, 0], - bufferDecoder: createBufferDecoder( - 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - }, - ]; -} - -exports = {getPackedSfixed32Pairs}; diff --git a/js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js b/js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js deleted file mode 100644 index 5b8670366..000000000 --- a/js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js +++ /dev/null @@ -1,53 +0,0 @@ -goog.module('protobuf.binary.packedSfixed64TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const Int64 = goog.require('protobuf.Int64'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed sfixed64 values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, sfixed64Values: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedSfixed64Pairs() { - return [ - { - name: 'empty value', - sfixed64Values: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - sfixed64Values: [Int64.fromInt(1)], - bufferDecoder: createBufferDecoder( - 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - }, - { - name: 'multiple values', - sfixed64Values: [Int64.fromInt(1), Int64.fromInt(0)], - bufferDecoder: createBufferDecoder( - 0x10, // length - 0x01, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // 1 - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, // 2 - ), - }, - ]; -} - -exports = {getPackedSfixed64Pairs}; diff --git a/js/experimental/runtime/kernel/packed_sint32_test_pairs.js b/js/experimental/runtime/kernel/packed_sint32_test_pairs.js deleted file mode 100644 index 314ac11fe..000000000 --- a/js/experimental/runtime/kernel/packed_sint32_test_pairs.js +++ /dev/null @@ -1,33 +0,0 @@ -goog.module('protobuf.binary.packedSint32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed sint32 values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, sint32Values: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedSint32Pairs() { - return [ - { - name: 'empty value', - sint32Values: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - sint32Values: [-1], - bufferDecoder: createBufferDecoder(0x01, 0x01), - }, - { - name: 'multiple values', - sint32Values: [-1, 0], - bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00), - }, - ]; -} - -exports = {getPackedSint32Pairs}; diff --git a/js/experimental/runtime/kernel/packed_sint64_test_pairs.js b/js/experimental/runtime/kernel/packed_sint64_test_pairs.js deleted file mode 100644 index c87302278..000000000 --- a/js/experimental/runtime/kernel/packed_sint64_test_pairs.js +++ /dev/null @@ -1,34 +0,0 @@ -goog.module('protobuf.binary.packedSint64TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const Int64 = goog.require('protobuf.Int64'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed sint64 values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, sint64Values: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedSint64Pairs() { - return [ - { - name: 'empty value', - sint64Values: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - sint64Values: [Int64.fromInt(-1)], - bufferDecoder: createBufferDecoder(0x01, 0x01), - }, - { - name: 'multiple values', - sint64Values: [Int64.fromInt(-1), Int64.fromInt(0)], - bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00), - }, - ]; -} - -exports = {getPackedSint64Pairs}; diff --git a/js/experimental/runtime/kernel/packed_uint32_test_pairs.js b/js/experimental/runtime/kernel/packed_uint32_test_pairs.js deleted file mode 100644 index 34fbbdfed..000000000 --- a/js/experimental/runtime/kernel/packed_uint32_test_pairs.js +++ /dev/null @@ -1,33 +0,0 @@ -goog.module('protobuf.binary.packedUint32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of packed uint32 values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, uint32Values: !Array, - * bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>} - */ -function getPackedUint32Pairs() { - return [ - { - name: 'empty value', - uint32Values: [], - bufferDecoder: createBufferDecoder(0x00), - skip_writer: true, - }, - { - name: 'single value', - uint32Values: [1], - bufferDecoder: createBufferDecoder(0x01, 0x01), - }, - { - name: 'multiple values', - uint32Values: [1, 0], - bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00), - }, - ]; -} - -exports = {getPackedUint32Pairs}; diff --git a/js/experimental/runtime/kernel/reader.js b/js/experimental/runtime/kernel/reader.js deleted file mode 100644 index 44708b5ae..000000000 --- a/js/experimental/runtime/kernel/reader.js +++ /dev/null @@ -1,364 +0,0 @@ -/** - * @fileoverview Helper methods for reading data from the binary wire format. - */ -goog.module('protobuf.binary.reader'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const ByteString = goog.require('protobuf.ByteString'); -const Int64 = goog.require('protobuf.Int64'); -const {checkState} = goog.require('protobuf.internal.checks'); - - -/****************************************************************************** - * OPTIONAL FUNCTIONS - ******************************************************************************/ - -/** - * Reads a boolean value from the binary bytes. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {boolean} - * @package - */ -function readBool(bufferDecoder, start) { - const {lowBits, highBits} = bufferDecoder.getVarint(start); - return lowBits !== 0 || highBits !== 0; -} - -/** - * Reads a ByteString value from the binary bytes. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!ByteString} - * @package - */ -function readBytes(bufferDecoder, start) { - return readDelimited(bufferDecoder, start).asByteString(); -} - -/** - * Reads a int32 value from the binary bytes encoded as varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {number} - * @package - */ -function readInt32(bufferDecoder, start) { - // Negative 32 bit integers are encoded with 64 bit values. - // Clients are expected to truncate back to 32 bits. - // This is why we are dropping the upper bytes here. - return bufferDecoder.getUnsignedVarint32At(start) | 0; -} - -/** - * Reads a int32 value from the binary bytes encoded as varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Int64} - * @package - */ -function readInt64(bufferDecoder, start) { - const {lowBits, highBits} = bufferDecoder.getVarint(start); - return Int64.fromBits(lowBits, highBits); -} - -/** - * Reads a fixed int32 value from the binary bytes. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {number} - * @package - */ -function readFixed32(bufferDecoder, start) { - return bufferDecoder.getUint32(start); -} - -/** - * Reads a float value from the binary bytes. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {number} - * @package - */ -function readFloat(bufferDecoder, start) { - return bufferDecoder.getFloat32(start); -} - -/** - * Reads a fixed int64 value from the binary bytes. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Int64} - * @package - */ -function readSfixed64(bufferDecoder, start) { - const lowBits = bufferDecoder.getInt32(start); - const highBits = bufferDecoder.getInt32(start + 4); - return Int64.fromBits(lowBits, highBits); -} - -/** - * Reads a sint64 value from the binary bytes encoded as varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Int64} - * @package - */ -function readSint64(bufferDecoder, start) { - const {lowBits, highBits} = bufferDecoder.getVarint(start); - const sign = -(lowBits & 0x01); - const decodedLowerBits = ((lowBits >>> 1) | (highBits & 0x01) << 31) ^ sign; - const decodedUpperBits = (highBits >>> 1) ^ sign; - return Int64.fromBits(decodedLowerBits, decodedUpperBits); -} - -/** - * Reads a sint32 value from the binary bytes encoded as varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {number} - * @package - */ -function readSint32(bufferDecoder, start) { - return readSint64(bufferDecoder, start).getLowBits(); -} - -/** - * Read a subarray of bytes representing a length delimited field. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!BufferDecoder} - * @package - */ -function readDelimited(bufferDecoder, start) { - const unsignedLength = bufferDecoder.getUnsignedVarint32At(start); - return bufferDecoder.subBufferDecoder(bufferDecoder.cursor(), unsignedLength); -} - -/** - * Reads a string value from the binary bytes. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {string} - * @package - */ -function readString(bufferDecoder, start) { - return readDelimited(bufferDecoder, start).asString(); -} - -/** - * Reads a uint32 value from the binary bytes encoded as varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {number} - * @package - */ -function readUint32(bufferDecoder, start) { - return bufferDecoder.getUnsignedVarint32At(start); -} - -/** - * Reads a double value from the binary bytes. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {number} - * @package - */ -function readDouble(bufferDecoder, start) { - return bufferDecoder.getFloat64(start); -} - -/** - * Reads a fixed int32 value from the binary bytes. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {number} - * @package - */ -function readSfixed32(bufferDecoder, start) { - return bufferDecoder.getInt32(start); -} - -/****************************************************************************** - * REPEATED FUNCTIONS - ******************************************************************************/ - -/** - * Reads a packed bool field, which consists of a length header and a list of - * unsigned varints. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedBool(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readBool); -} - -/** - * Reads a packed double field, which consists of a length header and a list of - * fixed64. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedDouble(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readDouble); -} - -/** - * Reads a packed fixed32 field, which consists of a length header and a list of - * fixed32. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedFixed32(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readFixed32); -} - -/** - * Reads a packed float field, which consists of a length header and a list of - * fixed64. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedFloat(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readFloat); -} - -/** - * Reads a packed int32 field, which consists of a length header and a list of - * varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedInt32(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readInt32); -} - -/** - * Reads a packed int64 field, which consists of a length header and a list - * of int64. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedInt64(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readInt64); -} - -/** - * Reads a packed sfixed32 field, which consists of a length header and a list - * of sfixed32. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedSfixed32(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readSfixed32); -} - -/** - * Reads a packed sfixed64 field, which consists of a length header and a list - * of sfixed64. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedSfixed64(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readSfixed64); -} - -/** - * Reads a packed sint32 field, which consists of a length header and a list of - * varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedSint32(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readSint32); -} - -/** - * Reads a packed sint64 field, which consists of a length header and a list - * of sint64. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedSint64(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readSint64); -} - -/** - * Reads a packed uint32 field, which consists of a length header and a list of - * varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @return {!Array} - * @package - */ -function readPackedUint32(bufferDecoder, start) { - return readPacked(bufferDecoder, start, readUint32); -} - -/** - * Read packed values. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @param {function(!BufferDecoder, number):T} valueFunction - * @return {!Array} - * @package - * @template T - */ -function readPacked(bufferDecoder, start, valueFunction) { - const /** !Array */ result = []; - const unsignedLength = bufferDecoder.getUnsignedVarint32At(start); - const dataStart = bufferDecoder.cursor(); - while (bufferDecoder.cursor() < dataStart + unsignedLength) { - checkState(bufferDecoder.cursor() > 0); - result.push(valueFunction(bufferDecoder, bufferDecoder.cursor())); - } - return result; -} - -exports = { - readBool, - readBytes, - readDelimited, - readDouble, - readFixed32, - readFloat, - readInt32, - readInt64, - readSint32, - readSint64, - readSfixed32, - readSfixed64, - readString, - readUint32, - readPackedBool, - readPackedDouble, - readPackedFixed32, - readPackedFloat, - readPackedInt32, - readPackedInt64, - readPackedSfixed32, - readPackedSfixed64, - readPackedSint32, - readPackedSint64, - readPackedUint32, -}; diff --git a/js/experimental/runtime/kernel/reader_test.js b/js/experimental/runtime/kernel/reader_test.js deleted file mode 100644 index 100c7937a..000000000 --- a/js/experimental/runtime/kernel/reader_test.js +++ /dev/null @@ -1,425 +0,0 @@ -/** - * @fileoverview Tests for reader.js. - */ -goog.module('protobuf.binary.ReaderTest'); - -goog.setTestOnly(); - -// Note to the reader: -// Since the reader behavior changes with the checking level some of the -// tests in this file have to know which checking level is enable to make -// correct assertions. -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const ByteString = goog.require('protobuf.ByteString'); -const reader = goog.require('protobuf.binary.reader'); -const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); -const {encode} = goog.require('protobuf.binary.textencoding'); -const {getBoolPairs} = goog.require('protobuf.binary.boolTestPairs'); -const {getDoublePairs} = goog.require('protobuf.binary.doubleTestPairs'); -const {getFixed32Pairs} = goog.require('protobuf.binary.fixed32TestPairs'); -const {getFloatPairs} = goog.require('protobuf.binary.floatTestPairs'); -const {getInt32Pairs} = goog.require('protobuf.binary.int32TestPairs'); -const {getInt64Pairs} = goog.require('protobuf.binary.int64TestPairs'); -const {getPackedBoolPairs} = goog.require('protobuf.binary.packedBoolTestPairs'); -const {getPackedDoublePairs} = goog.require('protobuf.binary.packedDoubleTestPairs'); -const {getPackedFixed32Pairs} = goog.require('protobuf.binary.packedFixed32TestPairs'); -const {getPackedFloatPairs} = goog.require('protobuf.binary.packedFloatTestPairs'); -const {getPackedInt32Pairs} = goog.require('protobuf.binary.packedInt32TestPairs'); -const {getPackedInt64Pairs} = goog.require('protobuf.binary.packedInt64TestPairs'); -const {getPackedSfixed32Pairs} = goog.require('protobuf.binary.packedSfixed32TestPairs'); -const {getPackedSfixed64Pairs} = goog.require('protobuf.binary.packedSfixed64TestPairs'); -const {getPackedSint32Pairs} = goog.require('protobuf.binary.packedSint32TestPairs'); -const {getPackedSint64Pairs} = goog.require('protobuf.binary.packedSint64TestPairs'); -const {getPackedUint32Pairs} = goog.require('protobuf.binary.packedUint32TestPairs'); -const {getSfixed32Pairs} = goog.require('protobuf.binary.sfixed32TestPairs'); -const {getSfixed64Pairs} = goog.require('protobuf.binary.sfixed64TestPairs'); -const {getSint32Pairs} = goog.require('protobuf.binary.sint32TestPairs'); -const {getSint64Pairs} = goog.require('protobuf.binary.sint64TestPairs'); -const {getUint32Pairs} = goog.require('protobuf.binary.uint32TestPairs'); - -/****************************************************************************** - * Optional FUNCTIONS - ******************************************************************************/ - -describe('Read bool does', () => { - for (const pair of getBoolPairs()) { - it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_CRITICAL_STATE) { - expect(() => reader.readBool(pair.bufferDecoder, 0)).toThrow(); - } else { - const d = reader.readBool( - pair.bufferDecoder, pair.bufferDecoder.startIndex()); - expect(d).toEqual(pair.boolValue); - } - }); - } -}); - -describe('readBytes does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(); - expect(() => reader.readBytes(bufferDecoder, 0)).toThrow(); - }); - - it('read bytes by index', () => { - const bufferDecoder = createBufferDecoder(3, 1, 2, 3); - const byteString = reader.readBytes(bufferDecoder, 0); - expect(ByteString.fromArrayBuffer(new Uint8Array([1, 2, 3]).buffer)) - .toEqual(byteString); - }); -}); - -describe('readDouble does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(); - expect(() => reader.readDouble(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getDoublePairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readDouble(pair.bufferDecoder, 0); - expect(d).toEqual(pair.doubleValue); - }); - } -}); - -describe('readFixed32 does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(); - expect(() => reader.readFixed32(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getFixed32Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readFixed32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.intValue); - }); - } -}); - -describe('readFloat does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(); - expect(() => reader.readFloat(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getFloatPairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readFloat(pair.bufferDecoder, 0); - expect(d).toEqual(Math.fround(pair.floatValue)); - }); - } -}); - -describe('readInt32 does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(0x80); - expect(() => reader.readInt32(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getInt32Pairs()) { - it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_CRITICAL_STATE) { - expect(() => reader.readInt32(pair.bufferDecoder, 0)).toThrow(); - } else { - const d = reader.readInt32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.intValue); - } - }); - } -}); - -describe('readSfixed32 does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(0x80); - expect(() => reader.readSfixed32(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getSfixed32Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readSfixed32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.intValue); - }); - } -}); - -describe('readSfixed64 does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(0x80); - expect(() => reader.readSfixed64(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getSfixed64Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readSfixed64(pair.bufferDecoder, 0); - expect(d).toEqual(pair.longValue); - }); - } -}); - -describe('readSint32 does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(0x80); - expect(() => reader.readSint32(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getSint32Pairs()) { - it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_CRITICAL_STATE) { - expect(() => reader.readSint32(pair.bufferDecoder, 0)).toThrow(); - } else { - const d = reader.readSint32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.intValue); - } - }); - } -}); - -describe('readInt64 does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(0x80); - expect(() => reader.readInt64(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getInt64Pairs()) { - it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_CRITICAL_STATE) { - expect(() => reader.readInt64(pair.bufferDecoder, 0)).toThrow(); - } else { - const d = reader.readInt64(pair.bufferDecoder, 0); - expect(d).toEqual(pair.longValue); - } - }); - } -}); - -describe('readSint64 does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(0x80); - expect(() => reader.readSint64(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getSint64Pairs()) { - it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_CRITICAL_STATE) { - expect(() => reader.readSint64(pair.bufferDecoder, 0)).toThrow(); - } else { - const d = reader.readSint64(pair.bufferDecoder, 0); - expect(d).toEqual(pair.longValue); - } - }); - } -}); - -describe('readUint32 does', () => { - it('throw exception if data is too short', () => { - const bufferDecoder = createBufferDecoder(0x80); - expect(() => reader.readUint32(bufferDecoder, 0)).toThrow(); - }); - - for (const pair of getUint32Pairs()) { - if (!pair.skip_reader) { - it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_CRITICAL_STATE) { - expect(() => reader.readUint32(pair.bufferDecoder, 0)).toThrow(); - } else { - const d = reader.readUint32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.intValue); - } - }); - } - } -}); - -/** - * - * @param {string} s - * @return {!Uint8Array} - */ -function encodeString(s) { - if (typeof TextEncoder !== 'undefined') { - const textEncoder = new TextEncoder('utf-8'); - return textEncoder.encode(s); - } else { - return encode(s); - } -} - -/** @param {string} s */ -function expectEncodedStringToMatch(s) { - const array = encodeString(s); - const length = array.length; - if (length > 127) { - throw new Error('Test only works for strings shorter than 128'); - } - const encodedArray = new Uint8Array(length + 1); - encodedArray[0] = length; - encodedArray.set(array, 1); - const bufferDecoder = BufferDecoder.fromArrayBuffer(encodedArray.buffer); - expect(reader.readString(bufferDecoder, 0)).toEqual(s); -} - -describe('readString does', () => { - it('return empty string for zero length string', () => { - const s = reader.readString(createBufferDecoder(0x00), 0); - expect(s).toEqual(''); - }); - - it('decode random strings', () => { - // 1 byte strings - expectEncodedStringToMatch('hello'); - expectEncodedStringToMatch('HELLO1!'); - - // 2 byte String - expectEncodedStringToMatch('©'); - - // 3 byte string - expectEncodedStringToMatch('❄'); - - // 4 byte string - expectEncodedStringToMatch('😁'); - }); - - it('decode 1 byte strings', () => { - for (let i = 0; i < 0x80; i++) { - const s = String.fromCharCode(i); - expectEncodedStringToMatch(s); - } - }); - - it('decode 2 byte strings', () => { - for (let i = 0xC0; i < 0x7FF; i++) { - const s = String.fromCharCode(i); - expectEncodedStringToMatch(s); - } - }); - - it('decode 3 byte strings', () => { - for (let i = 0x7FF; i < 0x8FFF; i++) { - const s = String.fromCharCode(i); - expectEncodedStringToMatch(s); - } - }); - - it('throw exception on invalid bytes', () => { - // This test will only succeed with the native TextDecoder since - // our polyfill does not do any validation. IE10 and IE11 don't support - // TextDecoder. - // TODO: Remove this check once we no longer need to support IE - if (typeof TextDecoder !== 'undefined') { - expect( - () => reader.readString( - createBufferDecoder(0x01, /* invalid utf data point*/ 0xFF), 0)) - .toThrow(); - } - }); - - it('throw exception if data is too short', () => { - const array = createBufferDecoder(0x02, '?'.charCodeAt(0)); - expect(() => reader.readString(array, 0)).toThrow(); - }); -}); - -/****************************************************************************** - * REPEATED FUNCTIONS - ******************************************************************************/ - -describe('readPackedBool does', () => { - for (const pair of getPackedBoolPairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedBool(pair.bufferDecoder, 0); - expect(d).toEqual(pair.boolValues); - }); - } -}); - -describe('readPackedDouble does', () => { - for (const pair of getPackedDoublePairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedDouble(pair.bufferDecoder, 0); - expect(d).toEqual(pair.doubleValues); - }); - } -}); - -describe('readPackedFixed32 does', () => { - for (const pair of getPackedFixed32Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedFixed32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.fixed32Values); - }); - } -}); - -describe('readPackedFloat does', () => { - for (const pair of getPackedFloatPairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedFloat(pair.bufferDecoder, 0); - expect(d).toEqual(pair.floatValues); - }); - } -}); - -describe('readPackedInt32 does', () => { - for (const pair of getPackedInt32Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedInt32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.int32Values); - }); - } -}); - -describe('readPackedInt64 does', () => { - for (const pair of getPackedInt64Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedInt64(pair.bufferDecoder, 0); - expect(d).toEqual(pair.int64Values); - }); - } -}); - -describe('readPackedSfixed32 does', () => { - for (const pair of getPackedSfixed32Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedSfixed32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.sfixed32Values); - }); - } -}); - -describe('readPackedSfixed64 does', () => { - for (const pair of getPackedSfixed64Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedSfixed64(pair.bufferDecoder, 0); - expect(d).toEqual(pair.sfixed64Values); - }); - } -}); - -describe('readPackedSint32 does', () => { - for (const pair of getPackedSint32Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedSint32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.sint32Values); - }); - } -}); - -describe('readPackedSint64 does', () => { - for (const pair of getPackedSint64Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedSint64(pair.bufferDecoder, 0); - expect(d).toEqual(pair.sint64Values); - }); - } -}); - -describe('readPackedUint32 does', () => { - for (const pair of getPackedUint32Pairs()) { - it(`decode ${pair.name}`, () => { - const d = reader.readPackedUint32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.uint32Values); - }); - } -}); diff --git a/js/experimental/runtime/kernel/sfixed32_test_pairs.js b/js/experimental/runtime/kernel/sfixed32_test_pairs.js deleted file mode 100644 index 5a082ce97..000000000 --- a/js/experimental/runtime/kernel/sfixed32_test_pairs.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @fileoverview Test data for sfixed32 encoding and decoding. - */ -goog.module('protobuf.binary.sfixed32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of int values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, intValue: number, bufferDecoder: - * !BufferDecoder}>} - */ -function getSfixed32Pairs() { - const sfixed32Pairs = [ - { - name: 'zero', - intValue: 0, - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x00), - }, - { - name: 'one', - intValue: 1, - bufferDecoder: createBufferDecoder(0x01, 0x00, 0x00, 0x00) - }, - { - name: 'minus one', - intValue: -1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF), - }, - { - name: 'max int 2^31 -1', - intValue: Math.pow(2, 31) - 1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0x7F) - }, - { - name: 'min int -2^31', - intValue: -Math.pow(2, 31), - bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x80) - }, - ]; - return [...sfixed32Pairs]; -} - -exports = {getSfixed32Pairs}; diff --git a/js/experimental/runtime/kernel/sfixed64_test_pairs.js b/js/experimental/runtime/kernel/sfixed64_test_pairs.js deleted file mode 100644 index c7c8d0020..000000000 --- a/js/experimental/runtime/kernel/sfixed64_test_pairs.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @fileoverview Test data for sfixed32 encoding and decoding. - */ -goog.module('protobuf.binary.sfixed64TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const Int64 = goog.require('protobuf.Int64'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of int values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, longValue: !Int64, bufferDecoder: - * !BufferDecoder}>} - */ -function getSfixed64Pairs() { - const sfixed64Pairs = [ - { - name: 'zero', - longValue: Int64.fromInt(0), - bufferDecoder: - createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - }, - { - name: 'one', - longValue: Int64.fromInt(1), - bufferDecoder: - createBufferDecoder(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) - }, - { - name: 'minus one', - longValue: Int64.fromInt(-1), - bufferDecoder: - createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - }, - { - name: 'max int 2^63 -1', - longValue: Int64.getMaxValue(), - bufferDecoder: - createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F) - }, - { - name: 'min int -2^63', - longValue: Int64.getMinValue(), - bufferDecoder: - createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80) - }, - ]; - return [...sfixed64Pairs]; -} - -exports = {getSfixed64Pairs}; diff --git a/js/experimental/runtime/kernel/sint32_test_pairs.js b/js/experimental/runtime/kernel/sint32_test_pairs.js deleted file mode 100644 index 954df90c9..000000000 --- a/js/experimental/runtime/kernel/sint32_test_pairs.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @fileoverview Test data for int32 encoding and decoding. - */ -goog.module('protobuf.binary.sint32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of float values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, intValue:number, bufferDecoder: - * !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>} - */ -function getSint32Pairs() { - const sint32Pairs = [ - { - name: 'zero', - intValue: 0, - bufferDecoder: createBufferDecoder(0x00), - }, - { - name: 'one ', - intValue: 1, - bufferDecoder: createBufferDecoder(0x02), - }, - { - name: 'minus one', - intValue: -1, - bufferDecoder: createBufferDecoder(0x01), - }, - { - name: 'two', - intValue: 2, - bufferDecoder: createBufferDecoder(0x04), - }, - { - name: 'minus two', - intValue: -2, - bufferDecoder: createBufferDecoder(0x03), - }, - { - name: 'int 2^31 - 1', - intValue: Math.pow(2, 31) - 1, - bufferDecoder: createBufferDecoder(0xFE, 0xFF, 0xFF, 0xFF, 0x0F), - - }, - { - name: '-2^31', - intValue: -Math.pow(2, 31), - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F), - }, - ]; - return [...sint32Pairs]; -} - -exports = {getSint32Pairs}; diff --git a/js/experimental/runtime/kernel/sint64_test_pairs.js b/js/experimental/runtime/kernel/sint64_test_pairs.js deleted file mode 100644 index f1b4610e7..000000000 --- a/js/experimental/runtime/kernel/sint64_test_pairs.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @fileoverview Test data for sint64 encoding and decoding. - */ -goog.module('protobuf.binary.sint64TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const Int64 = goog.require('protobuf.Int64'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of float values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, longValue: !Int64, bufferDecoder: - * !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>} - */ -function getSint64Pairs() { - const sint64Pairs = [ - { - name: 'zero', - longValue: Int64.fromInt(0), - bufferDecoder: createBufferDecoder(0x00), - }, - { - name: 'one ', - longValue: Int64.fromInt(1), - bufferDecoder: createBufferDecoder(0x02), - }, - { - name: 'minus one', - longValue: Int64.fromInt(-1), - bufferDecoder: createBufferDecoder(0x01), - }, - { - name: 'two', - longValue: Int64.fromInt(2), - bufferDecoder: createBufferDecoder(0x04), - }, - { - name: 'minus two', - longValue: Int64.fromInt(-2), - bufferDecoder: createBufferDecoder(0x03), - }, - { - name: 'min value', - longValue: Int64.getMinValue(), - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01), - }, - - { - name: 'max value', - longValue: Int64.getMaxValue(), - bufferDecoder: createBufferDecoder( - 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01), - }, - ]; - return [...sint64Pairs]; -} - -exports = {getSint64Pairs}; diff --git a/js/experimental/runtime/kernel/storage.js b/js/experimental/runtime/kernel/storage.js deleted file mode 100644 index a3e1e4f00..000000000 --- a/js/experimental/runtime/kernel/storage.js +++ /dev/null @@ -1,67 +0,0 @@ -goog.module('protobuf.runtime.Storage'); - -/** - * Interface for getting and storing fields of a protobuf message. - * - * @interface - * @package - * @template FieldType - */ -class Storage { - /** - * Returns the pivot value. - * - * @return {number} - */ - getPivot() {} - - /** - * Sets a field in the specified field number. - * - * @param {number} fieldNumber - * @param {!FieldType} field - */ - set(fieldNumber, field) {} - - /** - * Returns a field at the specified field number. - * - * @param {number} fieldNumber - * @return {!FieldType|undefined} - */ - get(fieldNumber) {} - - /** - * Deletes a field from the specified field number. - * - * @param {number} fieldNumber - */ - delete(fieldNumber) {} - - /** - * Executes the provided function once for each field. - * - * @param {function(!FieldType, number): void} callback - */ - forEach(callback) {} - - /** - * Creates a shallow copy of the storage. - * - * @return {!Storage} - */ - shallowCopy() {} -} - -/** - * 85% of the proto fields have a field number <= 24: - * https://plx.corp.google.com/scripts2/script_5d._f02af6_0000_23b1_a15f_001a1139dd02 - * - * @type {number} - */ -// LINT.IfChange -Storage.DEFAULT_PIVOT = 24; -// LINT.ThenChange(//depot/google3/third_party/protobuf/javascript/runtime/kernel/binary_storage_test.js, -// //depot/google3/net/proto2/contrib/js_proto/internal/kernel_message_generator.cc) - -exports = Storage; diff --git a/js/experimental/runtime/kernel/tag.js b/js/experimental/runtime/kernel/tag.js deleted file mode 100644 index b288df3b8..000000000 --- a/js/experimental/runtime/kernel/tag.js +++ /dev/null @@ -1,144 +0,0 @@ -goog.module('protobuf.binary.tag'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const WireType = goog.require('protobuf.binary.WireType'); -const {checkCriticalElementIndex, checkCriticalState} = goog.require('protobuf.internal.checks'); - -/** - * Returns wire type stored in a tag. - * Protos store the wire type as the first 3 bit of a tag. - * @param {number} tag - * @return {!WireType} - */ -function tagToWireType(tag) { - return /** @type {!WireType} */ (tag & 0x07); -} - -/** - * Returns the field number stored in a tag. - * Protos store the field number in the upper 29 bits of a 32 bit number. - * @param {number} tag - * @return {number} - */ -function tagToFieldNumber(tag) { - return tag >>> 3; -} - -/** - * Combines wireType and fieldNumber into a tag. - * @param {!WireType} wireType - * @param {number} fieldNumber - * @return {number} - */ -function createTag(wireType, fieldNumber) { - return (fieldNumber << 3 | wireType) >>> 0; -} - -/** - * Returns the length, in bytes, of the field in the tag stream, less the tag - * itself. - * Note: This moves the cursor in the bufferDecoder. - * @param {!BufferDecoder} bufferDecoder - * @param {number} start - * @param {!WireType} wireType - * @param {number} fieldNumber - * @return {number} - * @private - */ -function getTagLength(bufferDecoder, start, wireType, fieldNumber) { - bufferDecoder.setCursor(start); - skipField(bufferDecoder, wireType, fieldNumber); - return bufferDecoder.cursor() - start; -} - -/** - * @param {number} value - * @return {number} - */ -function get32BitVarintLength(value) { - if (value < 0) { - return 5; - } - let size = 1; - while (value >= 128) { - size++; - value >>>= 7; - } - return size; -} - -/** - * Skips over a field. - * Note: If the field is a start group the entire group will be skipped, placing - * the cursor onto the next field. - * @param {!BufferDecoder} bufferDecoder - * @param {!WireType} wireType - * @param {number} fieldNumber - */ -function skipField(bufferDecoder, wireType, fieldNumber) { - switch (wireType) { - case WireType.VARINT: - checkCriticalElementIndex( - bufferDecoder.cursor(), bufferDecoder.endIndex()); - bufferDecoder.skipVarint(); - return; - case WireType.FIXED64: - bufferDecoder.skip(8); - return; - case WireType.DELIMITED: - checkCriticalElementIndex( - bufferDecoder.cursor(), bufferDecoder.endIndex()); - const length = bufferDecoder.getUnsignedVarint32(); - bufferDecoder.skip(length); - return; - case WireType.START_GROUP: - const foundGroup = skipGroup_(bufferDecoder, fieldNumber); - checkCriticalState(foundGroup, 'No end group found.'); - return; - case WireType.FIXED32: - bufferDecoder.skip(4); - return; - default: - throw new Error(`Unexpected wire type: ${wireType}`); - } -} - -/** - * Skips over fields until it finds the end of a given group consuming the stop - * group tag. - * @param {!BufferDecoder} bufferDecoder - * @param {number} groupFieldNumber - * @return {boolean} Whether the end group tag was found. - * @private - */ -function skipGroup_(bufferDecoder, groupFieldNumber) { - // On a start group we need to keep skipping fields until we find a - // corresponding stop group - // Note: Since we are calling skipField from here nested groups will be - // handled by recursion of this method and thus we will not see a nested - // STOP GROUP here unless there is something wrong with the input data. - while (bufferDecoder.hasNext()) { - const tag = bufferDecoder.getUnsignedVarint32(); - const wireType = tagToWireType(tag); - const fieldNumber = tagToFieldNumber(tag); - - if (wireType === WireType.END_GROUP) { - checkCriticalState( - groupFieldNumber === fieldNumber, - `Expected stop group for fieldnumber ${groupFieldNumber} not found.`); - return true; - } else { - skipField(bufferDecoder, wireType, fieldNumber); - } - } - return false; -} - -exports = { - createTag, - get32BitVarintLength, - getTagLength, - skipField, - tagToWireType, - tagToFieldNumber, -}; diff --git a/js/experimental/runtime/kernel/tag_test.js b/js/experimental/runtime/kernel/tag_test.js deleted file mode 100644 index 35137bb24..000000000 --- a/js/experimental/runtime/kernel/tag_test.js +++ /dev/null @@ -1,221 +0,0 @@ -/** - * @fileoverview Tests for tag.js. - */ -goog.module('protobuf.binary.TagTests'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const WireType = goog.require('protobuf.binary.WireType'); -const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); -const {createTag, get32BitVarintLength, skipField, tagToFieldNumber, tagToWireType} = goog.require('protobuf.binary.tag'); - - -goog.setTestOnly(); - -/** - * @param {...number} bytes - * @return {!ArrayBuffer} - */ -function createArrayBuffer(...bytes) { - return new Uint8Array(bytes).buffer; -} - -describe('skipField', () => { - it('skips varints', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00)); - skipField(bufferDecoder, WireType.VARINT, 1); - expect(bufferDecoder.cursor()).toBe(2); - }); - - it('throws for out of bounds varints', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00)); - bufferDecoder.setCursor(2); - if (CHECK_CRITICAL_STATE) { - expect(() => skipField(bufferDecoder, WireType.VARINT, 1)).toThrowError(); - } - }); - - it('skips fixed64', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); - skipField(bufferDecoder, WireType.FIXED64, 1); - expect(bufferDecoder.cursor()).toBe(8); - }); - - it('throws for fixed64 if length is too short', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => skipField(bufferDecoder, WireType.FIXED64, 1)) - .toThrowError(); - } - }); - - it('skips fixed32', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0x80, 0x00, 0x00, 0x00)); - skipField(bufferDecoder, WireType.FIXED32, 1); - expect(bufferDecoder.cursor()).toBe(4); - }); - - it('throws for fixed32 if length is too short', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => skipField(bufferDecoder, WireType.FIXED32, 1)) - .toThrowError(); - } - }); - - - it('skips length delimited', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0x03, 0x00, 0x00, 0x00)); - skipField(bufferDecoder, WireType.DELIMITED, 1); - expect(bufferDecoder.cursor()).toBe(4); - }); - - it('throws for length delimited if length is too short', () => { - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x03, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => skipField(bufferDecoder, WireType.DELIMITED, 1)) - .toThrowError(); - } - }); - - it('skips groups', () => { - const bufferDecoder = BufferDecoder.fromArrayBuffer( - createArrayBuffer(0x0B, 0x08, 0x01, 0x0C)); - bufferDecoder.setCursor(1); - skipField(bufferDecoder, WireType.START_GROUP, 1); - expect(bufferDecoder.cursor()).toBe(4); - }); - - it('skips group in group', () => { - const buffer = createArrayBuffer( - 0x0B, // start outer - 0x10, 0x01, // field: 2, value: 1 - 0x0B, // start inner group - 0x10, 0x01, // payload inner group - 0x0C, // stop inner group - 0x0C // end outer - ); - const bufferDecoder = BufferDecoder.fromArrayBuffer(buffer); - bufferDecoder.setCursor(1); - skipField(bufferDecoder, WireType.START_GROUP, 1); - expect(bufferDecoder.cursor()).toBe(8); - }); - - it('throws for group if length is too short', () => { - // no closing group - const bufferDecoder = - BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0B, 0x00, 0x00)); - if (CHECK_CRITICAL_STATE) { - expect(() => skipField(bufferDecoder, WireType.START_GROUP, 1)) - .toThrowError(); - } - }); -}); - - -describe('tagToWireType', () => { - it('decodes numbers ', () => { - // simple numbers - expect(tagToWireType(0x00)).toBe(WireType.VARINT); - expect(tagToWireType(0x01)).toBe(WireType.FIXED64); - expect(tagToWireType(0x02)).toBe(WireType.DELIMITED); - expect(tagToWireType(0x03)).toBe(WireType.START_GROUP); - expect(tagToWireType(0x04)).toBe(WireType.END_GROUP); - expect(tagToWireType(0x05)).toBe(WireType.FIXED32); - - // upper bits should not matter - expect(tagToWireType(0x08)).toBe(WireType.VARINT); - expect(tagToWireType(0x09)).toBe(WireType.FIXED64); - expect(tagToWireType(0x0A)).toBe(WireType.DELIMITED); - expect(tagToWireType(0x0B)).toBe(WireType.START_GROUP); - expect(tagToWireType(0x0C)).toBe(WireType.END_GROUP); - expect(tagToWireType(0x0D)).toBe(WireType.FIXED32); - - // upper bits should not matter - expect(tagToWireType(0xF8)).toBe(WireType.VARINT); - expect(tagToWireType(0xF9)).toBe(WireType.FIXED64); - expect(tagToWireType(0xFA)).toBe(WireType.DELIMITED); - expect(tagToWireType(0xFB)).toBe(WireType.START_GROUP); - expect(tagToWireType(0xFC)).toBe(WireType.END_GROUP); - expect(tagToWireType(0xFD)).toBe(WireType.FIXED32); - - // negative numbers work - expect(tagToWireType(-8)).toBe(WireType.VARINT); - expect(tagToWireType(-7)).toBe(WireType.FIXED64); - expect(tagToWireType(-6)).toBe(WireType.DELIMITED); - expect(tagToWireType(-5)).toBe(WireType.START_GROUP); - expect(tagToWireType(-4)).toBe(WireType.END_GROUP); - expect(tagToWireType(-3)).toBe(WireType.FIXED32); - }); -}); - -describe('tagToFieldNumber', () => { - it('returns fieldNumber', () => { - expect(tagToFieldNumber(0x08)).toBe(1); - expect(tagToFieldNumber(0x09)).toBe(1); - expect(tagToFieldNumber(0x10)).toBe(2); - expect(tagToFieldNumber(0x12)).toBe(2); - }); -}); - -describe('createTag', () => { - it('combines fieldNumber and wireType', () => { - expect(createTag(WireType.VARINT, 1)).toBe(0x08); - expect(createTag(WireType.FIXED64, 1)).toBe(0x09); - expect(createTag(WireType.DELIMITED, 1)).toBe(0x0A); - expect(createTag(WireType.START_GROUP, 1)).toBe(0x0B); - expect(createTag(WireType.END_GROUP, 1)).toBe(0x0C); - expect(createTag(WireType.FIXED32, 1)).toBe(0x0D); - - expect(createTag(WireType.VARINT, 2)).toBe(0x10); - expect(createTag(WireType.FIXED64, 2)).toBe(0x11); - expect(createTag(WireType.DELIMITED, 2)).toBe(0x12); - expect(createTag(WireType.START_GROUP, 2)).toBe(0x13); - expect(createTag(WireType.END_GROUP, 2)).toBe(0x14); - expect(createTag(WireType.FIXED32, 2)).toBe(0x15); - - expect(createTag(WireType.VARINT, 0x1FFFFFFF)).toBe(0xFFFFFFF8 >>> 0); - expect(createTag(WireType.FIXED64, 0x1FFFFFFF)).toBe(0xFFFFFFF9 >>> 0); - expect(createTag(WireType.DELIMITED, 0x1FFFFFFF)).toBe(0xFFFFFFFA >>> 0); - expect(createTag(WireType.START_GROUP, 0x1FFFFFFF)).toBe(0xFFFFFFFB >>> 0); - expect(createTag(WireType.END_GROUP, 0x1FFFFFFF)).toBe(0xFFFFFFFC >>> 0); - expect(createTag(WireType.FIXED32, 0x1FFFFFFF)).toBe(0xFFFFFFFD >>> 0); - }); -}); - -describe('get32BitVarintLength', () => { - it('length of tag', () => { - expect(get32BitVarintLength(0)).toBe(1); - expect(get32BitVarintLength(1)).toBe(1); - expect(get32BitVarintLength(1)).toBe(1); - - expect(get32BitVarintLength(Math.pow(2, 7) - 1)).toBe(1); - expect(get32BitVarintLength(Math.pow(2, 7))).toBe(2); - - expect(get32BitVarintLength(Math.pow(2, 14) - 1)).toBe(2); - expect(get32BitVarintLength(Math.pow(2, 14))).toBe(3); - - expect(get32BitVarintLength(Math.pow(2, 21) - 1)).toBe(3); - expect(get32BitVarintLength(Math.pow(2, 21))).toBe(4); - - expect(get32BitVarintLength(Math.pow(2, 28) - 1)).toBe(4); - expect(get32BitVarintLength(Math.pow(2, 28))).toBe(5); - - expect(get32BitVarintLength(Math.pow(2, 31) - 1)).toBe(5); - - expect(get32BitVarintLength(-1)).toBe(5); - expect(get32BitVarintLength(-Math.pow(2, 31))).toBe(5); - - expect(get32BitVarintLength(createTag(WireType.VARINT, 0x1fffffff))) - .toBe(5); - expect(get32BitVarintLength(createTag(WireType.FIXED32, 0x1fffffff))) - .toBe(5); - }); -}); diff --git a/js/experimental/runtime/kernel/textencoding.js b/js/experimental/runtime/kernel/textencoding.js deleted file mode 100644 index fe8fd25e6..000000000 --- a/js/experimental/runtime/kernel/textencoding.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @fileoverview A UTF8 decoder. - */ -goog.module('protobuf.binary.textencoding'); - -const {checkElementIndex} = goog.require('protobuf.internal.checks'); - -/** - * Combines an array of codePoints into a string. - * @param {!Array} codePoints - * @return {string} - */ -function codePointsToString(codePoints) { - // Performance: http://jsperf.com/string-fromcharcode-test/13 - let s = '', i = 0; - const length = codePoints.length; - const BATCH_SIZE = 10000; - while (i < length) { - const end = Math.min(i + BATCH_SIZE, length); - s += String.fromCharCode.apply(null, codePoints.slice(i, end)); - i = end; - } - return s; -} - -/** - * Decodes raw bytes into a string. - * Supports codepoints from U+0000 up to U+10FFFF. - * (http://en.wikipedia.org/wiki/UTF-8). - * @param {!DataView} bytes - * @return {string} - */ -function decode(bytes) { - let cursor = 0; - const codePoints = []; - - while (cursor < bytes.byteLength) { - const c = bytes.getUint8(cursor++); - if (c < 0x80) { // Regular 7-bit ASCII. - codePoints.push(c); - } else if (c < 0xC0) { - // UTF-8 continuation mark. We are out of sync. This - // might happen if we attempted to read a character - // with more than four bytes. - continue; - } else if (c < 0xE0) { // UTF-8 with two bytes. - checkElementIndex(cursor, bytes.byteLength); - const c2 = bytes.getUint8(cursor++); - codePoints.push(((c & 0x1F) << 6) | (c2 & 0x3F)); - } else if (c < 0xF0) { // UTF-8 with three bytes. - checkElementIndex(cursor + 1, bytes.byteLength); - const c2 = bytes.getUint8(cursor++); - const c3 = bytes.getUint8(cursor++); - codePoints.push(((c & 0xF) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F)); - } else if (c < 0xF8) { // UTF-8 with 4 bytes. - checkElementIndex(cursor + 2, bytes.byteLength); - const c2 = bytes.getUint8(cursor++); - const c3 = bytes.getUint8(cursor++); - const c4 = bytes.getUint8(cursor++); - // Characters written on 4 bytes have 21 bits for a codepoint. - // We can't fit that on 16bit characters, so we use surrogates. - let codepoint = ((c & 0x07) << 18) | ((c2 & 0x3F) << 12) | - ((c3 & 0x3F) << 6) | (c4 & 0x3F); - // Surrogates formula from wikipedia. - // 1. Subtract 0x10000 from codepoint - codepoint -= 0x10000; - // 2. Split this into the high 10-bit value and the low 10-bit value - // 3. Add 0xD800 to the high value to form the high surrogate - // 4. Add 0xDC00 to the low value to form the low surrogate: - const low = (codepoint & 0x3FF) + 0xDC00; - const high = ((codepoint >> 10) & 0x3FF) + 0xD800; - codePoints.push(high, low); - } - } - return codePointsToString(codePoints); -} - -/** - * Writes a UTF16 JavaScript string to the buffer encoded as UTF8. - * @param {string} value The string to write. - * @return {!Uint8Array} An array containing the encoded bytes. - */ -function encode(value) { - const buffer = []; - - for (let i = 0; i < value.length; i++) { - const c1 = value.charCodeAt(i); - - if (c1 < 0x80) { - buffer.push(c1); - } else if (c1 < 0x800) { - buffer.push((c1 >> 6) | 0xC0); - buffer.push((c1 & 0x3F) | 0x80); - } else if (c1 < 0xD800 || c1 >= 0xE000) { - buffer.push((c1 >> 12) | 0xE0); - buffer.push(((c1 >> 6) & 0x3F) | 0x80); - buffer.push((c1 & 0x3F) | 0x80); - } else { - // surrogate pair - i++; - checkElementIndex(i, value.length); - const c2 = value.charCodeAt(i); - const paired = 0x10000 + (((c1 & 0x3FF) << 10) | (c2 & 0x3FF)); - buffer.push((paired >> 18) | 0xF0); - buffer.push(((paired >> 12) & 0x3F) | 0x80); - buffer.push(((paired >> 6) & 0x3F) | 0x80); - buffer.push((paired & 0x3F) | 0x80); - } - } - return new Uint8Array(buffer); -} - -exports = { - decode, - encode, -}; diff --git a/js/experimental/runtime/kernel/textencoding_test.js b/js/experimental/runtime/kernel/textencoding_test.js deleted file mode 100644 index c7ecd18a6..000000000 --- a/js/experimental/runtime/kernel/textencoding_test.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @fileoverview Tests for textdecoder.js. - */ -goog.module('protobuf.binary.TextDecoderTest'); - -goog.setTestOnly(); - -const {decode, encode} = goog.require('protobuf.binary.textencoding'); - -describe('Decode does', () => { - it('return empty string for empty array', () => { - expect(decode(new DataView(new ArrayBuffer(0)))).toEqual(''); - }); - - it('throw on null being passed', () => { - expect(() => decode(/** @type {!DataView} */ (/** @type {*} */ (null)))) - .toThrow(); - }); -}); - -describe('Encode does', () => { - it('return empty array for empty string', () => { - expect(encode('')).toEqual(new Uint8Array(0)); - }); - - it('throw on null being passed', () => { - expect(() => encode(/** @type {string} */ (/** @type {*} */ (null)))) - .toThrow(); - }); -}); - -/** @const {!TextEncoder} */ -const textEncoder = new TextEncoder('utf-8'); - -/** - * A Pair of string and Uint8Array representing the same data. - * Each pair has the string value and its utf-8 bytes. - */ -class Pair { - /** - * Constructs a pair from a given string. - * @param {string} s - * @return {!Pair} - */ - static fromString(s) { - return new Pair(s, textEncoder.encode(s).buffer); - } - /** - * Constructs a pair from a given charCode. - * @param {number} charCode - * @return {!Pair} - */ - static fromCharCode(charCode) { - return Pair.fromString(String.fromCharCode(charCode)); - } - - /** - * @param {string} stringValue - * @param {!ArrayBuffer} bytes - * @private - */ - constructor(stringValue, bytes) { - /** @const @private {string} */ - this.stringValue_ = stringValue; - /** @const @private {!ArrayBuffer} */ - this.bytes_ = bytes; - } - - /** Ensures that a given pair encodes and decodes round trip*/ - expectPairToMatch() { - expect(decode(new DataView(this.bytes_))).toEqual(this.stringValue_); - expect(encode(this.stringValue_)).toEqual(new Uint8Array(this.bytes_)); - } -} - -describe('textencoding does', () => { - it('works for empty string', () => { - Pair.fromString('').expectPairToMatch(); - }); - - it('decode and encode random strings', () => { - // 1 byte strings - Pair.fromString('hello').expectPairToMatch(); - Pair.fromString('HELLO1!'); - - // 2 byte String - Pair.fromString('©').expectPairToMatch(); - - // 3 byte string - Pair.fromString('❄').expectPairToMatch(); - - // 4 byte string - Pair.fromString('😁').expectPairToMatch(); - }); - - it('decode and encode 1 byte strings', () => { - for (let i = 0; i < 0x80; i++) { - Pair.fromCharCode(i).expectPairToMatch(); - } - }); - - it('decode and encode 2 byte strings', () => { - for (let i = 0xC0; i < 0x7FF; i++) { - Pair.fromCharCode(i).expectPairToMatch(); - } - }); - - it('decode and encode 3 byte strings', () => { - for (let i = 0x7FF; i < 0x8FFF; i++) { - Pair.fromCharCode(i).expectPairToMatch(); - } - }); -}); diff --git a/js/experimental/runtime/kernel/typed_arrays.js b/js/experimental/runtime/kernel/typed_arrays.js deleted file mode 100644 index 028096510..000000000 --- a/js/experimental/runtime/kernel/typed_arrays.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @fileoverview Helper methods for typed arrays. - */ -goog.module('protobuf.binary.typedArrays'); - -const {assert} = goog.require('goog.asserts'); - -/** - * @param {!ArrayBuffer} buffer1 - * @param {!ArrayBuffer} buffer2 - * @return {boolean} - */ -function arrayBufferEqual(buffer1, buffer2) { - if (!buffer1 || !buffer2) { - throw new Error('Buffer shouldn\'t be empty'); - } - - const array1 = new Uint8Array(buffer1); - const array2 = new Uint8Array(buffer2); - - return uint8ArrayEqual(array1, array2); -} - -/** - * @param {!Uint8Array} array1 - * @param {!Uint8Array} array2 - * @return {boolean} - */ -function uint8ArrayEqual(array1, array2) { - if (array1 === array2) { - return true; - } - - if (array1.byteLength !== array2.byteLength) { - return false; - } - - for (let i = 0; i < array1.byteLength; i++) { - if (array1[i] !== array2[i]) { - return false; - } - } - return true; -} - -/** - * ArrayBuffer.prototype.slice, but fallback to manual copy if missing. - * @param {!ArrayBuffer} buffer - * @param {number} start - * @param {number=} end - * @return {!ArrayBuffer} New array buffer with given the contents of `buffer`. - */ -function arrayBufferSlice(buffer, start, end = undefined) { - // The fallback isn't fully compatible with ArrayBuffer.slice, enforce - // strict requirements on start/end. - // Spec: - // https://www.ecma-international.org/ecma-262/6.0/#sec-arraybuffer.prototype.slice - assert(start >= 0); - assert(end === undefined || (end >= 0 && end <= buffer.byteLength)); - assert((end === undefined ? buffer.byteLength : end) >= start); - if (buffer.slice) { - const slicedBuffer = buffer.slice(start, end); - // The ArrayBuffer.prototype.slice function was flawed before iOS 12.2. This - // causes 0-length results when passing undefined or a number greater - // than 32 bits for the optional end value. In these cases, we fall back to - // using our own slice implementation. - // More details: https://bugs.webkit.org/show_bug.cgi?id=185127 - if (slicedBuffer.byteLength !== 0 || (start === end)) { - return slicedBuffer; - } - } - const realEnd = end == null ? buffer.byteLength : end; - const length = realEnd - start; - assert(length >= 0); - const view = new Uint8Array(buffer, start, length); - // A TypedArray constructed from another Typed array copies the data. - const clone = new Uint8Array(view); - - return clone.buffer; -} - -/** - * Returns a new Uint8Array with the size and contents of the given - * ArrayBufferView. ArrayBufferView is an interface implemented by DataView, - * Uint8Array and all typed arrays. - * @param {!ArrayBufferView} view - * @return {!Uint8Array} - */ -function cloneArrayBufferView(view) { - return new Uint8Array(arrayBufferSlice( - view.buffer, view.byteOffset, view.byteOffset + view.byteLength)); -} - -/** - * Returns a 32 bit number for the corresponding Uint8Array. - * @param {!Uint8Array} array - * @return {number} - */ -function hashUint8Array(array) { - const prime = 31; - let result = 17; - - for (let i = 0; i < array.length; i++) { - // '| 0' ensures signed 32 bits - result = (result * prime + array[i]) | 0; - } - return result; -} - -exports = { - arrayBufferEqual, - uint8ArrayEqual, - arrayBufferSlice, - cloneArrayBufferView, - hashUint8Array, -}; diff --git a/js/experimental/runtime/kernel/typed_arrays_test.js b/js/experimental/runtime/kernel/typed_arrays_test.js deleted file mode 100644 index be9ba65da..000000000 --- a/js/experimental/runtime/kernel/typed_arrays_test.js +++ /dev/null @@ -1,191 +0,0 @@ -/** - * @fileoverview Tests for typed_arrays.js. - */ -goog.module('protobuf.binary.typedArraysTest'); - -const {arrayBufferEqual, arrayBufferSlice, cloneArrayBufferView, hashUint8Array, uint8ArrayEqual} = goog.require('protobuf.binary.typedArrays'); - -describe('arrayBufferEqual', () => { - it('returns true for empty buffers', () => { - const buffer1 = new ArrayBuffer(0); - const buffer2 = new ArrayBuffer(0); - expect(arrayBufferEqual(buffer1, buffer2)).toBe(true); - }); - - it('throws for first null buffers', () => { - const buffer = new ArrayBuffer(0); - expect( - () => arrayBufferEqual( - /** @type {!ArrayBuffer} */ (/** @type {*} */ (null)), buffer)) - .toThrow(); - }); - - it('throws for second null buffers', () => { - const buffer = new ArrayBuffer(0); - expect( - () => arrayBufferEqual( - buffer, /** @type {!ArrayBuffer} */ (/** @type {*} */ (null)))) - .toThrow(); - }); - - it('returns true for arrays with same values', () => { - const array1 = new Uint8Array(4); - array1[0] = 1; - const array2 = new Uint8Array(4); - array2[0] = 1; - expect(arrayBufferEqual(array1.buffer, array2.buffer)).toBe(true); - }); - - it('returns false for arrays with different values', () => { - const array1 = new Uint8Array(4); - array1[0] = 1; - const array2 = new Uint8Array(4); - array2[0] = 2; - expect(arrayBufferEqual(array1.buffer, array2.buffer)).toBe(false); - }); - - it('returns true same instance', () => { - const array1 = new Uint8Array(4); - array1[0] = 1; - expect(arrayBufferEqual(array1.buffer, array1.buffer)).toBe(true); - }); -}); - -describe('uint8ArrayEqual', () => { - it('returns true for empty arrays', () => { - const array1 = new Uint8Array(0); - const array2 = new Uint8Array(0); - expect(uint8ArrayEqual(array1, array2)).toBe(true); - }); - - it('throws for first Uint8Array array', () => { - const array = new Uint8Array(0); - expect( - () => uint8ArrayEqual( - /** @type {!Uint8Array} */ (/** @type {*} */ (null)), array)) - .toThrow(); - }); - - it('throws for second null array', () => { - const array = new Uint8Array(0); - expect( - () => uint8ArrayEqual( - array, /** @type {!Uint8Array} */ (/** @type {*} */ (null)))) - .toThrow(); - }); - - it('returns true for arrays with same values', () => { - const buffer1 = new Uint8Array([0, 1, 2, 3]).buffer; - const buffer2 = new Uint8Array([1, 2, 3, 4]).buffer; - const array1 = new Uint8Array(buffer1, 1, 3); - const array2 = new Uint8Array(buffer2, 0, 3); - expect(uint8ArrayEqual(array1, array2)).toBe(true); - }); - - it('returns false for arrays with different values', () => { - const array1 = new Uint8Array(4); - array1[0] = 1; - const array2 = new Uint8Array(4); - array2[0] = 2; - expect(uint8ArrayEqual(array1, array2)).toBe(false); - }); - - it('returns true same instance', () => { - const array1 = new Uint8Array(4); - array1[0] = 1; - expect(uint8ArrayEqual(array1, array1)).toBe(true); - }); -}); - -describe('arrayBufferSlice', () => { - it('Returns a new instance.', () => { - const buffer1 = new ArrayBuffer(0); - const buffer2 = arrayBufferSlice(buffer1, 0); - expect(buffer2).not.toBe(buffer1); - expect(arrayBufferEqual(buffer1, buffer2)).toBe(true); - }); - - it('Copies data with positive start/end.', () => { - const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer; - expect(buffer1.byteLength).toEqual(10); - - const buffer2 = arrayBufferSlice(buffer1, 2, 6); - expect(buffer2.byteLength).toEqual(4); - expect(buffer2).not.toBe(buffer1); - const expected = new Uint8Array([2, 3, 4, 5]).buffer; - expect(arrayBufferEqual(expected, buffer2)).toBe(true); - }); - - it('Copies all data without end.', () => { - const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer; - expect(buffer1.byteLength).toEqual(10); - - const buffer2 = arrayBufferSlice(buffer1, 0); - expect(buffer2.byteLength).toEqual(10); - expect(arrayBufferEqual(buffer1, buffer2)).toBe(true); - }); - - if (goog.DEBUG) { - it('Fails with negative end.', () => { - const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer; - expect(() => void arrayBufferSlice(buffer1, 2, -1)).toThrow(); - }); - - it('Fails with negative start.', () => { - const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer; - expect(() => void arrayBufferSlice(buffer1, 2, -1)).toThrow(); - }); - - it('Fails when start > end.', () => { - const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer; - expect(() => void arrayBufferSlice(buffer1, 2, 1)).toThrow(); - }); - } -}); - -describe('cloneArrayBufferView', () => { - it('Returns a new instance.', () => { - const array1 = new Uint8Array(0); - const array2 = cloneArrayBufferView(new Uint8Array(array1)); - expect(array2).not.toBe(array1); - expect(uint8ArrayEqual(array1, array2)).toBe(true); - }); - - it('Returns an array of the exact size.', () => { - const array1 = - new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).subarray(2, 5); - expect(array1.length).toEqual(3); - expect(array1.buffer.byteLength).toEqual(10); - const array2 = cloneArrayBufferView(array1); - expect(array2.byteLength).toEqual(3); - expect(array2).toEqual(new Uint8Array([2, 3, 4])); - }); -}); - -describe('hashUint8Array', () => { - it('returns same hashcode for empty Uint8Arrays', () => { - const array1 = new Uint8Array(0); - const array2 = new Uint8Array(0); - expect(hashUint8Array(array1)).toBe(hashUint8Array(array2)); - }); - - it('returns same hashcode for Uint8Arrays with same values', () => { - const array1 = new Uint8Array(4); - array1[0] = 1; - const array2 = new Uint8Array(4); - array2[0] = 1; - expect(hashUint8Array(array1)).toBe(hashUint8Array(array2)); - }); - - it('returns different hashcode for Uint8Arrays with different values', () => { - // This test might fail in the future if the hashing algorithm is updated - // and we end up with a collision here. - // We still need this test to make sure that we are not just returning - // the same number for all buffers. - const array1 = new Uint8Array(4); - array1[0] = 1; - const array2 = new Uint8Array(4); - array2[0] = 2; - expect(hashUint8Array(array1)).not.toBe(hashUint8Array(array2)); - }); -}); diff --git a/js/experimental/runtime/kernel/uint32_test_pairs.js b/js/experimental/runtime/kernel/uint32_test_pairs.js deleted file mode 100644 index 851996d0f..000000000 --- a/js/experimental/runtime/kernel/uint32_test_pairs.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @fileoverview Test data for int32 encoding and decoding. - */ -goog.module('protobuf.binary.uint32TestPairs'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); - -/** - * An array of Pairs of float values and their bit representation. - * This is used to test encoding and decoding from/to the protobuf wire format. - * @return {!Array<{name: string, intValue:number, bufferDecoder: - * !BufferDecoder, error: (boolean|undefined), - * skip_reader: (boolean|undefined), skip_writer: (boolean|undefined)}>} - */ -function getUint32Pairs() { - const uint32Pairs = [ - { - name: 'zero', - intValue: 0, - bufferDecoder: createBufferDecoder(0x00), - }, - { - name: 'one ', - intValue: 1, - bufferDecoder: createBufferDecoder(0x01), - }, - { - name: 'max signed int 2^31 - 1', - intValue: Math.pow(2, 31) - 1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x07), - }, - { - name: 'max unsigned int 2^32 - 1', - intValue: Math.pow(2, 32) - 1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F), - }, - { - name: 'negative one', - intValue: -1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F), - skip_reader: true, - }, - { - name: 'truncates more than 32 bits', - intValue: Math.pow(2, 32) - 1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01), - skip_writer: true, - }, - { - name: 'truncates more than 32 bits (bit 33 set)', - intValue: Math.pow(2, 28) - 1, - bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x10), - skip_writer: true, - }, - { - name: 'errors out for 11 bytes', - intValue: Math.pow(2, 32) - 1, - bufferDecoder: createBufferDecoder( - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), - error: true, - skip_writer: true, - }, - ]; - return [...uint32Pairs]; -} - -exports = {getUint32Pairs}; diff --git a/js/experimental/runtime/kernel/uint8arrays.js b/js/experimental/runtime/kernel/uint8arrays.js deleted file mode 100644 index c6bed1666..000000000 --- a/js/experimental/runtime/kernel/uint8arrays.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @fileoverview Helper methods for Uint8Arrays. - */ -goog.module('protobuf.binary.uint8arrays'); - -/** - * Combines multiple bytes arrays (either Uint8Array or number array whose - * values are bytes) into a single Uint8Array. - * @param {!Array|!Array>} arrays - * @return {!Uint8Array} - */ -function concatenateByteArrays(arrays) { - let totalLength = 0; - for (const array of arrays) { - totalLength += array.length; - } - const result = new Uint8Array(totalLength); - let offset = 0; - for (const array of arrays) { - result.set(array, offset); - offset += array.length; - } - return result; -} - -exports = { - concatenateByteArrays, -}; diff --git a/js/experimental/runtime/kernel/uint8arrays_test.js b/js/experimental/runtime/kernel/uint8arrays_test.js deleted file mode 100644 index 6bb5a7565..000000000 --- a/js/experimental/runtime/kernel/uint8arrays_test.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * @fileoverview Tests for uint8arrays.js. - */ -goog.module('protobuf.binary.Uint8ArraysTest'); - -goog.setTestOnly(); - -const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays'); - -describe('concatenateByteArrays does', () => { - it('concatenate empty array', () => { - const byteArrays = []; - expect(concatenateByteArrays(byteArrays)).toEqual(new Uint8Array(0)); - }); - - it('concatenate Uint8Arrays', () => { - const byteArrays = [new Uint8Array([0x01]), new Uint8Array([0x02])]; - expect(concatenateByteArrays(byteArrays)).toEqual(new Uint8Array([ - 0x01, 0x02 - ])); - }); - - it('concatenate array of bytes', () => { - const byteArrays = [[0x01], [0x02]]; - expect(concatenateByteArrays(byteArrays)).toEqual(new Uint8Array([ - 0x01, 0x02 - ])); - }); - - it('concatenate array of non-bytes', () => { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const byteArrays = [[40.0], [256]]; - expect(concatenateByteArrays(byteArrays)).toEqual(new Uint8Array([ - 0x28, 0x00 - ])); - }); - - it('throw for null array', () => { - expect( - () => concatenateByteArrays( - /** @type {!Array} */ (/** @type {*} */ (null)))) - .toThrow(); - }); -}); diff --git a/js/experimental/runtime/kernel/wire_type.js b/js/experimental/runtime/kernel/wire_type.js deleted file mode 100644 index dee6fe4bd..000000000 --- a/js/experimental/runtime/kernel/wire_type.js +++ /dev/null @@ -1,17 +0,0 @@ -goog.module('protobuf.binary.WireType'); - -/** - * Wire-format type codes, taken from proto2/public/wire_format_lite.h. - * @enum {number} - */ -const WireType = { - VARINT: 0, - FIXED64: 1, - DELIMITED: 2, - START_GROUP: 3, - END_GROUP: 4, - FIXED32: 5, - INVALID: 6 -}; - -exports = WireType; diff --git a/js/experimental/runtime/kernel/writer.js b/js/experimental/runtime/kernel/writer.js deleted file mode 100644 index 5b8b79b6c..000000000 --- a/js/experimental/runtime/kernel/writer.js +++ /dev/null @@ -1,743 +0,0 @@ -/** - * @fileoverview Implements Writer for writing data as the binary wire format - * bytes array. - */ -goog.module('protobuf.binary.Writer'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const ByteString = goog.require('protobuf.ByteString'); -const Int64 = goog.require('protobuf.Int64'); -const WireType = goog.require('protobuf.binary.WireType'); -const {POLYFILL_TEXT_ENCODING, checkFieldNumber, checkTypeUnsignedInt32, checkWireType} = goog.require('protobuf.internal.checks'); -const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays'); -const {createTag, getTagLength} = goog.require('protobuf.binary.tag'); -const {encode} = goog.require('protobuf.binary.textencoding'); - -/** - * Returns a valid utf-8 encoder function based on TextEncoder if available or - * a polyfill. - * Some of the environments we run in do not have TextEncoder defined. - * TextEncoder is faster than our polyfill so we prefer it over the polyfill. - * @return {function(string):!Uint8Array} - */ -function getEncoderFunction() { - if (goog.global['TextEncoder']) { - const textEncoder = new goog.global['TextEncoder']('utf-8'); - return s => s.length === 0 ? new Uint8Array(0) : textEncoder.encode(s); - } - if (POLYFILL_TEXT_ENCODING) { - return encode; - } else { - throw new Error( - 'TextEncoder is missing. ' + - 'Enable protobuf.defines.POLYFILL_TEXT_ENCODING'); - } -} - -/** @const {function(string): !Uint8Array} */ -const encoderFunction = getEncoderFunction(); - -/** - * Writer provides methods for encoding all protobuf supported type into a - * binary format bytes array. - * Check https://developers.google.com/protocol-buffers/docs/encoding for binary - * format definition. - * @final - * @package - */ -class Writer { - constructor() { - /** - * Blocks of data that needs to be serialized. After writing all the data, - * the blocks are concatenated into a single Uint8Array. - * @private {!Array} - */ - this.blocks_ = []; - - /** - * A buffer for writing varint data (tag number + field number for each - * field, int32, uint32 etc.). Before writing a non-varint data block - * (string, fixed32 etc.), the buffer is appended to the block array as a - * new block, and a new buffer is started. - * - * We could've written each varint as a new block instead of writing - * multiple varints in this buffer. But this will increase the number of - * blocks, and concatenating many small blocks is slower than concatenating - * few large blocks. - * - * TODO: Experiment with writing data in a fixed-length - * Uint8Array instead of using a growing buffer. - * - * @private {!Array} - */ - this.currentBuffer_ = []; - } - - /** - * Converts the encoded data into a Uint8Array. - * The writer is also reset. - * @return {!ArrayBuffer} - */ - getAndResetResultBuffer() { - this.closeAndStartNewBuffer_(); - const result = concatenateByteArrays(this.blocks_); - this.blocks_ = []; - return result.buffer; - } - - /** - * Encodes a (field number, wire type) tuple into a wire-format field header. - * @param {number} fieldNumber - * @param {!WireType} wireType - */ - writeTag(fieldNumber, wireType) { - checkFieldNumber(fieldNumber); - checkWireType(wireType); - const tag = createTag(wireType, fieldNumber); - this.writeUnsignedVarint32_(tag); - } - - /** - * Appends the current buffer into the blocks array and starts a new buffer. - * @private - */ - closeAndStartNewBuffer_() { - this.blocks_.push(new Uint8Array(this.currentBuffer_)); - this.currentBuffer_ = []; - } - - /** - * Encodes a 32-bit integer into its wire-format varint representation and - * stores it in the buffer. - * @param {number} value - * @private - */ - writeUnsignedVarint32_(value) { - checkTypeUnsignedInt32(value); - while (value > 0x7f) { - this.currentBuffer_.push((value & 0x7f) | 0x80); - value = value >>> 7; - } - this.currentBuffer_.push(value); - } - - /**************************************************************************** - * OPTIONAL METHODS - ****************************************************************************/ - - /** - * Writes a boolean value field to the buffer as a varint. - * @param {boolean} value - * @private - */ - writeBoolValue_(value) { - this.currentBuffer_.push(value ? 1 : 0); - } - - /** - * Writes a boolean value field to the buffer as a varint. - * @param {number} fieldNumber - * @param {boolean} value - */ - writeBool(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.VARINT); - this.writeBoolValue_(value); - } - - /** - * Writes a bytes value field to the buffer as a length delimited field. - * @param {number} fieldNumber - * @param {!ByteString} value - */ - writeBytes(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.DELIMITED); - const buffer = value.toArrayBuffer(); - this.writeUnsignedVarint32_(buffer.byteLength); - this.writeRaw_(buffer); - } - - /** - * Writes a double value field to the buffer without tag. - * @param {number} value - * @private - */ - writeDoubleValue_(value) { - const buffer = new ArrayBuffer(8); - const view = new DataView(buffer); - view.setFloat64(0, value, true); - this.writeRaw_(buffer); - } - - /** - * Writes a double value field to the buffer. - * @param {number} fieldNumber - * @param {number} value - */ - writeDouble(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.FIXED64); - this.writeDoubleValue_(value); - } - - /** - * Writes a fixed32 value field to the buffer without tag. - * @param {number} value - * @private - */ - writeFixed32Value_(value) { - const buffer = new ArrayBuffer(4); - const view = new DataView(buffer); - view.setUint32(0, value, true); - this.writeRaw_(buffer); - } - - /** - * Writes a fixed32 value field to the buffer. - * @param {number} fieldNumber - * @param {number} value - */ - writeFixed32(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.FIXED32); - this.writeFixed32Value_(value); - } - - /** - * Writes a float value field to the buffer without tag. - * @param {number} value - * @private - */ - writeFloatValue_(value) { - const buffer = new ArrayBuffer(4); - const view = new DataView(buffer); - view.setFloat32(0, value, true); - this.writeRaw_(buffer); - } - - /** - * Writes a float value field to the buffer. - * @param {number} fieldNumber - * @param {number} value - */ - writeFloat(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.FIXED32); - this.writeFloatValue_(value); - } - - /** - * Writes a int32 value field to the buffer as a varint without tag. - * @param {number} value - * @private - */ - writeInt32Value_(value) { - if (value >= 0) { - this.writeVarint64_(0, value); - } else { - this.writeVarint64_(0xFFFFFFFF, value); - } - } - - /** - * Writes a int32 value field to the buffer as a varint. - * @param {number} fieldNumber - * @param {number} value - */ - writeInt32(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.VARINT); - this.writeInt32Value_(value); - } - - /** - * Writes a int64 value field to the buffer as a varint. - * @param {number} fieldNumber - * @param {!Int64} value - */ - writeInt64(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.VARINT); - this.writeVarint64_(value.getHighBits(), value.getLowBits()); - } - - /** - * Writes a sfixed32 value field to the buffer. - * @param {number} value - * @private - */ - writeSfixed32Value_(value) { - const buffer = new ArrayBuffer(4); - const view = new DataView(buffer); - view.setInt32(0, value, true); - this.writeRaw_(buffer); - } - - /** - * Writes a sfixed32 value field to the buffer. - * @param {number} fieldNumber - * @param {number} value - */ - writeSfixed32(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.FIXED32); - this.writeSfixed32Value_(value); - } - - /** - * Writes a sfixed64 value field to the buffer without tag. - * @param {!Int64} value - * @private - */ - writeSfixed64Value_(value) { - const buffer = new ArrayBuffer(8); - const view = new DataView(buffer); - view.setInt32(0, value.getLowBits(), true); - view.setInt32(4, value.getHighBits(), true); - this.writeRaw_(buffer); - } - - /** - * Writes a sfixed64 value field to the buffer. - * @param {number} fieldNumber - * @param {!Int64} value - */ - writeSfixed64(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.FIXED64); - this.writeSfixed64Value_(value); - } - - /** - * Writes a sfixed64 value field to the buffer. - * @param {number} fieldNumber - */ - writeStartGroup(fieldNumber) { - this.writeTag(fieldNumber, WireType.START_GROUP); - } - - /** - * Writes a sfixed64 value field to the buffer. - * @param {number} fieldNumber - */ - writeEndGroup(fieldNumber) { - this.writeTag(fieldNumber, WireType.END_GROUP); - } - - /** - * Writes a uint32 value field to the buffer as a varint without tag. - * @param {number} value - * @private - */ - writeUint32Value_(value) { - this.writeVarint64_(0, value); - } - - /** - * Writes a uint32 value field to the buffer as a varint. - * @param {number} fieldNumber - * @param {number} value - */ - writeUint32(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.VARINT); - this.writeUint32Value_(value); - } - - /** - * Writes the bits of a 64 bit number to the buffer as a varint. - * @param {number} highBits - * @param {number} lowBits - * @private - */ - writeVarint64_(highBits, lowBits) { - for (let i = 0; i < 28; i = i + 7) { - const shift = lowBits >>> i; - const hasNext = !((shift >>> 7) === 0 && highBits === 0); - const byte = (hasNext ? shift | 0x80 : shift) & 0xFF; - this.currentBuffer_.push(byte); - if (!hasNext) { - return; - } - } - - const splitBits = ((lowBits >>> 28) & 0x0F) | ((highBits & 0x07) << 4); - const hasMoreBits = !((highBits >> 3) === 0); - this.currentBuffer_.push( - (hasMoreBits ? splitBits | 0x80 : splitBits) & 0xFF); - - if (!hasMoreBits) { - return; - } - - for (let i = 3; i < 31; i = i + 7) { - const shift = highBits >>> i; - const hasNext = !((shift >>> 7) === 0); - const byte = (hasNext ? shift | 0x80 : shift) & 0xFF; - this.currentBuffer_.push(byte); - if (!hasNext) { - return; - } - } - - this.currentBuffer_.push((highBits >>> 31) & 0x01); - } - - /** - * Writes a sint32 value field to the buffer as a varint without tag. - * @param {number} value - * @private - */ - writeSint32Value_(value) { - value = (value << 1) ^ (value >> 31); - this.writeVarint64_(0, value); - } - - /** - * Writes a sint32 value field to the buffer as a varint. - * @param {number} fieldNumber - * @param {number} value - */ - writeSint32(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.VARINT); - this.writeSint32Value_(value); - } - - /** - * Writes a sint64 value field to the buffer as a varint without tag. - * @param {!Int64} value - * @private - */ - writeSint64Value_(value) { - const highBits = value.getHighBits(); - const lowBits = value.getLowBits(); - - const sign = highBits >> 31; - const encodedLowBits = (lowBits << 1) ^ sign; - const encodedHighBits = ((highBits << 1) | (lowBits >>> 31)) ^ sign; - this.writeVarint64_(encodedHighBits, encodedLowBits); - } - - /** - * Writes a sint64 value field to the buffer as a varint. - * @param {number} fieldNumber - * @param {!Int64} value - */ - writeSint64(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.VARINT); - this.writeSint64Value_(value); - } - - /** - * Writes a string value field to the buffer as a varint. - * @param {number} fieldNumber - * @param {string} value - */ - writeString(fieldNumber, value) { - this.writeTag(fieldNumber, WireType.DELIMITED); - const array = encoderFunction(value); - this.writeUnsignedVarint32_(array.length); - this.closeAndStartNewBuffer_(); - this.blocks_.push(array); - } - - /** - * Writes raw bytes to the buffer. - * @param {!ArrayBuffer} arrayBuffer - * @private - */ - writeRaw_(arrayBuffer) { - this.closeAndStartNewBuffer_(); - this.blocks_.push(new Uint8Array(arrayBuffer)); - } - - /** - * Writes raw bytes to the buffer. - * @param {!BufferDecoder} bufferDecoder - * @param {number} start - * @param {!WireType} wireType - * @param {number} fieldNumber - * @package - */ - writeBufferDecoder(bufferDecoder, start, wireType, fieldNumber) { - this.closeAndStartNewBuffer_(); - const dataLength = - getTagLength(bufferDecoder, start, wireType, fieldNumber); - this.blocks_.push( - bufferDecoder.subBufferDecoder(start, dataLength).asUint8Array()); - } - - /** - * Write the whole bytes as a length delimited field. - * @param {number} fieldNumber - * @param {!ArrayBuffer} arrayBuffer - */ - writeDelimited(fieldNumber, arrayBuffer) { - this.writeTag(fieldNumber, WireType.DELIMITED); - this.writeUnsignedVarint32_(arrayBuffer.byteLength); - this.writeRaw_(arrayBuffer); - } - - /**************************************************************************** - * REPEATED METHODS - ****************************************************************************/ - - /** - * Writes repeated boolean values to the buffer as unpacked varints. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedBool(fieldNumber, values) { - values.forEach(val => this.writeBool(fieldNumber, val)); - } - - /** - * Writes repeated boolean values to the buffer as packed varints. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedBool(fieldNumber, values) { - this.writeFixedPacked_( - fieldNumber, values, val => this.writeBoolValue_(val), 1); - } - - /** - * Writes repeated double values to the buffer as unpacked fixed64. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedDouble(fieldNumber, values) { - values.forEach(val => this.writeDouble(fieldNumber, val)); - } - - /** - * Writes repeated double values to the buffer as packed fixed64. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedDouble(fieldNumber, values) { - this.writeFixedPacked_( - fieldNumber, values, val => this.writeDoubleValue_(val), 8); - } - - /** - * Writes repeated fixed32 values to the buffer as unpacked fixed32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedFixed32(fieldNumber, values) { - values.forEach(val => this.writeFixed32(fieldNumber, val)); - } - - /** - * Writes repeated fixed32 values to the buffer as packed fixed32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedFixed32(fieldNumber, values) { - this.writeFixedPacked_( - fieldNumber, values, val => this.writeFixed32Value_(val), 4); - } - - /** - * Writes repeated float values to the buffer as unpacked fixed64. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedFloat(fieldNumber, values) { - values.forEach(val => this.writeFloat(fieldNumber, val)); - } - - /** - * Writes repeated float values to the buffer as packed fixed64. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedFloat(fieldNumber, values) { - this.writeFixedPacked_( - fieldNumber, values, val => this.writeFloatValue_(val), 4); - } - - /** - * Writes repeated int32 values to the buffer as unpacked int32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedInt32(fieldNumber, values) { - values.forEach(val => this.writeInt32(fieldNumber, val)); - } - - /** - * Writes repeated int32 values to the buffer as packed int32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedInt32(fieldNumber, values) { - this.writeVariablePacked_( - fieldNumber, values, (writer, val) => writer.writeInt32Value_(val)); - } - - /** - * Writes repeated int64 values to the buffer as unpacked varint. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedInt64(fieldNumber, values) { - values.forEach(val => this.writeInt64(fieldNumber, val)); - } - - /** - * Writes repeated int64 values to the buffer as packed varint. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedInt64(fieldNumber, values) { - this.writeVariablePacked_( - fieldNumber, values, - (writer, val) => - writer.writeVarint64_(val.getHighBits(), val.getLowBits())); - } - - /** - * Writes repeated sfixed32 values to the buffer as unpacked fixed32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedSfixed32(fieldNumber, values) { - values.forEach(val => this.writeSfixed32(fieldNumber, val)); - } - - /** - * Writes repeated sfixed32 values to the buffer as packed fixed32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedSfixed32(fieldNumber, values) { - this.writeFixedPacked_( - fieldNumber, values, val => this.writeSfixed32Value_(val), 4); - } - - /** - * Writes repeated sfixed64 values to the buffer as unpacked fixed64. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedSfixed64(fieldNumber, values) { - values.forEach(val => this.writeSfixed64(fieldNumber, val)); - } - - /** - * Writes repeated sfixed64 values to the buffer as packed fixed64. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedSfixed64(fieldNumber, values) { - this.writeFixedPacked_( - fieldNumber, values, val => this.writeSfixed64Value_(val), 8); - } - - /** - * Writes repeated sint32 values to the buffer as unpacked sint32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedSint32(fieldNumber, values) { - values.forEach(val => this.writeSint32(fieldNumber, val)); - } - - /** - * Writes repeated sint32 values to the buffer as packed sint32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedSint32(fieldNumber, values) { - this.writeVariablePacked_( - fieldNumber, values, (writer, val) => writer.writeSint32Value_(val)); - } - - /** - * Writes repeated sint64 values to the buffer as unpacked varint. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedSint64(fieldNumber, values) { - values.forEach(val => this.writeSint64(fieldNumber, val)); - } - - /** - * Writes repeated sint64 values to the buffer as packed varint. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedSint64(fieldNumber, values) { - this.writeVariablePacked_( - fieldNumber, values, (writer, val) => writer.writeSint64Value_(val)); - } - - /** - * Writes repeated uint32 values to the buffer as unpacked uint32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedUint32(fieldNumber, values) { - values.forEach(val => this.writeUint32(fieldNumber, val)); - } - - /** - * Writes repeated uint32 values to the buffer as packed uint32. - * @param {number} fieldNumber - * @param {!Array} values - */ - writePackedUint32(fieldNumber, values) { - this.writeVariablePacked_( - fieldNumber, values, (writer, val) => writer.writeUint32Value_(val)); - } - - /** - * Writes repeated bytes values to the buffer. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedBytes(fieldNumber, values) { - values.forEach(val => this.writeBytes(fieldNumber, val)); - } - - /** - * Writes packed fields with fixed length. - * @param {number} fieldNumber - * @param {!Array} values - * @param {function(T)} valueWriter - * @param {number} entitySize - * @template T - * @private - */ - writeFixedPacked_(fieldNumber, values, valueWriter, entitySize) { - if (values.length === 0) { - return; - } - this.writeTag(fieldNumber, WireType.DELIMITED); - this.writeUnsignedVarint32_(values.length * entitySize); - this.closeAndStartNewBuffer_(); - values.forEach(value => valueWriter(value)); - } - - /** - * Writes packed fields with variable length. - * @param {number} fieldNumber - * @param {!Array} values - * @param {function(!Writer, T)} valueWriter - * @template T - * @private - */ - writeVariablePacked_(fieldNumber, values, valueWriter) { - if (values.length === 0) { - return; - } - const writer = new Writer(); - values.forEach(val => valueWriter(writer, val)); - const bytes = writer.getAndResetResultBuffer(); - this.writeDelimited(fieldNumber, bytes); - } - - /** - * Writes repeated string values to the buffer. - * @param {number} fieldNumber - * @param {!Array} values - */ - writeRepeatedString(fieldNumber, values) { - values.forEach(val => this.writeString(fieldNumber, val)); - } -} - -exports = Writer; diff --git a/js/experimental/runtime/kernel/writer_test.js b/js/experimental/runtime/kernel/writer_test.js deleted file mode 100644 index 019ae1e18..000000000 --- a/js/experimental/runtime/kernel/writer_test.js +++ /dev/null @@ -1,927 +0,0 @@ -/** - * @fileoverview Tests for writer.js. - */ -goog.module('protobuf.binary.WriterTest'); - -goog.setTestOnly(); - -// Note to the reader: -// Since the writer behavior changes with the checking level some of the tests -// in this file have to know which checking level is enable to make correct -// assertions. -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const ByteString = goog.require('protobuf.ByteString'); -const WireType = goog.require('protobuf.binary.WireType'); -const Writer = goog.require('protobuf.binary.Writer'); -const {CHECK_BOUNDS, CHECK_TYPE, MAX_FIELD_NUMBER} = goog.require('protobuf.internal.checks'); -const {arrayBufferSlice} = goog.require('protobuf.binary.typedArrays'); -const {getDoublePairs} = goog.require('protobuf.binary.doubleTestPairs'); -const {getFixed32Pairs} = goog.require('protobuf.binary.fixed32TestPairs'); -const {getFloatPairs} = goog.require('protobuf.binary.floatTestPairs'); -const {getInt32Pairs} = goog.require('protobuf.binary.int32TestPairs'); -const {getInt64Pairs} = goog.require('protobuf.binary.int64TestPairs'); -const {getPackedBoolPairs} = goog.require('protobuf.binary.packedBoolTestPairs'); -const {getPackedDoublePairs} = goog.require('protobuf.binary.packedDoubleTestPairs'); -const {getPackedFixed32Pairs} = goog.require('protobuf.binary.packedFixed32TestPairs'); -const {getPackedFloatPairs} = goog.require('protobuf.binary.packedFloatTestPairs'); -const {getPackedInt32Pairs} = goog.require('protobuf.binary.packedInt32TestPairs'); -const {getPackedInt64Pairs} = goog.require('protobuf.binary.packedInt64TestPairs'); -const {getPackedSfixed32Pairs} = goog.require('protobuf.binary.packedSfixed32TestPairs'); -const {getPackedSfixed64Pairs} = goog.require('protobuf.binary.packedSfixed64TestPairs'); -const {getPackedSint32Pairs} = goog.require('protobuf.binary.packedSint32TestPairs'); -const {getPackedSint64Pairs} = goog.require('protobuf.binary.packedSint64TestPairs'); -const {getPackedUint32Pairs} = goog.require('protobuf.binary.packedUint32TestPairs'); -const {getSfixed32Pairs} = goog.require('protobuf.binary.sfixed32TestPairs'); -const {getSfixed64Pairs} = goog.require('protobuf.binary.sfixed64TestPairs'); -const {getSint32Pairs} = goog.require('protobuf.binary.sint32TestPairs'); -const {getSint64Pairs} = goog.require('protobuf.binary.sint64TestPairs'); -const {getUint32Pairs} = goog.require('protobuf.binary.uint32TestPairs'); - - -/** - * @param {...number} bytes - * @return {!ArrayBuffer} - */ -function createArrayBuffer(...bytes) { - return new Uint8Array(bytes).buffer; -} - -/****************************************************************************** - * OPTIONAL FUNCTIONS - ******************************************************************************/ - -describe('Writer does', () => { - it('return an empty ArrayBuffer when nothing is encoded', () => { - const writer = new Writer(); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - it('encode tag', () => { - const writer = new Writer(); - writer.writeTag(1, WireType.VARINT); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0x08)); - - writer.writeTag(0x0FFFFFFF, WireType.VARINT); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x7)); - - writer.writeTag(0x10000000, WireType.VARINT); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer(0x80, 0x80, 0x80, 0x80, 0x08)); - - writer.writeTag(0x1FFFFFFF, WireType.VARINT); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F)); - }); - - it('reset after calling getAndResetResultBuffer', () => { - const writer = new Writer(); - writer.writeTag(1, WireType.VARINT); - writer.getAndResetResultBuffer(); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - it('fail when field number is too large for writeTag', () => { - const writer = new Writer(); - if (CHECK_TYPE) { - expect(() => writer.writeTag(MAX_FIELD_NUMBER + 1, WireType.VARINT)) - .toThrowError('Field number is out of range: 536870912'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - writer.writeTag(MAX_FIELD_NUMBER + 1, WireType.VARINT); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0)); - } - }); - - it('fail when field number is negative for writeTag', () => { - const writer = new Writer(); - if (CHECK_TYPE) { - expect(() => writer.writeTag(-1, WireType.VARINT)) - .toThrowError('Field number is out of range: -1'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - writer.writeTag(-1, WireType.VARINT); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0xF)); - } - }); - - it('fail when wire type is invalid for writeTag', () => { - const writer = new Writer(); - if (CHECK_TYPE) { - expect(() => writer.writeTag(1, /** @type {!WireType} */ (0x08))) - .toThrowError('Invalid wire type: 8'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - writer.writeTag(1, /** @type {!WireType} */ (0x08)); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0x08)); - } - }); - - it('encode singular boolean value', () => { - const writer = new Writer(); - writer.writeBool(1, true); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer(0x08, 0x01)); - }); - - it('encode length delimited', () => { - const writer = new Writer(); - writer.writeDelimited(1, createArrayBuffer(0x01, 0x02)); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer(0x0A, 0x02, 0x01, 0x02)); - }); -}); - -describe('Writer.writeBufferDecoder does', () => { - it('encode BufferDecoder containing a varint value', () => { - const writer = new Writer(); - const expected = createArrayBuffer( - 0x08, /* varint start= */ 0xFF, /* varint end= */ 0x01, 0x08, 0x01); - writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.VARINT, 1); - const result = writer.getAndResetResultBuffer(); - expect(result).toEqual(arrayBufferSlice(expected, 1, 3)); - }); - - it('encode BufferDecoder containing a fixed64 value', () => { - const writer = new Writer(); - const expected = createArrayBuffer( - 0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - /* fixed64 end= */ 0x08, 0x08, 0x01); - writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED64, 1); - const result = writer.getAndResetResultBuffer(); - expect(result).toEqual(arrayBufferSlice(expected, 1, 9)); - }); - - it('encode BufferDecoder containing a length delimited value', () => { - const writer = new Writer(); - const expected = createArrayBuffer( - 0xA, /* length= */ 0x03, /* data start= */ 0x01, 0x02, - /* data end= */ 0x03, 0x08, 0x01); - writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.DELIMITED, 1); - const result = writer.getAndResetResultBuffer(); - expect(result).toEqual(arrayBufferSlice(expected, 1, 5)); - }); - - it('encode BufferDecoder containing a group', () => { - const writer = new Writer(); - const expected = createArrayBuffer( - 0xB, /* group start= */ 0x08, 0x01, /* nested group start= */ 0x0B, - /* nested group end= */ 0x0C, /* group end= */ 0x0C, 0x08, 0x01); - writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.START_GROUP, 1); - const result = writer.getAndResetResultBuffer(); - expect(result).toEqual(arrayBufferSlice(expected, 1, 6)); - }); - - it('encode BufferDecoder containing a fixed32 value', () => { - const writer = new Writer(); - const expected = createArrayBuffer( - 0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, /* fixed64 end= */ 0x04, - 0x08, 0x01); - writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED32, 1); - const result = writer.getAndResetResultBuffer(); - expect(result).toEqual(arrayBufferSlice(expected, 1, 5)); - }); - - it('fail when encoding out of bound data', () => { - const writer = new Writer(); - const buffer = createArrayBuffer(0x4, 0x0, 0x1, 0x2, 0x3); - const subBuffer = arrayBufferSlice(buffer, 0, 2); - expect( - () => writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(subBuffer), 0, WireType.DELIMITED, 1)) - .toThrow(); - }); -}); - -describe('Writer.writeBytes does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encodes empty ByteString', () => { - writer.writeBytes(1, ByteString.EMPTY); - const buffer = writer.getAndResetResultBuffer(); - expect(buffer.byteLength).toBe(2); - }); - - it('encodes empty array', () => { - writer.writeBytes(1, ByteString.fromArrayBuffer(new ArrayBuffer(0))); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer( - 1 << 3 | 0x02, // tag (fieldnumber << 3 | (length delimited)) - 0, // length of the bytes - )); - }); - - it('encodes ByteString', () => { - const array = createArrayBuffer(1, 2, 3); - writer.writeBytes(1, ByteString.fromArrayBuffer(array)); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer( - 1 << 3 | 0x02, // tag (fieldnumber << 3 | (length delimited)) - 3, // length of the bytes - 1, - 2, - 3, - )); - }); -}); - -describe('Writer.writeDouble does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - for (const pair of getDoublePairs()) { - it(`encode ${pair.name}`, () => { - writer.writeDouble(1, pair.doubleValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - expect(buffer.length).toBe(9); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x09); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, 9)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - - /** - * NaN may have different value in different browsers. Thus, we need to make - * the test lenient. - */ - it('encode NaN', () => { - writer.writeDouble(1, NaN); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - expect(buffer.length).toBe(9); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x09); - // Encoded values are stored right after the tag - const float64 = new DataView(buffer.buffer); - expect(float64.getFloat64(1, true)).toBeNaN(); - }); -}); - -describe('Writer.writeFixed32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - for (const pair of getFixed32Pairs()) { - it(`encode ${pair.name}`, () => { - writer.writeFixed32(1, pair.intValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - expect(buffer.length).toBe(5); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0D); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array()); - }); - } -}); - -describe('Writer.writeFloat does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - for (const pair of getFloatPairs()) { - it(`encode ${pair.name}`, () => { - writer.writeFloat(1, pair.floatValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - expect(buffer.length).toBe(5); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0D); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - - /** - * NaN may have different value in different browsers. Thus, we need to make - * the test lenient. - */ - it('encode NaN', () => { - writer.writeFloat(1, NaN); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - expect(buffer.length).toBe(5); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0D); - // Encoded values are stored right after the tag - const float32 = new DataView(buffer.buffer); - expect(float32.getFloat32(1, true)).toBeNaN(); - }); -}); - -describe('Writer.writeInt32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - for (const pair of getInt32Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writeInt32(1, pair.intValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x08); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writeSfixed32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedSfixed32(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getSfixed32Pairs()) { - it(`encode ${pair.name}`, () => { - writer.writeSfixed32(1, pair.intValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - expect(buffer.length).toBe(5); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0D); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array()); - }); - } -}); - -describe('Writer.writeSfixed64 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - for (const pair of getSfixed64Pairs()) { - it(`encode ${pair.name}`, () => { - writer.writeSfixed64(1, pair.longValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - expect(buffer.length).toBe(9); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x09); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, 9)).toEqual(pair.bufferDecoder.asUint8Array()); - }); - } -}); - -describe('Writer.writeSint32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - for (const pair of getSint32Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writeSint32(1, pair.intValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x08); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writeSint64 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - for (const pair of getSint64Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writeSint64(1, pair.longValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x08); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writeInt64 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - for (const pair of getInt64Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writeInt64(1, pair.longValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x08); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writeUint32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - for (const pair of getUint32Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writeUint32(1, pair.intValue); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x08); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writeString does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty string', () => { - writer.writeString(1, ''); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer( - 1 << 3 | 0x02, // tag (fieldnumber << 3 | (length delimited)) - 0, // length of the string - )); - }); - - it('encode simple string', () => { - writer.writeString(1, 'hello'); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer( - 1 << 3 | 0x02, // tag (fieldnumber << 3 | (length delimited)) - 5, // length of the string - 'h'.charCodeAt(0), - 'e'.charCodeAt(0), - 'l'.charCodeAt(0), - 'l'.charCodeAt(0), - 'o'.charCodeAt(0), - )); - }); - - it('throw for invalid fieldnumber', () => { - if (CHECK_BOUNDS) { - expect(() => writer.writeString(-1, 'a')) - .toThrowError('Field number is out of range: -1'); - } else { - writer.writeString(-1, 'a'); - expect(new Uint8Array(writer.getAndResetResultBuffer())) - .toEqual(new Uint8Array(createArrayBuffer( - -6, // invalid tag - 0xff, - 0xff, - 0xff, - 0x0f, - 1, // string length - 'a'.charCodeAt(0), - ))); - } - }); - - it('throw for null string value', () => { - expect( - () => writer.writeString( - 1, /** @type {string} */ (/** @type {*} */ (null)))) - .toThrow(); - }); -}); - - -/****************************************************************************** - * REPEATED FUNCTIONS - ******************************************************************************/ - -describe('Writer.writePackedBool does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedBool(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedBoolPairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedBool(1, pair.boolValues); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writeRepeatedBool does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writeRepeatedBool(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - it('encode repeated unpacked boolean values', () => { - const writer = new Writer(); - writer.writeRepeatedBool(1, [true, false]); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer( - 1 << 3 | 0x00, // tag (fieldnumber << 3 | (varint)) - 0x01, // value[0] - 1 << 3 | 0x00, // tag (fieldnumber << 3 | (varint)) - 0x00, // value[1] - )); - }); -}); - -describe('Writer.writePackedDouble does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedDouble(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedDoublePairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedDouble(1, pair.doubleValues); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writePackedFixed32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedFixed32(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedFixed32Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedFixed32(1, pair.fixed32Values); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writePackedFloat does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedFloat(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedFloatPairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedFloat(1, pair.floatValues); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writePackedInt32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedInt32(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedInt32Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedInt32(1, pair.int32Values); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writePackedInt64 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedInt64(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedInt64Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedInt64(1, pair.int64Values); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writePackedSfixed32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedSfixed32(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedSfixed32Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedSfixed32(1, pair.sfixed32Values); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writePackedSfixed64 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedSfixed64(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedSfixed64Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedSfixed64(1, pair.sfixed64Values); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writePackedSint32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedSint32(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedSint32Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedSint32(1, pair.sint32Values); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writePackedSint64 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedSint64(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedSint64Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedSint64(1, pair.sint64Values); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writePackedUint32 does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writePackedUint32(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - for (const pair of getPackedUint32Pairs()) { - if (!pair.skip_writer) { - it(`encode ${pair.name}`, () => { - writer.writePackedUint32(1, pair.uint32Values); - const buffer = new Uint8Array(writer.getAndResetResultBuffer()); - // ensure we have a correct tag - expect(buffer[0]).toEqual(0x0A); - // Encoded values are stored right after the tag - expect(buffer.subarray(1, buffer.length)) - .toEqual(pair.bufferDecoder.asUint8Array()); - }); - } - } -}); - -describe('Writer.writeRepeatedBytes does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writeRepeatedBytes(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - it('encode single value', () => { - const value = createArrayBuffer(0x61); - writer.writeRepeatedBytes(1, [ByteString.fromArrayBuffer(value)]); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer( - 0x0A, - 0x01, - 0x61, // a - )); - }); - - it('encode multiple values', () => { - const value1 = createArrayBuffer(0x61); - const value2 = createArrayBuffer(0x62); - writer.writeRepeatedBytes(1, [ - ByteString.fromArrayBuffer(value1), - ByteString.fromArrayBuffer(value2), - ]); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer( - 0x0A, - 0x01, - 0x61, // a - 0x0A, - 0x01, - 0x62, // b - )); - }); -}); - -describe('Writer.writeRepeatedString does', () => { - let writer; - beforeEach(() => { - writer = new Writer(); - }); - - it('encode empty array', () => { - writer.writeRepeatedString(1, []); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer()); - }); - - it('encode single value', () => { - writer.writeRepeatedString(1, ['a']); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer( - 0x0A, - 0x01, - 0x61, // a - )); - }); - - it('encode multiple values', () => { - writer.writeRepeatedString(1, ['a', 'b']); - expect(writer.getAndResetResultBuffer()) - .toEqual(createArrayBuffer( - 0x0A, - 0x01, - 0x61, // a - 0x0A, - 0x01, - 0x62, // b - )); - }); -}); diff --git a/js/experimental/runtime/testing/binary/test_message.js b/js/experimental/runtime/testing/binary/test_message.js deleted file mode 100644 index cfd264b32..000000000 --- a/js/experimental/runtime/testing/binary/test_message.js +++ /dev/null @@ -1,1769 +0,0 @@ -/** - * @fileoverview Kernel wrapper message. - */ -goog.module('protobuf.testing.binary.TestMessage'); - -const ByteString = goog.require('protobuf.ByteString'); -const Int64 = goog.require('protobuf.Int64'); -const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const Kernel = goog.require('protobuf.runtime.Kernel'); - -/** - * A protobuf message implemented as a Kernel wrapper. - * @implements {InternalMessage} - */ -class TestMessage { - /** - * @return {!TestMessage} - */ - static createEmpty() { - return TestMessage.instanceCreator(Kernel.createEmpty()); - } - - /** - * @param {!Kernel} kernel - * @return {!TestMessage} - */ - static instanceCreator(kernel) { - return new TestMessage(kernel); - } - - /** - * @param {!Kernel} kernel - */ - constructor(kernel) { - /** @private @const {!Kernel} */ - this.kernel_ = kernel; - } - - /** - * @override - * @return {!Kernel} - */ - internalGetKernel() { - return this.kernel_; - } - - /** - * @return {!ArrayBuffer} - */ - serialize() { - return this.kernel_.serialize(); - } - - /** - * @param {number} fieldNumber - * @param {boolean=} defaultValue - * @return {boolean} - */ - getBoolWithDefault(fieldNumber, defaultValue = false) { - return this.kernel_.getBoolWithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {!ByteString=} defaultValue - * @return {!ByteString} - */ - getBytesWithDefault(fieldNumber, defaultValue = ByteString.EMPTY) { - return this.kernel_.getBytesWithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getDoubleWithDefault(fieldNumber, defaultValue = 0) { - return this.kernel_.getDoubleWithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getFixed32WithDefault(fieldNumber, defaultValue = 0) { - return this.kernel_.getFixed32WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getFixed64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - return this.kernel_.getFixed64WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getFloatWithDefault(fieldNumber, defaultValue = 0) { - return this.kernel_.getFloatWithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getInt32WithDefault(fieldNumber, defaultValue = 0) { - return this.kernel_.getInt32WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getInt64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - return this.kernel_.getInt64WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getSfixed32WithDefault(fieldNumber, defaultValue = 0) { - return this.kernel_.getSfixed32WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getSfixed64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - return this.kernel_.getSfixed64WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getSint32WithDefault(fieldNumber, defaultValue = 0) { - return this.kernel_.getSint32WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getSint64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - return this.kernel_.getSint64WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {string=} defaultValue - * @return {string} - */ - getStringWithDefault(fieldNumber, defaultValue = '') { - return this.kernel_.getStringWithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {number=} defaultValue - * @return {number} - */ - getUint32WithDefault(fieldNumber, defaultValue = 0) { - return this.kernel_.getUint32WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {!Int64=} defaultValue - * @return {!Int64} - */ - getUint64WithDefault(fieldNumber, defaultValue = Int64.getZero()) { - return this.kernel_.getUint64WithDefault(fieldNumber, defaultValue); - } - - /** - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @return {?T} - * @template T - */ - getMessageOrNull(fieldNumber, instanceCreator) { - return this.kernel_.getMessageOrNull(fieldNumber, instanceCreator); - } - - /** - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @return {T} - * @template T - */ - getMessageAttach(fieldNumber, instanceCreator) { - return this.kernel_.getMessageAttach(fieldNumber, instanceCreator); - } - - /** - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @return {T} - * @template T - */ - getMessage(fieldNumber, instanceCreator) { - return this.kernel_.getMessage(fieldNumber, instanceCreator); - } - - /** - * @param {number} fieldNumber - * @return {?Kernel} - * @template T - */ - getMessageAccessorOrNull(fieldNumber) { - return this.kernel_.getMessageAccessorOrNull(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {boolean} - */ - getRepeatedBoolElement(fieldNumber, index) { - return this.kernel_.getRepeatedBoolElement(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedBoolIterable(fieldNumber) { - return this.kernel_.getRepeatedBoolIterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedBoolSize(fieldNumber) { - return this.kernel_.getRepeatedBoolSize(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedDoubleElement(fieldNumber, index) { - return this.kernel_.getRepeatedDoubleElement(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedDoubleIterable(fieldNumber) { - return this.kernel_.getRepeatedDoubleIterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedDoubleSize(fieldNumber) { - return this.kernel_.getRepeatedDoubleSize(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedFixed32Element(fieldNumber, index) { - return this.kernel_.getRepeatedFixed32Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedFixed32Iterable(fieldNumber) { - return this.kernel_.getRepeatedFixed32Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedFixed32Size(fieldNumber) { - return this.kernel_.getRepeatedFixed32Size(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedFixed64Element(fieldNumber, index) { - return this.kernel_.getRepeatedFixed64Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedFixed64Iterable(fieldNumber) { - return this.kernel_.getRepeatedFixed64Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedFixed64Size(fieldNumber) { - return this.kernel_.getRepeatedFixed64Size(fieldNumber); - } - /** - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedFloatElement(fieldNumber, index) { - return this.kernel_.getRepeatedFloatElement(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedFloatIterable(fieldNumber) { - return this.kernel_.getRepeatedFloatIterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedFloatSize(fieldNumber) { - return this.kernel_.getRepeatedFloatSize(fieldNumber); - } - /** - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedInt32Element(fieldNumber, index) { - return this.kernel_.getRepeatedInt32Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedInt32Iterable(fieldNumber) { - return this.kernel_.getRepeatedInt32Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedInt32Size(fieldNumber) { - return this.kernel_.getRepeatedInt32Size(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedInt64Element(fieldNumber, index) { - return this.kernel_.getRepeatedInt64Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedInt64Iterable(fieldNumber) { - return this.kernel_.getRepeatedInt64Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedInt64Size(fieldNumber) { - return this.kernel_.getRepeatedInt64Size(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedSfixed32Element(fieldNumber, index) { - return this.kernel_.getRepeatedSfixed32Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedSfixed32Iterable(fieldNumber) { - return this.kernel_.getRepeatedSfixed32Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedSfixed32Size(fieldNumber) { - return this.kernel_.getRepeatedSfixed32Size(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedSfixed64Element(fieldNumber, index) { - return this.kernel_.getRepeatedSfixed64Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedSfixed64Iterable(fieldNumber) { - return this.kernel_.getRepeatedSfixed64Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedSfixed64Size(fieldNumber) { - return this.kernel_.getRepeatedSfixed64Size(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedSint32Element(fieldNumber, index) { - return this.kernel_.getRepeatedSint32Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedSint32Iterable(fieldNumber) { - return this.kernel_.getRepeatedSint32Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedSint32Size(fieldNumber) { - return this.kernel_.getRepeatedSint32Size(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedSint64Element(fieldNumber, index) { - return this.kernel_.getRepeatedSint64Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedSint64Iterable(fieldNumber) { - return this.kernel_.getRepeatedSint64Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedSint64Size(fieldNumber) { - return this.kernel_.getRepeatedSint64Size(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {number} - */ - getRepeatedUint32Element(fieldNumber, index) { - return this.kernel_.getRepeatedUint32Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedUint32Iterable(fieldNumber) { - return this.kernel_.getRepeatedUint32Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedUint32Size(fieldNumber) { - return this.kernel_.getRepeatedUint32Size(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {!Int64} - */ - getRepeatedUint64Element(fieldNumber, index) { - return this.kernel_.getRepeatedUint64Element(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedUint64Iterable(fieldNumber) { - return this.kernel_.getRepeatedUint64Iterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedUint64Size(fieldNumber) { - return this.kernel_.getRepeatedUint64Size(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {!ByteString} - */ - getRepeatedBytesElement(fieldNumber, index) { - return this.kernel_.getRepeatedBytesElement(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedBytesIterable(fieldNumber) { - return this.kernel_.getRepeatedBytesIterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedBytesSize(fieldNumber) { - return this.kernel_.getRepeatedBytesSize(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @return {string} - */ - getRepeatedStringElement(fieldNumber, index) { - return this.kernel_.getRepeatedStringElement(fieldNumber, index); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - */ - getRepeatedStringIterable(fieldNumber) { - return this.kernel_.getRepeatedStringIterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @return {number} - */ - getRepeatedStringSize(fieldNumber) { - return this.kernel_.getRepeatedStringSize(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @param {number} index - * @return {T} - * @template T - */ - getRepeatedMessageElement(fieldNumber, instanceCreator, index) { - return this.kernel_.getRepeatedMessageElement( - fieldNumber, instanceCreator, index); - } - - /** - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @return {!Iterable} - * @template T - */ - getRepeatedMessageIterable(fieldNumber, instanceCreator) { - return this.kernel_.getRepeatedMessageIterable( - fieldNumber, instanceCreator); - } - - /** - * @param {number} fieldNumber - * @return {!Iterable} - * @template T - */ - getRepeatedMessageAccessorIterable(fieldNumber) { - return this.kernel_.getRepeatedMessageAccessorIterable(fieldNumber); - } - - /** - * @param {number} fieldNumber - * @param {function(!Kernel):T} instanceCreator - * @return {number} - * @template T - */ - getRepeatedMessageSize(fieldNumber, instanceCreator) { - return this.kernel_.getRepeatedMessageSize(fieldNumber, instanceCreator); - } - - /** - * @param {number} fieldNumber - * @param {boolean} value - */ - setBool(fieldNumber, value) { - this.kernel_.setBool(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!ByteString} value - */ - setBytes(fieldNumber, value) { - this.kernel_.setBytes(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - setDouble(fieldNumber, value) { - this.kernel_.setDouble(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - setFixed32(fieldNumber, value) { - this.kernel_.setFixed32(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - setFixed64(fieldNumber, value) { - this.kernel_.setFixed64(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - setFloat(fieldNumber, value) { - this.kernel_.setFloat(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - setInt32(fieldNumber, value) { - this.kernel_.setInt32(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - setInt64(fieldNumber, value) { - this.kernel_.setInt64(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - setSfixed32(fieldNumber, value) { - this.kernel_.setSfixed32(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - setSfixed64(fieldNumber, value) { - this.kernel_.setSfixed64(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - setSint32(fieldNumber, value) { - this.kernel_.setSint32(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - setSint64(fieldNumber, value) { - this.kernel_.setSint64(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {string} value - */ - setString(fieldNumber, value) { - this.kernel_.setString(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - setUint32(fieldNumber, value) { - this.kernel_.setUint32(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - setUint64(fieldNumber, value) { - this.kernel_.setUint64(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {T} value - * @template T - */ - setMessage(fieldNumber, value) { - this.kernel_.setMessage(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {boolean} value - */ - addPackedBoolElement(fieldNumber, value) { - this.kernel_.addPackedBoolElement(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedBoolIterable(fieldNumber, values) { - this.kernel_.addPackedBoolIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {boolean} value - */ - addUnpackedBoolElement(fieldNumber, value) { - this.kernel_.addUnpackedBoolElement(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedBoolIterable(fieldNumber, values) { - this.kernel_.addUnpackedBoolIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {boolean} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedBoolElement(fieldNumber, index, value) { - this.kernel_.setPackedBoolElement(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedBoolIterable(fieldNumber, values) { - this.kernel_.setPackedBoolIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {boolean} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedBoolElement(fieldNumber, index, value) { - this.kernel_.setUnpackedBoolElement(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedBoolIterable(fieldNumber, values) { - this.kernel_.setUnpackedBoolIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addPackedDoubleElement(fieldNumber, value) { - this.kernel_.addPackedDoubleElement(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedDoubleIterable(fieldNumber, values) { - this.kernel_.addPackedDoubleIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedDoubleElement(fieldNumber, value) { - this.kernel_.addUnpackedDoubleElement(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedDoubleIterable(fieldNumber, values) { - this.kernel_.addUnpackedDoubleIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedDoubleElement(fieldNumber, index, value) { - this.kernel_.setPackedDoubleElement(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedDoubleIterable(fieldNumber, values) { - this.kernel_.setPackedDoubleIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedDoubleElement(fieldNumber, index, value) { - this.kernel_.setUnpackedDoubleElement(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedDoubleIterable(fieldNumber, values) { - this.kernel_.setUnpackedDoubleIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addPackedFixed32Element(fieldNumber, value) { - this.kernel_.addPackedFixed32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedFixed32Iterable(fieldNumber, values) { - this.kernel_.addPackedFixed32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedFixed32Element(fieldNumber, value) { - this.kernel_.addUnpackedFixed32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedFixed32Iterable(fieldNumber, values) { - this.kernel_.addUnpackedFixed32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedFixed32Element(fieldNumber, index, value) { - this.kernel_.setPackedFixed32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedFixed32Iterable(fieldNumber, values) { - this.kernel_.setPackedFixed32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedFixed32Element(fieldNumber, index, value) { - this.kernel_.setUnpackedFixed32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedFixed32Iterable(fieldNumber, values) { - this.kernel_.setUnpackedFixed32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedFixed64Element(fieldNumber, value) { - this.kernel_.addPackedFixed64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedFixed64Iterable(fieldNumber, values) { - this.kernel_.addPackedFixed64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedFixed64Element(fieldNumber, value) { - this.kernel_.addUnpackedFixed64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedFixed64Iterable(fieldNumber, values) { - this.kernel_.addUnpackedFixed64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedFixed64Element(fieldNumber, index, value) { - this.kernel_.setPackedFixed64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedFixed64Iterable(fieldNumber, values) { - this.kernel_.setPackedFixed64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedFixed64Element(fieldNumber, index, value) { - this.kernel_.setUnpackedFixed64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedFixed64Iterable(fieldNumber, values) { - this.kernel_.setUnpackedFixed64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addPackedFloatElement(fieldNumber, value) { - this.kernel_.addPackedFloatElement(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedFloatIterable(fieldNumber, values) { - this.kernel_.addPackedFloatIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedFloatElement(fieldNumber, value) { - this.kernel_.addUnpackedFloatElement(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedFloatIterable(fieldNumber, values) { - this.kernel_.addUnpackedFloatIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedFloatElement(fieldNumber, index, value) { - this.kernel_.setPackedFloatElement(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedFloatIterable(fieldNumber, values) { - this.kernel_.setPackedFloatIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedFloatElement(fieldNumber, index, value) { - this.kernel_.setUnpackedFloatElement(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedFloatIterable(fieldNumber, values) { - this.kernel_.setUnpackedFloatIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addPackedInt32Element(fieldNumber, value) { - this.kernel_.addPackedInt32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedInt32Iterable(fieldNumber, values) { - this.kernel_.addPackedInt32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedInt32Element(fieldNumber, value) { - this.kernel_.addUnpackedInt32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedInt32Iterable(fieldNumber, values) { - this.kernel_.addUnpackedInt32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedInt32Element(fieldNumber, index, value) { - this.kernel_.setPackedInt32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedInt32Iterable(fieldNumber, values) { - this.kernel_.setPackedInt32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedInt32Element(fieldNumber, index, value) { - this.kernel_.setUnpackedInt32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedInt32Iterable(fieldNumber, values) { - this.kernel_.setUnpackedInt32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedInt64Element(fieldNumber, value) { - this.kernel_.addPackedInt64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedInt64Iterable(fieldNumber, values) { - this.kernel_.addPackedInt64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedInt64Element(fieldNumber, value) { - this.kernel_.addUnpackedInt64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedInt64Iterable(fieldNumber, values) { - this.kernel_.addUnpackedInt64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedInt64Element(fieldNumber, index, value) { - this.kernel_.setPackedInt64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedInt64Iterable(fieldNumber, values) { - this.kernel_.setPackedInt64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedInt64Element(fieldNumber, index, value) { - this.kernel_.setUnpackedInt64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedInt64Iterable(fieldNumber, values) { - this.kernel_.setUnpackedInt64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addPackedSfixed32Element(fieldNumber, value) { - this.kernel_.addPackedSfixed32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedSfixed32Iterable(fieldNumber, values) { - this.kernel_.addPackedSfixed32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedSfixed32Element(fieldNumber, value) { - this.kernel_.addUnpackedSfixed32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedSfixed32Iterable(fieldNumber, values) { - this.kernel_.addUnpackedSfixed32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedSfixed32Element(fieldNumber, index, value) { - this.kernel_.setPackedSfixed32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedSfixed32Iterable(fieldNumber, values) { - this.kernel_.setPackedSfixed32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedSfixed32Element(fieldNumber, index, value) { - this.kernel_.setUnpackedSfixed32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedSfixed32Iterable(fieldNumber, values) { - this.kernel_.setUnpackedSfixed32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedSfixed64Element(fieldNumber, value) { - this.kernel_.addPackedSfixed64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedSfixed64Iterable(fieldNumber, values) { - this.kernel_.addPackedSfixed64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedSfixed64Element(fieldNumber, value) { - this.kernel_.addUnpackedSfixed64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedSfixed64Iterable(fieldNumber, values) { - this.kernel_.addUnpackedSfixed64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedSfixed64Element(fieldNumber, index, value) { - this.kernel_.setPackedSfixed64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedSfixed64Iterable(fieldNumber, values) { - this.kernel_.setPackedSfixed64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedSfixed64Element(fieldNumber, index, value) { - this.kernel_.setUnpackedSfixed64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedSfixed64Iterable(fieldNumber, values) { - this.kernel_.setUnpackedSfixed64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addPackedSint32Element(fieldNumber, value) { - this.kernel_.addPackedSint32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedSint32Iterable(fieldNumber, values) { - this.kernel_.addPackedSint32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedSint32Element(fieldNumber, value) { - this.kernel_.addUnpackedSint32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedSint32Iterable(fieldNumber, values) { - this.kernel_.addUnpackedSint32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedSint32Element(fieldNumber, index, value) { - this.kernel_.setPackedSint32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedSint32Iterable(fieldNumber, values) { - this.kernel_.setPackedSint32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedSint32Element(fieldNumber, index, value) { - this.kernel_.setUnpackedSint32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedSint32Iterable(fieldNumber, values) { - this.kernel_.setUnpackedSint32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedSint64Element(fieldNumber, value) { - this.kernel_.addPackedSint64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedSint64Iterable(fieldNumber, values) { - this.kernel_.addPackedSint64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedSint64Element(fieldNumber, value) { - this.kernel_.addUnpackedSint64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedSint64Iterable(fieldNumber, values) { - this.kernel_.addUnpackedSint64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedSint64Element(fieldNumber, index, value) { - this.kernel_.setPackedSint64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedSint64Iterable(fieldNumber, values) { - this.kernel_.setPackedSint64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedSint64Element(fieldNumber, index, value) { - this.kernel_.setUnpackedSint64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedSint64Iterable(fieldNumber, values) { - this.kernel_.setUnpackedSint64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addPackedUint32Element(fieldNumber, value) { - this.kernel_.addPackedUint32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedUint32Iterable(fieldNumber, values) { - this.kernel_.addPackedUint32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} value - */ - addUnpackedUint32Element(fieldNumber, value) { - this.kernel_.addUnpackedUint32Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedUint32Iterable(fieldNumber, values) { - this.kernel_.addUnpackedUint32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedUint32Element(fieldNumber, index, value) { - this.kernel_.setPackedUint32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedUint32Iterable(fieldNumber, values) { - this.kernel_.setPackedUint32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {number} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedUint32Element(fieldNumber, index, value) { - this.kernel_.setUnpackedUint32Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedUint32Iterable(fieldNumber, values) { - this.kernel_.setUnpackedUint32Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addPackedUint64Element(fieldNumber, value) { - this.kernel_.addPackedUint64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addPackedUint64Iterable(fieldNumber, values) { - this.kernel_.addPackedUint64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Int64} value - */ - addUnpackedUint64Element(fieldNumber, value) { - this.kernel_.addUnpackedUint64Element(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addUnpackedUint64Iterable(fieldNumber, values) { - this.kernel_.addUnpackedUint64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setPackedUint64Element(fieldNumber, index, value) { - this.kernel_.setPackedUint64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setPackedUint64Iterable(fieldNumber, values) { - this.kernel_.setPackedUint64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!Int64} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setUnpackedUint64Element(fieldNumber, index, value) { - this.kernel_.setUnpackedUint64Element(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setUnpackedUint64Iterable(fieldNumber, values) { - this.kernel_.setUnpackedUint64Iterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setRepeatedBytesIterable(fieldNumber, values) { - this.kernel_.setRepeatedBytesIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addRepeatedBytesIterable(fieldNumber, values) { - this.kernel_.addRepeatedBytesIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {!ByteString} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setRepeatedBytesElement(fieldNumber, index, value) { - this.kernel_.setRepeatedBytesElement(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {!ByteString} value - */ - addRepeatedBytesElement(fieldNumber, value) { - this.kernel_.addRepeatedBytesElement(fieldNumber, value); - } - - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - setRepeatedStringIterable(fieldNumber, values) { - this.kernel_.setRepeatedStringIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - */ - addRepeatedStringIterable(fieldNumber, values) { - this.kernel_.addRepeatedStringIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {number} index - * @param {string} value - * @throws {!Error} if index is out of range when check mode is critical - */ - setRepeatedStringElement(fieldNumber, index, value) { - this.kernel_.setRepeatedStringElement(fieldNumber, index, value); - } - - /** - * @param {number} fieldNumber - * @param {string} value - */ - addRepeatedStringElement(fieldNumber, value) { - this.kernel_.addRepeatedStringElement(fieldNumber, value); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - * @template T - */ - setRepeatedMessageIterable(fieldNumber, values) { - this.kernel_.setRepeatedMessageIterable(fieldNumber, values); - } - - /** - * @param {number} fieldNumber - * @param {!Iterable} values - * @param {function(!Kernel):T} instanceCreator - * @template T - */ - addRepeatedMessageIterable(fieldNumber, values, instanceCreator) { - this.kernel_.addRepeatedMessageIterable( - fieldNumber, values, instanceCreator); - } - - /** - * @param {number} fieldNumber - * @param {T} value - * @param {function(!Kernel):T} instanceCreator - * @param {number} index - * @throws {!Error} if index is out of range when check mode is critical - * @template T - */ - setRepeatedMessageElement(fieldNumber, value, instanceCreator, index) { - this.kernel_.setRepeatedMessageElement( - fieldNumber, value, instanceCreator, index); - } - - /** - * @param {number} fieldNumber - * @param {T} value - * @param {function(!Kernel):T} instanceCreator - * @template T - */ - addRepeatedMessageElement(fieldNumber, value, instanceCreator) { - this.kernel_.addRepeatedMessageElement(fieldNumber, value, instanceCreator); - } -} - -exports = TestMessage; diff --git a/js/experimental/runtime/testing/ensure_custom_equality_test.js b/js/experimental/runtime/testing/ensure_custom_equality_test.js deleted file mode 100644 index 9323ffd52..000000000 --- a/js/experimental/runtime/testing/ensure_custom_equality_test.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @fileoverview Tests in this file will fail if our custom equality have not - * been installed. - * see b/131864652 - */ - -goog.module('protobuf.testing.ensureCustomEqualityTest'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const ByteString = goog.require('protobuf.ByteString'); - -describe('Custom equality', () => { - it('ensure that custom equality for ArrayBuffer is installed', () => { - const buffer1 = new ArrayBuffer(4); - const buffer2 = new ArrayBuffer(4); - const array = new Uint8Array(buffer1); - array[0] = 1; - expect(buffer1).not.toEqual(buffer2); - }); - - it('ensure that custom equality for ByteString is installed', () => { - const HALLO_IN_BASE64 = 'aGFsbG8='; - const BYTES_WITH_HALLO = new Uint8Array([ - 'h'.charCodeAt(0), - 'a'.charCodeAt(0), - 'l'.charCodeAt(0), - 'l'.charCodeAt(0), - 'o'.charCodeAt(0), - ]); - - const byteString1 = ByteString.fromBase64String(HALLO_IN_BASE64); - const byteString2 = ByteString.fromArrayBufferView(BYTES_WITH_HALLO); - expect(byteString1).toEqual(byteString2); - }); - - it('ensure that custom equality for BufferDecoder is installed', () => { - const arrayBuffer1 = new Uint8Array([0, 1, 2]).buffer; - const arrayBuffer2 = new Uint8Array([0, 1, 2]).buffer; - - const bufferDecoder1 = BufferDecoder.fromArrayBuffer(arrayBuffer1); - const bufferDecoder2 = BufferDecoder.fromArrayBuffer(arrayBuffer2); - expect(bufferDecoder1).toEqual(bufferDecoder2); - }); -}); diff --git a/js/experimental/runtime/testing/jasmine_protobuf.js b/js/experimental/runtime/testing/jasmine_protobuf.js deleted file mode 100644 index d6bc0ffd3..000000000 --- a/js/experimental/runtime/testing/jasmine_protobuf.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @fileoverview Installs our custom equality matchers in Jasmine. - */ -goog.module('protobuf.testing.jasmineProtoBuf'); - -const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const ByteString = goog.require('protobuf.ByteString'); -const {arrayBufferEqual} = goog.require('protobuf.binary.typedArrays'); - -/** - * A function that ensures custom equality for ByteStrings. - * Since Jasmine compare structure by default Bytestrings might be equal that - * are not equal since ArrayBuffers still compare content in g3. - * (Jasmine fix upstream: https://github.com/jasmine/jasmine/issues/1687) - * Also ByteStrings that are equal might compare non equal in jasmine of the - * base64 string has been initialized. - * @param {*} first - * @param {*} second - * @return {boolean|undefined} - */ -const byteStringEquality = (first, second) => { - if (second instanceof ByteString) { - return second.equals(first); - } - - // Intentionally not returning anything, this signals to jasmine that we - // did not perform any equality on the given objects. -}; - -/** - * A function that ensures custom equality for ArrayBuffers. - * By default Jasmine does not compare the content of an ArrayBuffer and thus - * will return true for buffers with the same length but different content. - * @param {*} first - * @param {*} second - * @return {boolean|undefined} - */ -const arrayBufferCustomEquality = (first, second) => { - if (first instanceof ArrayBuffer && second instanceof ArrayBuffer) { - return arrayBufferEqual(first, second); - } - // Intentionally not returning anything, this signals to jasmine that we - // did not perform any equality on the given objects. -}; - -/** - * A function that ensures custom equality for ArrayBuffers. - * By default Jasmine does not compare the content of an ArrayBuffer and thus - * will return true for buffers with the same length but different content. - * @param {*} first - * @param {*} second - * @return {boolean|undefined} - */ -const bufferDecoderCustomEquality = (first, second) => { - if (first instanceof BufferDecoder && second instanceof BufferDecoder) { - return first.asByteString().equals(second.asByteString()); - } - // Intentionally not returning anything, this signals to jasmine that we - // did not perform any equality on the given objects. -}; - -/** - * Overrides the default ArrayBuffer toString method ([object ArrayBuffer]) with - * a more readable representation. - */ -function overrideArrayBufferToString() { - /** - * Returns the hex values of the underlying bytes of the ArrayBuffer. - * - * @override - * @return {string} - */ - ArrayBuffer.prototype.toString = function() { - const arr = Array.from(new Uint8Array(this)); - return 'ArrayBuffer[' + - arr.map((b) => '0x' + (b & 0xFF).toString(16).toUpperCase()) - .join(', ') + - ']'; - }; -} - -beforeEach(() => { - jasmine.addCustomEqualityTester(arrayBufferCustomEquality); - jasmine.addCustomEqualityTester(bufferDecoderCustomEquality); - jasmine.addCustomEqualityTester(byteStringEquality); - - overrideArrayBufferToString(); -}); diff --git a/js/gulpfile.js b/js/gulpfile.js deleted file mode 100644 index 00a6d64f9..000000000 --- a/js/gulpfile.js +++ /dev/null @@ -1,273 +0,0 @@ -var gulp = require('gulp'); -var execFile = require('child_process').execFile; -var glob = require('glob'); - -function exec(command, cb) { - execFile('sh', ['-c', command], cb); -} - -var protoc = process.env.PROTOC || '../src/protoc'; - -var wellKnownTypes = [ - '../src/google/protobuf/any.proto', - '../src/google/protobuf/api.proto', - '../src/google/protobuf/compiler/plugin.proto', - '../src/google/protobuf/descriptor.proto', - '../src/google/protobuf/duration.proto', - '../src/google/protobuf/empty.proto', - '../src/google/protobuf/field_mask.proto', - '../src/google/protobuf/source_context.proto', - '../src/google/protobuf/struct.proto', - '../src/google/protobuf/timestamp.proto', - '../src/google/protobuf/type.proto', - '../src/google/protobuf/wrappers.proto', -]; - -var group1Protos = [ - 'data.proto', - 'test3.proto', - 'test5.proto', - 'commonjs/test6/test6.proto', - 'test8.proto', - 'test11.proto', - 'test12.proto', - 'test13.proto', - 'test14.proto', - 'test15.proto', - 'testbinary.proto', - 'testempty.proto', - 'test.proto', - 'testlargenumbers.proto', -]; - -var group2Protos = [ - 'proto3_test.proto', - 'test2.proto', - 'test4.proto', - 'commonjs/test7/test7.proto', -]; - -var group3Protos = [ - 'test9.proto', - 'test10.proto' -]; - - -gulp.task('genproto_well_known_types_closure', function (cb) { - exec(protoc + ' --js_out=one_output_file_per_input_file,binary:. -I ../src -I . ' + wellKnownTypes.join(' '), - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - -gulp.task('genproto_group1_closure', function (cb) { - exec(protoc + ' --js_out=library=testproto_libs1,binary:. -I ../src -I . ' + group1Protos.join(' '), - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - -gulp.task('genproto_group2_closure', function(cb) { - exec( - protoc + - ' --experimental_allow_proto3_optional --js_out=library=testproto_libs2,binary:. -I ../src -I . -I commonjs ' + - group2Protos.join(' '), - function(err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - -gulp.task('genproto_well_known_types_commonjs', function (cb) { - exec('mkdir -p commonjs_out && ' + protoc + ' --js_out=import_style=commonjs,binary:commonjs_out -I ../src ' + wellKnownTypes.join(' '), - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - -gulp.task('genproto_group1_commonjs', function (cb) { - exec('mkdir -p commonjs_out && ' + protoc + ' --js_out=import_style=commonjs,binary:commonjs_out -I ../src -I commonjs -I . ' + group1Protos.join(' '), - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - -gulp.task('genproto_group2_commonjs', function(cb) { - exec( - 'mkdir -p commonjs_out && ' + protoc + - ' --experimental_allow_proto3_optional --js_out=import_style=commonjs,binary:commonjs_out -I ../src -I commonjs -I . ' + - group2Protos.join(' '), - function(err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - -gulp.task('genproto_commonjs_wellknowntypes', function (cb) { - exec('mkdir -p commonjs_out/node_modules/google-protobuf && ' + protoc + ' --js_out=import_style=commonjs,binary:commonjs_out/node_modules/google-protobuf -I ../src ' + wellKnownTypes.join(' '), - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - -gulp.task('genproto_wellknowntypes', function (cb) { - exec(protoc + ' --js_out=import_style=commonjs,binary:. -I ../src ' + wellKnownTypes.join(' '), - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); -gulp.task('genproto_group3_commonjs_strict', function (cb) { - exec('mkdir -p commonjs_out && ' + protoc + ' --js_out=import_style=commonjs_strict,binary:commonjs_out -I ../src -I commonjs -I . ' + group3Protos.join(' '), - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - - -function getClosureCompilerCommand(exportsFile, outputFile) { - const closureLib = 'node_modules/google-closure-library'; - return [ - 'node_modules/.bin/google-closure-compiler', - `--js=${closureLib}/closure/goog/**.js`, - `--js=${closureLib}/third_party/closure/goog/**.js`, '--js=map.js', - '--js=message.js', '--js=binary/arith.js', '--js=binary/constants.js', - '--js=binary/decoder.js', '--js=binary/encoder.js', '--js=binary/reader.js', - '--js=binary/utils.js', '--js=binary/writer.js', `--js=${exportsFile}`, - `--entry_point=${exportsFile}`, `> ${outputFile}` - ].join(' '); -} - -gulp.task('dist', gulp.series(['genproto_wellknowntypes'], function(cb) { - // TODO(haberman): minify this more aggressively. - // Will require proper externs/exports. - exec( - getClosureCompilerCommand('commonjs/export.js', 'google-protobuf.js'), - function(err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -})); - -gulp.task('commonjs_asserts', function(cb) { - exec( - 'mkdir -p commonjs_out/test_node_modules && ' + - getClosureCompilerCommand( - 'commonjs/export_asserts.js', - 'commonjs_out/test_node_modules/closure_asserts_commonjs.js'), - function(err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - -gulp.task('commonjs_testdeps', function(cb) { - exec( - 'mkdir -p commonjs_out/test_node_modules && ' + - getClosureCompilerCommand( - 'commonjs/export_testdeps.js', - 'commonjs_out/test_node_modules/testdeps_commonjs.js'), - function(err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -}); - -gulp.task( - 'make_commonjs_out', - gulp.series( - [ - 'dist', 'genproto_well_known_types_commonjs', - 'genproto_group1_commonjs', 'genproto_group2_commonjs', - 'genproto_commonjs_wellknowntypes', 'commonjs_asserts', - 'commonjs_testdeps', 'genproto_group3_commonjs_strict' - ], - function(cb) { - // TODO(haberman): minify this more aggressively. - // Will require proper externs/exports. - var cmd = - 'mkdir -p commonjs_out/binary && mkdir -p commonjs_out/test_node_modules && '; - function addTestFile(file) { - cmd += 'node commonjs/rewrite_tests_for_commonjs.js < ' + file + - ' > commonjs_out/' + file + '&& '; - } - - glob.sync('*_test.js').forEach(addTestFile); - glob.sync('binary/*_test.js').forEach(addTestFile); - - exec( - cmd + 'cp commonjs/jasmine.json commonjs_out/jasmine.json && ' + - 'cp google-protobuf.js commonjs_out/test_node_modules && ' + - 'cp commonjs/strict_test.js commonjs_out/strict_test.js &&' + - 'cp commonjs/import_test.js commonjs_out/import_test.js', - function(err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); - })); - -gulp.task( - 'deps', - gulp.series( - [ - 'genproto_well_known_types_closure', 'genproto_group1_closure', - 'genproto_group2_closure' - ], - function(cb) { - exec( - './node_modules/.bin/closure-make-deps --closure-path=. --file=node_modules/google-closure-library/closure/goog/deps.js binary/arith.js binary/constants.js binary/decoder.js binary/encoder.js binary/reader.js binary/utils.js binary/writer.js debug.js map.js message.js node_loader.js test_bootstrap.js > deps.js', - function(err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); - })); - -gulp.task( - 'test_closure', - gulp.series( - [ - 'genproto_well_known_types_closure', 'genproto_group1_closure', - 'genproto_group2_closure', 'deps' - ], - function(cb) { - exec( - 'JASMINE_CONFIG_PATH=jasmine.json ./node_modules/.bin/jasmine', - function(err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); - })); - -gulp.task('test_commonjs', gulp.series(['make_commonjs_out'], function(cb) { - exec('cd commonjs_out && JASMINE_CONFIG_PATH=jasmine.json NODE_PATH=test_node_modules ../node_modules/.bin/jasmine', - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); -})); - -gulp.task('test', gulp.series(['test_closure', 'test_commonjs'], function(cb) { - cb(); -})); diff --git a/js/jasmine.json b/js/jasmine.json deleted file mode 100644 index aeea72f85..000000000 --- a/js/jasmine.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "spec_dir": "", - "spec_files": [ - "*_test.js", - "binary/*_test.js" - ], - "helpers": [ - "node_modules/google-closure-library/closure/goog/bootstrap/nodejs.js", - "node_loader.js", - "deps.js", - "google/protobuf/any.js", - "google/protobuf/struct.js", - "google/protobuf/timestamp.js", - "testproto_libs1.js", - "testproto_libs2.js" - ] -} diff --git a/js/map.js b/js/map.js deleted file mode 100644 index 61f0f3b63..000000000 --- a/js/map.js +++ /dev/null @@ -1,557 +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. - -/** - * @fileoverview - * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed - */ -goog.provide('jspb.Map'); - -goog.require('goog.asserts'); - -goog.requireType('jspb.BinaryReader'); -goog.requireType('jspb.BinaryWriter'); - - - -/** - * Constructs a new Map. A Map is a container that is used to implement map - * fields on message objects. It closely follows the ES6 Map API; however, - * it is distinct because we do not want to depend on external polyfills or - * on ES6 itself. - * - * This constructor should only be called from generated message code. It is not - * intended for general use by library consumers. - * - * @template K, V - * - * @param {!Array>} arr - * - * @param {?function(new:V, ?=)=} opt_valueCtor - * The constructor for type V, if type V is a message type. - * - * @constructor - * @struct - */ -jspb.Map = function(arr, opt_valueCtor) { - /** @const @private */ - this.arr_ = arr; - /** @const @private */ - this.valueCtor_ = opt_valueCtor; - - /** @type {!Object>} @private */ - this.map_ = {}; - - /** - * Is `this.arr_ updated with respect to `this.map_`? - * @type {boolean} - */ - this.arrClean = true; - - if (this.arr_.length > 0) { - this.loadFromArray_(); - } -}; - - -/** - * Load initial content from underlying array. - * @private - */ -jspb.Map.prototype.loadFromArray_ = function() { - for (var i = 0; i < this.arr_.length; i++) { - var record = this.arr_[i]; - var key = record[0]; - var value = record[1]; - this.map_[key.toString()] = new jspb.Map.Entry_(key, value); - } - this.arrClean = true; -}; - - -/** - * Synchronize content to underlying array, if needed, and return it. - * @return {!Array>} - */ -jspb.Map.prototype.toArray = function() { - if (this.arrClean) { - if (this.valueCtor_) { - // We need to recursively sync maps in submessages to their arrays. - var m = this.map_; - for (var p in m) { - if (Object.prototype.hasOwnProperty.call(m, p)) { - var valueWrapper = /** @type {?jspb.Message} */ (m[p].valueWrapper); - if (valueWrapper) { - valueWrapper.toArray(); - } - } - } - } - } else { - // Delete all elements. - this.arr_.length = 0; - var strKeys = this.stringKeys_(); - // Output keys in deterministic (sorted) order. - strKeys.sort(); - for (var i = 0; i < strKeys.length; i++) { - var entry = this.map_[strKeys[i]]; - var valueWrapper = /** @type {?jspb.Message} */ (entry.valueWrapper); - if (valueWrapper) { - valueWrapper.toArray(); - } - this.arr_.push([entry.key, entry.value]); - } - this.arrClean = true; - } - return this.arr_; -}; - - -/** - * Returns the map formatted as an array of key-value pairs, suitable for the - * toObject() form of a message. - * - * @param {boolean=} includeInstance Whether to include the JSPB instance for - * transitional soy proto support: http://goto/soy-param-migration - * @param {function((boolean|undefined),V):!Object=} valueToObject - * The static toObject() method, if V is a message type. - * @return {!Array>} - */ -jspb.Map.prototype.toObject = function(includeInstance, valueToObject) { - var rawArray = this.toArray(); - var entries = []; - for (var i = 0; i < rawArray.length; i++) { - var entry = this.map_[rawArray[i][0].toString()]; - this.wrapEntry_(entry); - var valueWrapper = /** @type {V|undefined} */ (entry.valueWrapper); - if (valueWrapper) { - goog.asserts.assert(valueToObject); - entries.push([entry.key, valueToObject(includeInstance, valueWrapper)]); - } else { - entries.push([entry.key, entry.value]); - } - } - return entries; -}; - - -/** - * Returns a Map from the given array of key-value pairs when the values are of - * message type. The values in the array must match the format returned by their - * message type's toObject() method. - * - * @template K, V - * @param {!Array>} entries - * @param {function(new:V,?=)} valueCtor - * The constructor for type V. - * @param {function(!Object):V} valueFromObject - * The fromObject function for type V. - * @return {!jspb.Map} - */ -jspb.Map.fromObject = function(entries, valueCtor, valueFromObject) { - var result = new jspb.Map([], valueCtor); - for (var i = 0; i < entries.length; i++) { - var key = entries[i][0]; - var value = valueFromObject(entries[i][1]); - result.set(key, value); - } - return result; -}; - - -/** - * Helper: an IteratorIterable over an array. - * @template T - * @param {!Array} arr the array - * @implements {IteratorIterable} - * @constructor @struct - * @private - */ -jspb.Map.ArrayIteratorIterable_ = function(arr) { - /** @type {number} @private */ - this.idx_ = 0; - - /** @const @private */ - this.arr_ = arr; -}; - - -/** @override @final */ -jspb.Map.ArrayIteratorIterable_.prototype.next = function() { - if (this.idx_ < this.arr_.length) { - return {done: false, value: this.arr_[this.idx_++]}; - } else { - return {done: true, value: undefined}; - } -}; - -if (typeof(Symbol) != 'undefined') { - /** @override */ - jspb.Map.ArrayIteratorIterable_.prototype[Symbol.iterator] = function() { - return this; - }; -} - - -/** - * Returns the map's length (number of key/value pairs). - * @return {number} - */ -jspb.Map.prototype.getLength = function() { - return this.stringKeys_().length; -}; - - -/** - * Clears the map. - */ -jspb.Map.prototype.clear = function() { - this.map_ = {}; - this.arrClean = false; -}; - - -/** - * Deletes a particular key from the map. - * N.B.: differs in name from ES6 Map's `delete` because IE8 does not support - * reserved words as property names. - * @this {jspb.Map} - * @param {K} key - * @return {boolean} Whether any entry with this key was deleted. - */ -jspb.Map.prototype.del = function(key) { - var keyValue = key.toString(); - var hadKey = this.map_.hasOwnProperty(keyValue); - delete this.map_[keyValue]; - this.arrClean = false; - return hadKey; -}; - - -/** - * Returns an array of [key, value] pairs in the map. - * - * This is redundant compared to the plain entries() method, but we provide this - * to help out Angular 1.x users. Still evaluating whether this is the best - * option. - * - * @return {!Array>} - */ -jspb.Map.prototype.getEntryList = function() { - var entries = []; - var strKeys = this.stringKeys_(); - strKeys.sort(); - for (var i = 0; i < strKeys.length; i++) { - var entry = this.map_[strKeys[i]]; - entries.push([entry.key, entry.value]); - } - return entries; -}; - - -/** - * Returns an iterator-iterable over [key, value] pairs in the map. - * Closure compiler sadly doesn't support tuples, ie. Iterator<[K,V]>. - * @return {!IteratorIterable>} The iterator-iterable. - */ -jspb.Map.prototype.entries = function() { - var entries = []; - var strKeys = this.stringKeys_(); - strKeys.sort(); - for (var i = 0; i < strKeys.length; i++) { - var entry = this.map_[strKeys[i]]; - entries.push([entry.key, this.wrapEntry_(entry)]); - } - return new jspb.Map.ArrayIteratorIterable_(entries); -}; - - -/** - * Returns an iterator-iterable over keys in the map. - * @return {!IteratorIterable} The iterator-iterable. - */ -jspb.Map.prototype.keys = function() { - var keys = []; - var strKeys = this.stringKeys_(); - strKeys.sort(); - for (var i = 0; i < strKeys.length; i++) { - var entry = this.map_[strKeys[i]]; - keys.push(entry.key); - } - return new jspb.Map.ArrayIteratorIterable_(keys); -}; - - -/** - * Returns an iterator-iterable over values in the map. - * @return {!IteratorIterable} The iterator-iterable. - */ -jspb.Map.prototype.values = function() { - var values = []; - var strKeys = this.stringKeys_(); - strKeys.sort(); - for (var i = 0; i < strKeys.length; i++) { - var entry = this.map_[strKeys[i]]; - values.push(this.wrapEntry_(entry)); - } - return new jspb.Map.ArrayIteratorIterable_(values); -}; - - -/** - * Iterates over entries in the map, calling a function on each. - * @template T - * @param {function(this:T, V, K, ?jspb.Map)} cb - * @param {T=} opt_thisArg - */ -jspb.Map.prototype.forEach = function(cb, opt_thisArg) { - var strKeys = this.stringKeys_(); - strKeys.sort(); - for (var i = 0; i < strKeys.length; i++) { - var entry = this.map_[strKeys[i]]; - cb.call(opt_thisArg, this.wrapEntry_(entry), entry.key, this); - } -}; - - -/** - * Sets a key in the map to the given value. - * @param {K} key The key - * @param {V} value The value - * @return {!jspb.Map} - */ -jspb.Map.prototype.set = function(key, value) { - var entry = new jspb.Map.Entry_(key); - if (this.valueCtor_) { - entry.valueWrapper = value; - // .toArray() on a message returns a reference to the underlying array - // rather than a copy. - entry.value = value.toArray(); - } else { - entry.value = value; - } - this.map_[key.toString()] = entry; - this.arrClean = false; - return this; -}; - - -/** - * Helper: lazily construct a wrapper around an entry, if needed, and return the - * user-visible type. - * @param {!jspb.Map.Entry_} entry - * @return {V} - * @private - */ -jspb.Map.prototype.wrapEntry_ = function(entry) { - if (this.valueCtor_) { - if (!entry.valueWrapper) { - entry.valueWrapper = new this.valueCtor_(entry.value); - } - return /** @type {V} */ (entry.valueWrapper); - } else { - return entry.value; - } -}; - - -/** - * Gets the value corresponding to a key in the map. - * @param {K} key - * @return {V|undefined} The value, or `undefined` if key not present - */ -jspb.Map.prototype.get = function(key) { - var keyValue = key.toString(); - var entry = this.map_[keyValue]; - if (entry) { - return this.wrapEntry_(entry); - } else { - return undefined; - } -}; - - -/** - * Determines whether the given key is present in the map. - * @param {K} key - * @return {boolean} `true` if the key is present - */ -jspb.Map.prototype.has = function(key) { - var keyValue = key.toString(); - return (keyValue in this.map_); -}; - - -/** - * Write this Map field in wire format to a BinaryWriter, using the given field - * number. - * @param {number} fieldNumber - * @param {!jspb.BinaryWriter} writer - * @param {function(this:jspb.BinaryWriter,number,K)} keyWriterFn - * The method on BinaryWriter that writes type K to the stream. - * @param {function(this:jspb.BinaryWriter,number,V,?=)| - * function(this:jspb.BinaryWriter,number,V,?)} valueWriterFn - * The method on BinaryWriter that writes type V to the stream. May be - * writeMessage, in which case the second callback arg form is used. - * @param {function(V,!jspb.BinaryWriter)=} opt_valueWriterCallback - * The BinaryWriter serialization callback for type V, if V is a message - * type. - */ -jspb.Map.prototype.serializeBinary = function( - fieldNumber, writer, keyWriterFn, valueWriterFn, opt_valueWriterCallback) { - var strKeys = this.stringKeys_(); - strKeys.sort(); - for (var i = 0; i < strKeys.length; i++) { - var entry = this.map_[strKeys[i]]; - writer.beginSubMessage(fieldNumber); - keyWriterFn.call(writer, 1, entry.key); - if (this.valueCtor_) { - valueWriterFn.call(writer, 2, this.wrapEntry_(entry), - opt_valueWriterCallback); - } else { - /** @type {function(this:jspb.BinaryWriter,number,?)} */ (valueWriterFn) - .call(writer, 2, entry.value); - } - writer.endSubMessage(); - } -}; - - -/** - * Read one key/value message from the given BinaryReader. Compatible as the - * `reader` callback parameter to jspb.BinaryReader.readMessage, to be called - * when a key/value pair submessage is encountered. If the Key is undefined, - * we should default it to 0. - * @template K, V - * @param {!jspb.Map} map - * @param {!jspb.BinaryReader} reader - * @param {function(this:jspb.BinaryReader):K} keyReaderFn - * The method on BinaryReader that reads type K from the stream. - * - * @param {function(this:jspb.BinaryReader):V| - * function(this:jspb.BinaryReader,V, - * function(V,!jspb.BinaryReader))} valueReaderFn - * The method on BinaryReader that reads type V from the stream. May be - * readMessage, in which case the second callback arg form is used. - * - * @param {?function(V,!jspb.BinaryReader)=} opt_valueReaderCallback - * The BinaryReader parsing callback for type V, if V is a message type - * - * @param {K=} opt_defaultKey - * The default value for the type of map keys. Accepting map entries with - * unset keys is required for maps to be backwards compatible with the - * repeated message representation described here: goo.gl/zuoLAC - * - * @param {V=} opt_defaultValue - * The default value for the type of map values. Accepting map entries with - * unset values is required for maps to be backwards compatible with the - * repeated message representation described here: goo.gl/zuoLAC - * - */ -jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn, - opt_valueReaderCallback, opt_defaultKey, - opt_defaultValue) { - var key = opt_defaultKey; - var value = opt_defaultValue; - - while (reader.nextField()) { - if (reader.isEndGroup()) { - break; - } - var field = reader.getFieldNumber(); - - if (field == 1) { - // Key. - key = keyReaderFn.call(reader); - } else if (field == 2) { - // Value. - if (map.valueCtor_) { - goog.asserts.assert(opt_valueReaderCallback); - if (!value) { - // Old generator still doesn't provide default value message. - // Need this for backward compatibility. - value = new map.valueCtor_(); - } - valueReaderFn.call(reader, value, opt_valueReaderCallback); - } else { - value = - (/** @type {function(this:jspb.BinaryReader):?} */ (valueReaderFn)) - .call(reader); - } - } - } - - goog.asserts.assert(key != undefined); - goog.asserts.assert(value != undefined); - map.set(key, value); -}; - - -/** - * Helper: compute the list of all stringified keys in the underlying Object - * map. - * @return {!Array} - * @private - */ -jspb.Map.prototype.stringKeys_ = function() { - var m = this.map_; - var ret = []; - for (var p in m) { - if (Object.prototype.hasOwnProperty.call(m, p)) { - ret.push(p); - } - } - return ret; -}; - - - -/** - * @param {K} key The entry's key. - * @param {V=} opt_value The entry's value wrapper. - * @constructor - * @struct - * @template K, V - * @private - */ -jspb.Map.Entry_ = function(key, opt_value) { - /** @const {K} */ - this.key = key; - - // The JSPB-serializable value. For primitive types this will be of type V. - // For message types it will be an array. - /** @type {V} */ - this.value = opt_value; - - // Only used for submessage values. - /** @type {V} */ - this.valueWrapper = undefined; -}; diff --git a/js/maps_test.js b/js/maps_test.js deleted file mode 100644 index 68ed6834c..000000000 --- a/js/maps_test.js +++ /dev/null @@ -1,439 +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. - -goog.require('goog.testing.asserts'); -goog.require('goog.userAgent'); - -// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test -goog.require('proto.jspb.test.MapValueEnum'); -goog.require('proto.jspb.test.MapValueMessage'); -goog.require('proto.jspb.test.TestMapFields'); -goog.require('proto.jspb.test.TestMapFieldsOptionalKeys'); -goog.require('proto.jspb.test.TestMapFieldsOptionalValues'); -goog.require('proto.jspb.test.MapEntryOptionalKeysStringKey'); -goog.require('proto.jspb.test.MapEntryOptionalKeysInt32Key'); -goog.require('proto.jspb.test.MapEntryOptionalKeysInt64Key'); -goog.require('proto.jspb.test.MapEntryOptionalKeysBoolKey'); -goog.require('proto.jspb.test.MapEntryOptionalValuesStringValue'); -goog.require('proto.jspb.test.MapEntryOptionalValuesInt32Value'); -goog.require('proto.jspb.test.MapEntryOptionalValuesInt64Value'); -goog.require('proto.jspb.test.MapEntryOptionalValuesBoolValue'); -goog.require('proto.jspb.test.MapEntryOptionalValuesDoubleValue'); -goog.require('proto.jspb.test.MapEntryOptionalValuesEnumValue'); -goog.require('proto.jspb.test.MapEntryOptionalValuesMessageValue'); - -// CommonJS-LoadFromFile: test_pb proto.jspb.test -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 - * @param {!Array>} entries - */ -function checkMapEquals(map, entries) { - var arr = map.toArray(); - assertEquals(arr.length, entries.length); - for (var i = 0; i < arr.length; i++) { - if (Array.isArray(arr[i])) { - assertTrue(Array.isArray(entries[i])); - assertArrayEquals(arr[i], entries[i]); - } else { - assertElementsEquals(arr[i], entries[i]); - } - } -} - -/** - * Converts an ES6 iterator to an array. - * @template T - * @param {!Iterator} iter an iterator - * @return {!Array} - */ -function toArray(iter) { - var arr = []; - while (true) { - var val = iter.next(); - if (val.done) { - break; - } - arr.push(val.value); - } - return arr; -} - - -/** - * Helper: generate test methods for this TestMapFields class. - * @param {?} msgInfo - * @param {?} submessageCtor - * @param {string} suffix - */ -function makeTests(msgInfo, submessageCtor, suffix) { - /** - * Helper: fill all maps on a TestMapFields. - * @param {?} msg - */ - var fillMapFields = function(msg) { - msg.getMapStringStringMap().set('asdf', 'jkl;').set('key 2', 'hello world'); - msg.getMapStringInt32Map().set('a', 1).set('b', -2); - msg.getMapStringInt64Map().set('c', 0x100000000).set('d', 0x200000000); - msg.getMapStringBoolMap().set('e', true).set('f', false); - msg.getMapStringDoubleMap().set('g', 3.14159).set('h', 2.71828); - msg.getMapStringEnumMap() - .set('i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR) - .set('j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ); - msg.getMapStringMsgMap() - .set('k', new submessageCtor()) - .set('l', new submessageCtor()); - msg.getMapStringMsgMap().get('k').setFoo(42); - msg.getMapStringMsgMap().get('l').setFoo(84); - msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b'); - msg.getMapInt64StringMap() - .set(0x123456789abc, 'c') - .set(0xcba987654321, 'd'); - msg.getMapBoolStringMap().set(false, 'e').set(true, 'f'); - }; - - /** - * Helper: check all maps on a TestMapFields. - * @param {?} msg - */ - var checkMapFields = function(msg) { - checkMapEquals( - msg.getMapStringStringMap(), - [['asdf', 'jkl;'], ['key 2', 'hello world']]); - checkMapEquals(msg.getMapStringInt32Map(), [['a', 1], ['b', -2]]); - checkMapEquals( - msg.getMapStringInt64Map(), [['c', 0x100000000], ['d', 0x200000000]]); - checkMapEquals(msg.getMapStringBoolMap(), [['e', true], ['f', false]]); - checkMapEquals( - msg.getMapStringDoubleMap(), [['g', 3.14159], ['h', 2.71828]]); - checkMapEquals(msg.getMapStringEnumMap(), [ - ['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR], - ['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ] - ]); - checkMapEquals(msg.getMapInt32StringMap(), [[-1, 'a'], [42, 'b']]); - checkMapEquals( - msg.getMapInt64StringMap(), - [[0x123456789abc, 'c'], [0xcba987654321, 'd']]); - checkMapEquals(msg.getMapBoolStringMap(), [[false, 'e'], [true, 'f']]); - - assertEquals(msg.getMapStringMsgMap().getLength(), 2); - assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42); - assertEquals(msg.getMapStringMsgMap().get('l').getFoo(), 84); - - var entries = toArray(msg.getMapStringMsgMap().entries()); - assertEquals(entries.length, 2); - entries.forEach(function(entry) { - var key = entry[0]; - var val = entry[1]; - assert(val === msg.getMapStringMsgMap().get(key)); - }); - - msg.getMapStringMsgMap().forEach(function(val, key) { - assert(val === msg.getMapStringMsgMap().get(key)); - }); - }; - - it('testMapStringStringField' + suffix, function() { - var msg = new msgInfo.constructor(); - assertEquals(msg.getMapStringStringMap().getLength(), 0); - assertEquals(msg.getMapStringInt32Map().getLength(), 0); - assertEquals(msg.getMapStringInt64Map().getLength(), 0); - assertEquals(msg.getMapStringBoolMap().getLength(), 0); - assertEquals(msg.getMapStringDoubleMap().getLength(), 0); - assertEquals(msg.getMapStringEnumMap().getLength(), 0); - assertEquals(msg.getMapStringMsgMap().getLength(), 0); - - // Re-create to clear out any internally-cached wrappers, etc. - msg = new msgInfo.constructor(); - var m = msg.getMapStringStringMap(); - assertEquals(m.has('asdf'), false); - assertEquals(m.get('asdf'), undefined); - m.set('asdf', 'hello world'); - assertEquals(m.has('asdf'), true); - assertEquals(m.get('asdf'), 'hello world'); - m.set('jkl;', 'key 2'); - assertEquals(m.has('jkl;'), true); - assertEquals(m.get('jkl;'), 'key 2'); - assertEquals(m.getLength(), 2); - var it = m.entries(); - assertElementsEquals(it.next().value, ['asdf', 'hello world']); - assertElementsEquals(it.next().value, ['jkl;', 'key 2']); - assertEquals(it.next().done, true); - checkMapEquals(m, [['asdf', 'hello world'], ['jkl;', 'key 2']]); - m.del('jkl;'); - assertEquals(m.has('jkl;'), false); - assertEquals(m.get('jkl;'), undefined); - assertEquals(m.getLength(), 1); - it = m.keys(); - assertEquals(it.next().value, 'asdf'); - assertEquals(it.next().done, true); - it = m.values(); - assertEquals(it.next().value, 'hello world'); - assertEquals(it.next().done, true); - - var count = 0; - m.forEach(function(value, key, map) { - assertEquals(map, m); - assertEquals(key, 'asdf'); - assertEquals(value, 'hello world'); - count++; - }); - assertEquals(count, 1); - - m.clear(); - assertEquals(m.getLength(), 0); - }); - - - /** - * Tests operations on maps with all key and value types. - */ - it('testAllMapTypes' + suffix, function() { - var msg = new msgInfo.constructor(); - fillMapFields(msg); - checkMapFields(msg); - }); - - - if (msgInfo.deserializeBinary) { - /** - * Tests serialization and deserialization in binary format. - */ - it('testBinaryFormat' + suffix, function() { - if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) { - // IE8/9 currently doesn't support binary format because they lack - // TypedArray. - return; - } - - // Check that the format is correct. - var msg = new msgInfo.constructor(); - msg.getMapStringStringMap().set('A', 'a'); - var serialized = msg.serializeBinary(); - var expectedSerialized = [ - 0x0a, 0x6, // field 1 (map_string_string), delimited, length 6 - 0x0a, 0x1, // field 1 in submessage (key), delimited, length 1 - 0x41, // ASCII 'A' - 0x12, 0x1, // field 2 in submessage (value), delimited, length 1 - 0x61 // ASCII 'a' - ]; - assertEquals(serialized.length, expectedSerialized.length); - for (var i = 0; i < serialized.length; i++) { - assertEquals(serialized[i], expectedSerialized[i]); - } - - // Check that all map fields successfully round-trip. - msg = new msgInfo.constructor(); - fillMapFields(msg); - serialized = msg.serializeBinary(); - var decoded = msgInfo.deserializeBinary(serialized); - checkMapFields(decoded); - }); - - /** - * Tests deserialization of undefined map keys go to default values in - * binary format. - */ - it('testMapDeserializationForUndefinedKeys', function() { - 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'); - testMessageOptionalKeys.setMapInt32String(mapEntryInt32Key); - var mapEntryInt64Key = new proto.jspb.test.MapEntryOptionalKeysInt64Key(); - mapEntryInt64Key.setValue('c'); - testMessageOptionalKeys.setMapInt64String(mapEntryInt64Key); - var mapEntryBoolKey = new proto.jspb.test.MapEntryOptionalKeysBoolKey(); - 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']]); - }); - - /** - * Tests deserialization of undefined map values go to default values in - * binary format. - */ - it('testMapDeserializationForUndefinedValues', function() { - var testMessageOptionalValues = - new proto.jspb.test.TestMapFieldsOptionalValues(); - var mapEntryStringValue = - new proto.jspb.test.MapEntryOptionalValuesStringValue(); - mapEntryStringValue.setKey('a'); - testMessageOptionalValues.setMapStringString(mapEntryStringValue); - var mapEntryInt32Value = - new proto.jspb.test.MapEntryOptionalValuesInt32Value(); - mapEntryInt32Value.setKey('b'); - testMessageOptionalValues.setMapStringInt32(mapEntryInt32Value); - var mapEntryInt64Value = - new proto.jspb.test.MapEntryOptionalValuesInt64Value(); - mapEntryInt64Value.setKey('c'); - testMessageOptionalValues.setMapStringInt64(mapEntryInt64Value); - var mapEntryBoolValue = - new proto.jspb.test.MapEntryOptionalValuesBoolValue(); - mapEntryBoolValue.setKey('d'); - testMessageOptionalValues.setMapStringBool(mapEntryBoolValue); - var mapEntryDoubleValue = - new proto.jspb.test.MapEntryOptionalValuesDoubleValue(); - mapEntryDoubleValue.setKey('e'); - testMessageOptionalValues.setMapStringDouble(mapEntryDoubleValue); - var mapEntryEnumValue = - new proto.jspb.test.MapEntryOptionalValuesEnumValue(); - mapEntryEnumValue.setKey('f'); - testMessageOptionalValues.setMapStringEnum(mapEntryEnumValue); - var mapEntryMessageValue = - new proto.jspb.test.MapEntryOptionalValuesMessageValue(); - 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', []]]); - }); - } - - - /** - * Exercises the lazy map<->underlying array sync. - */ - it('testLazyMapSync' + suffix, function() { - // Start with a JSPB array containing a few map entries. - var entries = [['a', 'entry 1'], ['c', 'entry 2'], ['b', 'entry 3']]; - var msg = new msgInfo.constructor([entries]); - assertEquals(entries.length, 3); - assertEquals(entries[0][0], 'a'); - assertEquals(entries[1][0], 'c'); - assertEquals(entries[2][0], 'b'); - msg.getMapStringStringMap().del('a'); - assertEquals(entries.length, 3); // not yet sync'd - msg.toArray(); // force a sync - assertEquals(entries.length, 2); - assertEquals(entries[0][0], 'b'); // now in sorted order - assertEquals(entries[1][0], 'c'); - - var a = msg.toArray(); - assertEquals(a[0], entries); // retains original reference - }); - - /** - * Returns IteratorIterables for entries(), keys() and values(). - */ - it('testIteratorIterables' + suffix, function() { - var msg = new msgInfo.constructor(); - var m = msg.getMapStringStringMap(); - m.set('key1', 'value1'); - m.set('key2', 'value2'); - var entryIterator = m.entries(); - assertElementsEquals(entryIterator.next().value, ['key1', 'value1']); - assertElementsEquals(entryIterator.next().value, ['key2', 'value2']); - assertEquals(entryIterator.next().done, true); - - try { - var entryIterable = m.entries()[Symbol.iterator](); - assertElementsEquals(entryIterable.next().value, ['key1', 'value1']); - assertElementsEquals(entryIterable.next().value, ['key2', 'value2']); - assertEquals(entryIterable.next().done, true); - } catch (err) { - // jspb.Map.ArrayIteratorIterable_.prototype[Symbol.iterator] may be - // undefined in some environment. - if (err.name != 'TypeError' && err.name != 'ReferenceError') { - throw err; - } - } - - var keyIterator = m.keys(); - assertEquals(keyIterator.next().value, 'key1'); - assertEquals(keyIterator.next().value, 'key2'); - assertEquals(keyIterator.next().done, true); - - try { - var keyIterable = m.keys()[Symbol.iterator](); - assertEquals(keyIterable.next().value, 'key1'); - assertEquals(keyIterable.next().value, 'key2'); - assertEquals(keyIterable.next().done, true); - } catch (err) { - // jspb.Map.ArrayIteratorIterable_.prototype[Symbol.iterator] may be - // undefined in some environment. - if (err.name != 'TypeError' && err.name != 'ReferenceError') { - throw err; - } - } - var valueIterator = m.values(); - assertEquals(valueIterator.next().value, 'value1'); - assertEquals(valueIterator.next().value, 'value2'); - assertEquals(valueIterator.next().done, true); - - try { - var valueIterable = m.values()[Symbol.iterator](); - assertEquals(valueIterable.next().value, 'value1'); - assertEquals(valueIterable.next().value, 'value2'); - assertEquals(valueIterable.next().done, true); - } catch (err) { - // jspb.Map.ArrayIteratorIterable_.prototype[Symbol.iterator] may be - // undefined in some environment. - if (err.name != 'TypeError' && err.name != 'ReferenceError') { - throw err; - } - } - }); -} - -describe('mapsTest', function() { - makeTests( - { - constructor: proto.jspb.test.TestMapFields, - deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary - }, - proto.jspb.test.MapValueMessage, '_Binary'); - makeTests( - { - constructor: proto.jspb.test.TestMapFieldsNoBinary, - deserializeBinary: null - }, - proto.jspb.test.MapValueMessageNoBinary, '_NoBinary'); -}); diff --git a/js/message.js b/js/message.js deleted file mode 100644 index 905329fe4..000000000 --- a/js/message.js +++ /dev/null @@ -1,1890 +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. - -/** - * @fileoverview Definition of jspb.Message. - * - * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed - * @author mwr@google.com (Mark Rawling) - */ - -goog.provide('jspb.ExtensionFieldBinaryInfo'); -goog.provide('jspb.ExtensionFieldInfo'); -goog.provide('jspb.Message'); - -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.crypt.base64'); -goog.require('jspb.BinaryReader'); -goog.require('jspb.Map'); - - - - -/** - * Stores information for a single extension field. - * - * For example, an extension field defined like so: - * - * extend BaseMessage { - * optional MyMessage my_field = 123; - * } - * - * will result in an ExtensionFieldInfo object with these properties: - * - * { - * fieldIndex: 123, - * fieldName: {my_field_renamed: 0}, - * ctor: proto.example.MyMessage, - * toObjectFn: proto.example.MyMessage.toObject, - * isRepeated: 0 - * } - * - * We include `toObjectFn` to allow the JSCompiler to perform dead-code removal - * on unused toObject() methods. - * - * If an extension field is primitive, ctor and toObjectFn will be null. - * isRepeated should be 0 or 1. - * - * binary{Reader,Writer}Fn and (if message type) binaryMessageSerializeFn are - * always provided. binaryReaderFn and binaryWriterFn are references to the - * appropriate methods on BinaryReader/BinaryWriter to read/write the value of - * this extension, and binaryMessageSerializeFn is a reference to the message - * class's .serializeBinary method, if available. - * - * @param {number} fieldNumber - * @param {Object} fieldName This has the extension field name as a property. - * @param {?function(new: jspb.Message, Array=)} ctor - * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn - * @param {number} isRepeated - * @constructor - * @struct - * @template T - */ -jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn, - isRepeated) { - /** @const */ - this.fieldIndex = fieldNumber; - /** @const */ - this.fieldName = fieldName; - /** @const */ - this.ctor = ctor; - /** @const */ - this.toObjectFn = toObjectFn; - /** @const */ - this.isRepeated = isRepeated; -}; - -/** - * Stores binary-related information for a single extension field. - * @param {!jspb.ExtensionFieldInfo} fieldInfo - * @param {function(this:jspb.BinaryReader,number,?,?)} binaryReaderFn - * @param {function(this:jspb.BinaryWriter,number,?) - * |function(this:jspb.BinaryWriter,number,?,?,?,?,?)} binaryWriterFn - * @param {function(?,?)=} opt_binaryMessageSerializeFn - * @param {function(?,?)=} opt_binaryMessageDeserializeFn - * @param {boolean=} opt_isPacked - * @constructor - * @struct - * @template T - */ -jspb.ExtensionFieldBinaryInfo = function(fieldInfo, binaryReaderFn, binaryWriterFn, - opt_binaryMessageSerializeFn, opt_binaryMessageDeserializeFn, opt_isPacked) { - /** @const */ - this.fieldInfo = fieldInfo; - /** @const */ - this.binaryReaderFn = binaryReaderFn; - /** @const */ - this.binaryWriterFn = binaryWriterFn; - /** @const */ - this.binaryMessageSerializeFn = opt_binaryMessageSerializeFn; - /** @const */ - this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn; - /** @const */ - this.isPacked = opt_isPacked; -}; - -/** - * @return {boolean} Does this field represent a sub Message? - */ -jspb.ExtensionFieldInfo.prototype.isMessageType = function() { - return !!this.ctor; -}; - - -/** - * Base class for all JsPb messages. - * - * Several common methods (toObject, serializeBinary, in particular) are not - * defined on the prototype to encourage code patterns that minimize code bloat - * due to otherwise unused code on all protos contained in the project. - * - * If you want to call these methods on a generic message, either - * pass in your instance of method as a parameter: - * someFunction(instanceOfKnownProto, - * KnownProtoClass.prototype.serializeBinary); - * or use a lambda that knows the type: - * someFunction(()=>instanceOfKnownProto.serializeBinary()); - * or, if you don't care about code size, just suppress the - * WARNING - Property serializeBinary never defined on jspb.Message - * and call it the intuitive way. - * - * @constructor - * @struct - */ -jspb.Message = function() { -}; - - -/** - * @define {boolean} Whether to generate toObject methods for objects. Turn - * this off, if you do not want toObject to be ever used in your project. - * When turning off this flag, consider adding a conformance test that bans - * calling toObject. Enabling this will disable the JSCompiler's ability to - * dead code eliminate fields used in protocol buffers that are never used - * in an application. - */ -jspb.Message.GENERATE_TO_OBJECT = - goog.define('jspb.Message.GENERATE_TO_OBJECT', true); - - -/** - * @define {boolean} Whether to generate fromObject methods for objects. Turn - * this off, if you do not want fromObject to be ever used in your project. - * When turning off this flag, consider adding a conformance test that bans - * calling fromObject. Enabling this might disable the JSCompiler's ability - * to dead code eliminate fields used in protocol buffers that are never - * used in an application. - * By default this is enabled for test code only. - */ -jspb.Message.GENERATE_FROM_OBJECT = goog.define( - 'jspb.Message.GENERATE_FROM_OBJECT', !goog.DISALLOW_TEST_ONLY_CODE); - - -/** - * @define {boolean} Whether to generate toString methods for objects. Turn - * this off if you do not use toString in your project and want to trim it - * from the compiled JS. - */ -jspb.Message.GENERATE_TO_STRING = - goog.define('jspb.Message.GENERATE_TO_STRING', true); - - -/** - * @define {boolean} Whether arrays passed to initialize() can be assumed to be - * local (e.g. not from another iframe) and thus safely classified with - * instanceof Array. - */ -jspb.Message.ASSUME_LOCAL_ARRAYS = - goog.define('jspb.Message.ASSUME_LOCAL_ARRAYS', false); - - -// TODO(jakubvrana): Turn this off by default. -/** - * @define {boolean} Disabling the serialization of empty trailing fields - * reduces the size of serialized protos. The price is an extra iteration of - * the proto before serialization. This is enabled by default to be - * backwards compatible. Projects are advised to turn this flag always off. - */ -jspb.Message.SERIALIZE_EMPTY_TRAILING_FIELDS = - goog.define('jspb.Message.SERIALIZE_EMPTY_TRAILING_FIELDS', true); - - -/** - * Does this JavaScript environment support Uint8Aray typed arrays? - * @type {boolean} - * @private - */ -jspb.Message.SUPPORTS_UINT8ARRAY_ = (typeof Uint8Array == 'function'); - - -/** - * The internal data array. - * @type {!Array} - * @protected - */ -jspb.Message.prototype.array; - - -/** - * Wrappers are the constructed instances of message-type fields. They are built - * on demand from the raw array data. Includes message fields, repeated message - * fields and extension message fields. Indexed by field number. - * @type {Object} - * @private - */ -jspb.Message.prototype.wrappers_; - - -/** - * The object that contains extension fields, if any. This is an object that - * maps from a proto field number to the field's value. - * @type {Object} - * @private - */ -jspb.Message.prototype.extensionObject_; - - -/** - * Non-extension fields with a field number at or above the pivot are - * stored in the extension object (in addition to all extension fields). - * @type {number} - * @private - */ -jspb.Message.prototype.pivot_; - - -/** - * The JsPb message_id of this proto. - * @type {string|undefined} the message id or undefined if this message - * has no id. - * @private - */ -jspb.Message.prototype.messageId_; - - -/** - * Repeated fields that have been converted to their proper type. This is used - * for numbers stored as strings (typically "NaN", "Infinity" and "-Infinity") - * and for booleans stored as numbers (0 or 1). - * @private {!Object|undefined} - */ -jspb.Message.prototype.convertedPrimitiveFields_; - -/** - * Repeated fields numbers. - * @protected {?Array|undefined} - */ -jspb.Message.prototype.repeatedFields; - - - -/** - * Returns the JsPb message_id of this proto. - * @return {string|undefined} the message id or undefined if this message - * has no id. - */ -jspb.Message.prototype.getJsPbMessageId = function() { - return this.messageId_; -}; - - -/** - * An offset applied to lookups into this.array to account for the presence or - * absence of a messageId at position 0. For response messages, this will be 0. - * Otherwise, it will be -1 so that the first array position is not wasted. - * @type {number} - * @private - */ -jspb.Message.prototype.arrayIndexOffset_; - - -/** - * Returns the index into msg.array at which the proto field with tag number - * fieldNumber will be located. - * @param {!jspb.Message} msg Message for which we're calculating an index. - * @param {number} fieldNumber The field number. - * @return {number} The index. - * @private - */ -jspb.Message.getIndex_ = function(msg, fieldNumber) { - return fieldNumber + msg.arrayIndexOffset_; -}; - -// This is only here to ensure we are not back sliding on ES6 requirements for -// protos in g3. -jspb.Message.hiddenES6Property_ = class {}; - - -/** - * Returns the tag number based on the index in msg.array. - * @param {!jspb.Message} msg Message for which we're calculating an index. - * @param {number} index The tag number. - * @return {number} The field number. - * @private - */ -jspb.Message.getFieldNumber_ = function(msg, index) { - return index - msg.arrayIndexOffset_; -}; - - -/** - * Initializes a JsPb Message. - * @param {!jspb.Message} msg The JsPb proto to modify. - * @param {Array|undefined} data An initial data array. - * @param {string|number} messageId For response messages, the message id or '' - * if no message id is specified. For non-response messages, 0. - * @param {number} suggestedPivot The field number at which to start putting - * fields into the extension object. This is only used if data does not - * contain an extension object already. -1 if no extension object is - * required for this message type. - * @param {Array} repeatedFields The message's repeated fields. - * @param {Array>=} opt_oneofFields The fields belonging to - * each of the message's oneof unions. - * @protected - */ -jspb.Message.initialize = function( - msg, data, messageId, suggestedPivot, repeatedFields, opt_oneofFields) { - msg.wrappers_ = null; - if (!data) { - data = messageId ? [messageId] : []; - } - msg.messageId_ = messageId ? String(messageId) : undefined; - // If the messageId is 0, this message is not a response message, so we shift - // array indices down by 1 so as not to waste the first position in the array, - // which would otherwise go unused. - msg.arrayIndexOffset_ = messageId === 0 ? -1 : 0; - msg.array = data; - jspb.Message.initPivotAndExtensionObject_(msg, suggestedPivot); - msg.convertedPrimitiveFields_ = {}; - - if (!jspb.Message.SERIALIZE_EMPTY_TRAILING_FIELDS) { - // TODO(jakubvrana): This is same for all instances, move to prototype. - // TODO(jakubvrana): There are indexOf calls on this in serialization, - // consider switching to a set. - msg.repeatedFields = repeatedFields; - } - - if (repeatedFields) { - for (var i = 0; i < repeatedFields.length; i++) { - var fieldNumber = repeatedFields[i]; - if (fieldNumber < msg.pivot_) { - var index = jspb.Message.getIndex_(msg, fieldNumber); - msg.array[index] = - msg.array[index] || jspb.Message.EMPTY_LIST_SENTINEL_; - } else { - jspb.Message.maybeInitEmptyExtensionObject_(msg); - msg.extensionObject_[fieldNumber] = msg.extensionObject_[fieldNumber] || - jspb.Message.EMPTY_LIST_SENTINEL_; - } - } - } - - if (opt_oneofFields && opt_oneofFields.length) { - // Compute the oneof case for each union. This ensures only one value is - // set in the union. - for (var i = 0; i < opt_oneofFields.length; i++) { - jspb.Message.computeOneofCase(msg, opt_oneofFields[i]); - } - } -}; - - -/** - * Used to mark empty repeated fields. Serializes to null when serialized - * to JSON. - * When reading a repeated field readers must check the return value against - * this value and return and replace it with a new empty array if it is - * present. - * @private @const {!Object} - */ -jspb.Message.EMPTY_LIST_SENTINEL_ = goog.DEBUG && Object.freeze ? - Object.freeze([]) : - []; - - -/** - * Returns true if the provided argument is an array. - * @param {*} o The object to classify as array or not. - * @return {boolean} True if the provided object is an array. - * @private - */ -jspb.Message.isArray_ = function(o) { - return jspb.Message.ASSUME_LOCAL_ARRAYS ? o instanceof Array : - Array.isArray(o); -}; - -/** - * Returns true if the provided argument is an extension object. - * @param {*} o The object to classify as array or not. - * @return {boolean} True if the provided object is an extension object. - * @private - */ -jspb.Message.isExtensionObject_ = function(o) { - // Normal fields are never objects, so we can be sure that if we find an - // object here, then it's the extension object. However, we must ensure that - // the object is not an array, since arrays are valid field values (bytes - // fields can also be array). - // NOTE(lukestebbing): We avoid looking at .length to avoid a JIT bug - // in Safari on iOS 8. See the description of CL/86511464 for details. - return (o !== null && typeof o == 'object' && - !jspb.Message.isArray_(o) && - !(jspb.Message.SUPPORTS_UINT8ARRAY_ && o instanceof Uint8Array)); -}; - - -/** - * If the array contains an extension object in its last position, then the - * object is kept in place and its position is used as the pivot. If not, - * decides the pivot of the message based on suggestedPivot without - * materializing the extension object. - * - * @param {!jspb.Message} msg The JsPb proto to modify. - * @param {number} suggestedPivot See description for initialize(). - * @private - */ -jspb.Message.initPivotAndExtensionObject_ = function(msg, suggestedPivot) { - // There are 3 variants that need to be dealt with which are the - // combination of whether there exists an extension object (EO) and - // whether there is a suggested pivot (SP). - // - // EO, ? : pivot is the index of the EO - // no-EO, no-SP: pivot is MAX_INT - // no-EO, SP : pivot is the max(lastindex + 1, SP) - - var msgLength = msg.array.length; - var lastIndex = -1; - if (msgLength) { - lastIndex = msgLength - 1; - var obj = msg.array[lastIndex]; - if (jspb.Message.isExtensionObject_(obj)) { - msg.pivot_ = jspb.Message.getFieldNumber_(msg, lastIndex); - msg.extensionObject_ = obj; - return; - } - } - - if (suggestedPivot > -1) { - // If a extension object is not present, set the pivot value as being - // after the last value in the array to avoid overwriting values, etc. - msg.pivot_ = Math.max( - suggestedPivot, jspb.Message.getFieldNumber_(msg, lastIndex + 1)); - // Avoid changing the shape of the proto with an empty extension object by - // deferring the materialization of the extension object until the first - // time a field set into it (may be due to getting a repeated proto field - // from it, in which case a new empty array is set into it at first). - msg.extensionObject_ = null; - } else { - // suggestedPivot is -1, which means that we don't have an extension object - // at all, in which case all fields are stored in the array. - msg.pivot_ = Number.MAX_VALUE; - } -}; - - -/** - * Creates an empty extensionObject_ if non exists. - * @param {!jspb.Message} msg The JsPb proto to modify. - * @private - */ -jspb.Message.maybeInitEmptyExtensionObject_ = function(msg) { - var pivotIndex = jspb.Message.getIndex_(msg, msg.pivot_); - if (!msg.array[pivotIndex]) { - msg.extensionObject_ = msg.array[pivotIndex] = {}; - } -}; - - -/** - * Converts a JsPb repeated message field into an object list. - * @param {!Array} field The repeated message field to be - * converted. - * @param {?function(boolean=): Object| - * function((boolean|undefined),T): Object} toObjectFn The toObject - * function for this field. We need to pass this for effective dead code - * removal. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - * @return {!Array} An array of converted message objects. - * @template T - */ -jspb.Message.toObjectList = function(field, toObjectFn, opt_includeInstance) { - // Not using goog.array.map in the generated code to keep it small. - // And not using it here to avoid a function call. - var result = []; - for (var i = 0; i < field.length; i++) { - result[i] = toObjectFn.call(field[i], opt_includeInstance, field[i]); - } - return result; -}; - - -/** - * Adds a proto's extension data to a Soy rendering object. - * @param {!jspb.Message} proto The proto whose extensions to convert. - * @param {!Object} obj The Soy object to add converted extension data to. - * @param {!Object} extensions The proto class' registered extensions. - * @param {function(this:?, jspb.ExtensionFieldInfo) : *} getExtensionFn - * The proto class' getExtension function. Passed for effective dead code - * removal. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - */ -jspb.Message.toObjectExtension = function(proto, obj, extensions, - getExtensionFn, opt_includeInstance) { - for (var fieldNumber in extensions) { - var fieldInfo = extensions[fieldNumber]; - var value = getExtensionFn.call(proto, fieldInfo); - if (value != null) { - for (var name in fieldInfo.fieldName) { - if (fieldInfo.fieldName.hasOwnProperty(name)) { - break; // the compiled field name - } - } - if (!fieldInfo.toObjectFn) { - obj[name] = value; - } else { - if (fieldInfo.isRepeated) { - obj[name] = jspb.Message.toObjectList( - /** @type {!Array} */ (value), - fieldInfo.toObjectFn, opt_includeInstance); - } else { - obj[name] = fieldInfo.toObjectFn( - opt_includeInstance, /** @type {!jspb.Message} */ (value)); - } - } - } - } -}; - - -/** - * Writes a proto's extension data to a binary-format output stream. - * @param {!jspb.Message} proto The proto whose extensions to convert. - * @param {*} writer The binary-format writer to write to. - * @param {!Object} extensions The proto class' registered extensions. - * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo) : *} getExtensionFn The proto - * class' getExtension function. Passed for effective dead code removal. - */ -jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, - getExtensionFn) { - for (var fieldNumber in extensions) { - var binaryFieldInfo = extensions[fieldNumber]; - var fieldInfo = binaryFieldInfo.fieldInfo; - - // The old codegen doesn't add the extra fields to ExtensionFieldInfo, so we - // need to gracefully error-out here rather than produce a null dereference - // below. - if (!binaryFieldInfo.binaryWriterFn) { - throw new Error('Message extension present that was generated ' + - 'without binary serialization support'); - } - var value = getExtensionFn.call(proto, fieldInfo); - if (value != null) { - if (fieldInfo.isMessageType()) { - // If the message type of the extension was generated without binary - // support, there may not be a binary message serializer function, and - // we can't know when we codegen the extending message that the extended - // message may require binary support, so we can *only* catch this error - // here, at runtime (and this decoupled codegen is the whole point of - // extensions!). - if (binaryFieldInfo.binaryMessageSerializeFn) { - binaryFieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex, - value, binaryFieldInfo.binaryMessageSerializeFn); - } else { - throw new Error('Message extension present holding submessage ' + - 'without binary support enabled, and message is ' + - 'being serialized to binary format'); - } - } else { - binaryFieldInfo.binaryWriterFn.call( - writer, fieldInfo.fieldIndex, value); - } - } - } -}; - - -/** - * Reads an extension field from the given reader and, if a valid extension, - * sets the extension value. - * @param {!jspb.Message} msg A jspb proto. - * @param {!jspb.BinaryReader} reader - * @param {!Object} extensions The extensions object. - * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo)} getExtensionFn - * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo, ?)} setExtensionFn - */ -jspb.Message.readBinaryExtension = function(msg, reader, extensions, - getExtensionFn, setExtensionFn) { - var binaryFieldInfo = extensions[reader.getFieldNumber()]; - if (!binaryFieldInfo) { - reader.skipField(); - return; - } - var fieldInfo = binaryFieldInfo.fieldInfo; - if (!binaryFieldInfo.binaryReaderFn) { - throw new Error('Deserializing extension whose generated code does not ' + - 'support binary format'); - } - - var value; - if (fieldInfo.isMessageType()) { - value = new fieldInfo.ctor(); - binaryFieldInfo.binaryReaderFn.call( - reader, value, binaryFieldInfo.binaryMessageDeserializeFn); - } else { - // All other types. - value = binaryFieldInfo.binaryReaderFn.call(reader); - } - - if (fieldInfo.isRepeated && !binaryFieldInfo.isPacked) { - var currentList = getExtensionFn.call(msg, fieldInfo); - if (!currentList) { - setExtensionFn.call(msg, fieldInfo, [value]); - } else { - currentList.push(value); - } - } else { - setExtensionFn.call(msg, fieldInfo, value); - } -}; - - -/** - * Gets the value of a non-extension field. - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @return {string|number|boolean|Uint8Array|Array|null|undefined} - * The field's value. - * @protected - */ -jspb.Message.getField = function(msg, fieldNumber) { - if (fieldNumber < msg.pivot_) { - var index = jspb.Message.getIndex_(msg, fieldNumber); - var val = msg.array[index]; - if (val === jspb.Message.EMPTY_LIST_SENTINEL_) { - return msg.array[index] = []; - } - return val; - } else { - if (!msg.extensionObject_) { - return undefined; - } - var val = msg.extensionObject_[fieldNumber]; - if (val === jspb.Message.EMPTY_LIST_SENTINEL_) { - return msg.extensionObject_[fieldNumber] = []; - } - return val; - } -}; - - -/** - * Gets the value of a non-extension repeated field. - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @return {!Array} - * The field's value. - * @protected - */ -jspb.Message.getRepeatedField = function(msg, fieldNumber) { - return /** @type {!Array} */ (jspb.Message.getField(msg, fieldNumber)); -}; - - -/** - * Gets the value of an optional float or double field. - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @return {?number|undefined} The field's value. - * @protected - */ -jspb.Message.getOptionalFloatingPointField = function(msg, fieldNumber) { - var value = jspb.Message.getField(msg, fieldNumber); - // Converts "NaN", "Infinity" and "-Infinity" to their corresponding numbers. - return value == null ? value : +value; -}; - - -/** - * Gets the value of an optional boolean field. - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @return {?boolean|undefined} The field's value. - * @protected - */ -jspb.Message.getBooleanField = function(msg, fieldNumber) { - var value = jspb.Message.getField(msg, fieldNumber); - // TODO(b/122673075): always return null when the value is null-ish. - return value == null ? (value) : !!value; -}; - - -/** - * Gets the value of a repeated float or double field. - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @return {!Array} The field's value. - * @protected - */ -jspb.Message.getRepeatedFloatingPointField = function(msg, fieldNumber) { - var values = jspb.Message.getRepeatedField(msg, fieldNumber); - if (!msg.convertedPrimitiveFields_) { - msg.convertedPrimitiveFields_ = {}; - } - if (!msg.convertedPrimitiveFields_[fieldNumber]) { - for (var i = 0; i < values.length; i++) { - // Converts "NaN", "Infinity" and "-Infinity" to their corresponding - // numbers. - values[i] = +values[i]; - } - msg.convertedPrimitiveFields_[fieldNumber] = true; - } - return /** @type {!Array} */ (values); -}; - -/** - * Gets the value of a repeated boolean field. - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @return {!Array} The field's value. - * @protected - */ -jspb.Message.getRepeatedBooleanField = function(msg, fieldNumber) { - var values = jspb.Message.getRepeatedField(msg, fieldNumber); - if (!msg.convertedPrimitiveFields_) { - msg.convertedPrimitiveFields_ = {}; - } - if (!msg.convertedPrimitiveFields_[fieldNumber]) { - for (var i = 0; i < values.length; i++) { - // Converts 0 and 1 to their corresponding booleans. - values[i] = !!values[i]; - } - msg.convertedPrimitiveFields_[fieldNumber] = true; - } - return /** @type {!Array} */ (values); -}; - - -/** - * Coerce a 'bytes' field to a base 64 string. - * @param {string|Uint8Array|null} value - * @return {?string} The field's coerced value. - */ -jspb.Message.bytesAsB64 = function(value) { - if (value == null || typeof value === 'string') { - return value; - } - if (jspb.Message.SUPPORTS_UINT8ARRAY_ && value instanceof Uint8Array) { - return goog.crypt.base64.encodeByteArray(value); - } - goog.asserts.fail('Cannot coerce to b64 string: ' + goog.typeOf(value)); - return null; -}; - - -/** - * Coerce a 'bytes' field to a Uint8Array byte buffer. - * Note that Uint8Array is not supported on IE versions before 10 nor on Opera - * Mini. @see http://caniuse.com/Uint8Array - * @param {string|Uint8Array|null} value - * @return {?Uint8Array} The field's coerced value. - */ -jspb.Message.bytesAsU8 = function(value) { - if (value == null || value instanceof Uint8Array) { - return value; - } - if (typeof value === 'string') { - return goog.crypt.base64.decodeStringToUint8Array(value); - } - goog.asserts.fail('Cannot coerce to Uint8Array: ' + goog.typeOf(value)); - return null; -}; - - -/** - * Coerce a repeated 'bytes' field to an array of base 64 strings. - * Note: the returned array should be treated as immutable. - * @param {!Array|!Array} value - * @return {!Array} The field's coerced value. - */ -jspb.Message.bytesListAsB64 = function(value) { - jspb.Message.assertConsistentTypes_(value); - if (!value.length || typeof value[0] === 'string') { - return /** @type {!Array} */ (value); - } - return goog.array.map(value, jspb.Message.bytesAsB64); -}; - - -/** - * Coerce a repeated 'bytes' field to an array of Uint8Array byte buffers. - * Note: the returned array should be treated as immutable. - * Note that Uint8Array is not supported on IE versions before 10 nor on Opera - * Mini. @see http://caniuse.com/Uint8Array - * @param {!Array|!Array} value - * @return {!Array} The field's coerced value. - */ -jspb.Message.bytesListAsU8 = function(value) { - jspb.Message.assertConsistentTypes_(value); - if (!value.length || value[0] instanceof Uint8Array) { - return /** @type {!Array} */ (value); - } - return goog.array.map(value, jspb.Message.bytesAsU8); -}; - - -/** - * Asserts that all elements of an array are of the same type. - * @param {Array?} array The array to test. - * @private - */ -jspb.Message.assertConsistentTypes_ = function(array) { - if (goog.DEBUG && array && array.length > 1) { - var expected = goog.typeOf(array[0]); - goog.array.forEach(array, function(e) { - if (goog.typeOf(e) != expected) { - goog.asserts.fail('Inconsistent type in JSPB repeated field array. ' + - 'Got ' + goog.typeOf(e) + ' expected ' + expected); - } - }); - } -}; - - -/** - * Gets the value of a non-extension primitive field, with proto3 (non-nullable - * primitives) semantics. Returns `defaultValue` if the field is not otherwise - * set. - * @template T - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {T} defaultValue The default value. - * @return {T} The field's value. - * @protected - */ -jspb.Message.getFieldWithDefault = function(msg, fieldNumber, defaultValue) { - var value = jspb.Message.getField(msg, fieldNumber); - if (value == null) { - return defaultValue; - } else { - return value; - } -}; - - -/** - * Gets the value of a boolean field, with proto3 (non-nullable primitives) - * semantics. Returns `defaultValue` if the field is not otherwise set. - * @template T - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {boolean} defaultValue The default value. - * @return {boolean} The field's value. - * @protected - */ -jspb.Message.getBooleanFieldWithDefault = function( - msg, fieldNumber, defaultValue) { - var value = jspb.Message.getBooleanField(msg, fieldNumber); - if (value == null) { - return defaultValue; - } else { - return value; - } -}; - - -/** - * Gets the value of a floating point field, with proto3 (non-nullable - * primitives) semantics. Returns `defaultValue` if the field is not otherwise - * set. - * @template T - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {number} defaultValue The default value. - * @return {number} The field's value. - * @protected - */ -jspb.Message.getFloatingPointFieldWithDefault = function( - msg, fieldNumber, defaultValue) { - var value = jspb.Message.getOptionalFloatingPointField(msg, fieldNumber); - if (value == null) { - return defaultValue; - } else { - return value; - } -}; - - -/** - * Alias for getFieldWithDefault used by older generated code. - * @template T - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {T} defaultValue The default value. - * @return {T} The field's value. - * @protected - */ -jspb.Message.getFieldProto3 = jspb.Message.getFieldWithDefault; - - -/** - * Gets the value of a map field, lazily creating the map container if - * necessary. - * - * This should only be called from generated code, because it requires knowledge - * of serialization/parsing callbacks (which are required by the map at - * construction time, and the map may be constructed here). - * - * @template K, V - * @param {!jspb.Message} msg - * @param {number} fieldNumber - * @param {boolean|undefined} noLazyCreate - * @param {?=} opt_valueCtor - * @return {!jspb.Map|undefined} - * @protected - */ -jspb.Message.getMapField = function(msg, fieldNumber, noLazyCreate, - opt_valueCtor) { - if (!msg.wrappers_) { - msg.wrappers_ = {}; - } - // If we already have a map in the map wrappers, return that. - if (fieldNumber in msg.wrappers_) { - return msg.wrappers_[fieldNumber]; - } - var arr = jspb.Message.getField(msg, fieldNumber); - // Wrap the underlying elements array with a Map. - if (!arr) { - if (noLazyCreate) { - return undefined; - } - arr = []; - jspb.Message.setField(msg, fieldNumber, arr); - } - return msg.wrappers_[fieldNumber] = - new jspb.Map( - /** @type {!Array>} */ (arr), opt_valueCtor); -}; - - -/** - * Sets the value of a non-extension field. - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {string|number|boolean|Uint8Array|Array|undefined} value New value - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.setField = function(msg, fieldNumber, value) { - // TODO(b/35241823): replace this with a bounded generic when available - goog.asserts.assertInstanceof(msg, jspb.Message); - if (fieldNumber < msg.pivot_) { - msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value; - } else { - jspb.Message.maybeInitEmptyExtensionObject_(msg); - msg.extensionObject_[fieldNumber] = value; - } - return msg; -}; - - -/** - * Sets the value of a non-extension integer field of a proto3 - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {number} value New value - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.setProto3IntField = function(msg, fieldNumber, value) { - return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, 0); -}; - - -/** - * Sets the value of a non-extension floating point field of a proto3 - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {number} value New value - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.setProto3FloatField = function(msg, fieldNumber, value) { - return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, 0.0); -}; - - -/** - * Sets the value of a non-extension boolean field of a proto3 - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {boolean} value New value - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.setProto3BooleanField = function(msg, fieldNumber, value) { - return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, false); -}; - - -/** - * Sets the value of a non-extension String field of a proto3 - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {string} value New value - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.setProto3StringField = function(msg, fieldNumber, value) { - return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, ''); -}; - - -/** - * Sets the value of a non-extension Bytes field of a proto3 - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {!Uint8Array|string} value New value - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.setProto3BytesField = function(msg, fieldNumber, value) { - return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, ''); -}; - - -/** - * Sets the value of a non-extension enum field of a proto3 - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {number} value New value - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.setProto3EnumField = function(msg, fieldNumber, value) { - return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, 0); -}; - - -/** - * Sets the value of a non-extension int field of a proto3 that has jstype set - * to String. - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {string} value New value - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.setProto3StringIntField = function(msg, fieldNumber, value) { - return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, '0'); -}; - -/** - * Sets the value of a non-extension primitive field, with proto3 (non-nullable - * primitives) semantics of ignoring values that are equal to the type's - * default. - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {!Uint8Array|string|number|boolean|undefined} value New value - * @param {!Uint8Array|string|number|boolean} defaultValue The default value. - * @return {T} return msg - * @template T - * @private - */ -jspb.Message.setFieldIgnoringDefault_ = function( - msg, fieldNumber, value, defaultValue) { - // TODO(b/35241823): replace this with a bounded generic when available - goog.asserts.assertInstanceof(msg, jspb.Message); - if (value !== defaultValue) { - jspb.Message.setField(msg, fieldNumber, value); - } else if (fieldNumber < msg.pivot_) { - msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = null; - } else { - jspb.Message.maybeInitEmptyExtensionObject_(msg); - delete msg.extensionObject_[fieldNumber]; - } - return msg; -}; - - -/** - * Adds a value to a repeated, primitive field. - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {string|number|boolean|!Uint8Array} value New value - * @param {number=} opt_index Index where to put new value. - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.addToRepeatedField = function(msg, fieldNumber, value, opt_index) { - // TODO(b/35241823): replace this with a bounded generic when available - goog.asserts.assertInstanceof(msg, jspb.Message); - var arr = jspb.Message.getRepeatedField(msg, fieldNumber); - if (opt_index != undefined) { - arr.splice(opt_index, 0, value); - } else { - arr.push(value); - } - return msg; -}; - - -/** - * Sets the value of a field in a oneof union and clears all other fields in - * the union. - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {!Array} oneof The fields belonging to the union. - * @param {string|number|boolean|Uint8Array|Array|undefined} value New value - * @return {T} return msg - * @template T - * @protected - */ -jspb.Message.setOneofField = function(msg, fieldNumber, oneof, value) { - // TODO(b/35241823): replace this with a bounded generic when available - goog.asserts.assertInstanceof(msg, jspb.Message); - var currentCase = jspb.Message.computeOneofCase(msg, oneof); - if (currentCase && currentCase !== fieldNumber && value !== undefined) { - if (msg.wrappers_ && currentCase in msg.wrappers_) { - msg.wrappers_[currentCase] = undefined; - } - jspb.Message.setField(msg, currentCase, undefined); - } - return jspb.Message.setField(msg, fieldNumber, value); -}; - - -/** - * Computes the selection in a oneof group for the given message, ensuring - * only one field is set in the process. - * - * According to the protobuf language guide ( - * https://developers.google.com/protocol-buffers/docs/proto#oneof), "if the - * parser encounters multiple members of the same oneof on the wire, only the - * last member seen is used in the parsed message." Since JSPB serializes - * messages to a JSON array, the "last member seen" will always be the field - * with the greatest field number (directly corresponding to the greatest - * array index). - * - * @param {!jspb.Message} msg A jspb proto. - * @param {!Array} oneof The field numbers belonging to the union. - * @return {number} The field number currently set in the union, or 0 if none. - * @protected - */ -jspb.Message.computeOneofCase = function(msg, oneof) { - var oneofField; - var oneofValue; - - for (var i = 0; i < oneof.length; i++) { - var fieldNumber = oneof[i]; - var value = jspb.Message.getField(msg, fieldNumber); - if (value != null) { - oneofField = fieldNumber; - oneofValue = value; - jspb.Message.setField(msg, fieldNumber, undefined); - } - } - - if (oneofField) { - // NB: We know the value is unique, so we can call jspb.Message.setField - // directly instead of jpsb.Message.setOneofField. Also, setOneofField - // calls this function. - jspb.Message.setField(msg, oneofField, oneofValue); - return oneofField; - } - - return 0; -}; - - -/** - * Gets and wraps a proto field on access. - * @param {!jspb.Message} msg A jspb proto. - * @param {function(new:jspb.Message, Array)} ctor Constructor for the field. - * @param {number} fieldNumber The field number. - * @param {number=} opt_required True (1) if this is a required field. - * @return {jspb.Message} The field as a jspb proto. - * @protected - */ -jspb.Message.getWrapperField = function(msg, ctor, fieldNumber, opt_required) { - // TODO(mwr): Consider copying data and/or arrays. - if (!msg.wrappers_) { - msg.wrappers_ = {}; - } - if (!msg.wrappers_[fieldNumber]) { - var data = /** @type {Array} */ (jspb.Message.getField(msg, fieldNumber)); - if (opt_required || data) { - // TODO(mwr): Remove existence test for always valid default protos. - msg.wrappers_[fieldNumber] = new ctor(data); - } - } - return /** @type {jspb.Message} */ (msg.wrappers_[fieldNumber]); -}; - - -/** - * Gets and wraps a repeated proto field on access. - * @param {!jspb.Message} msg A jspb proto. - * @param {function(new:jspb.Message, Array)} ctor Constructor for the field. - * @param {number} fieldNumber The field number. - * @return {!Array} The repeated field as an array of protos. - * @protected - */ -jspb.Message.getRepeatedWrapperField = function(msg, ctor, fieldNumber) { - jspb.Message.wrapRepeatedField_(msg, ctor, fieldNumber); - var val = msg.wrappers_[fieldNumber]; - if (val == jspb.Message.EMPTY_LIST_SENTINEL_) { - val = msg.wrappers_[fieldNumber] = []; - } - return /** @type {!Array} */ (val); -}; - - -/** - * Wraps underlying array into proto message representation if it wasn't done - * before. - * @param {!jspb.Message} msg A jspb proto. - * @param {function(new:jspb.Message, ?Array)} ctor Constructor for the field. - * @param {number} fieldNumber The field number. - * @private - */ -jspb.Message.wrapRepeatedField_ = function(msg, ctor, fieldNumber) { - if (!msg.wrappers_) { - msg.wrappers_ = {}; - } - if (!msg.wrappers_[fieldNumber]) { - var data = jspb.Message.getRepeatedField(msg, fieldNumber); - for (var wrappers = [], i = 0; i < data.length; i++) { - wrappers[i] = new ctor(data[i]); - } - msg.wrappers_[fieldNumber] = wrappers; - } -}; - - -/** - * Sets a proto field and syncs it to the backing array. - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {?jspb.Message|?jspb.Map|undefined} value A new value for this proto - * field. - * @return {T} the msg - * @template T - * @protected - */ -jspb.Message.setWrapperField = function(msg, fieldNumber, value) { - // TODO(b/35241823): replace this with a bounded generic when available - goog.asserts.assertInstanceof(msg, jspb.Message); - if (!msg.wrappers_) { - msg.wrappers_ = {}; - } - var data = value ? value.toArray() : value; - msg.wrappers_[fieldNumber] = value; - return jspb.Message.setField(msg, fieldNumber, data); -}; - - - -/** - * Sets a proto field in a oneof union and syncs it to the backing array. - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {!Array} oneof The fields belonging to the union. - * @param {jspb.Message|undefined} value A new value for this proto field. - * @return {T} the msg - * @template T - * @protected - */ -jspb.Message.setOneofWrapperField = function(msg, fieldNumber, oneof, value) { - // TODO(b/35241823): replace this with a bounded generic when available - goog.asserts.assertInstanceof(msg, jspb.Message); - if (!msg.wrappers_) { - msg.wrappers_ = {}; - } - var data = value ? value.toArray() : value; - msg.wrappers_[fieldNumber] = value; - return jspb.Message.setOneofField(msg, fieldNumber, oneof, data); -}; - - -/** - * Sets a repeated proto field and syncs it to the backing array. - * @param {T} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {Array|undefined} value An array of protos. - * @return {T} the msg - * @template T - * @protected - */ -jspb.Message.setRepeatedWrapperField = function(msg, fieldNumber, value) { - // TODO(b/35241823): replace this with a bounded generic when available - goog.asserts.assertInstanceof(msg, jspb.Message); - if (!msg.wrappers_) { - msg.wrappers_ = {}; - } - value = value || []; - for (var data = [], i = 0; i < value.length; i++) { - data[i] = value[i].toArray(); - } - msg.wrappers_[fieldNumber] = value; - return jspb.Message.setField(msg, fieldNumber, data); -}; - - -/** - * Add a message to a repeated proto field. - * @param {!jspb.Message} msg A jspb proto. - * @param {number} fieldNumber The field number. - * @param {T_CHILD|undefined} value Proto that will be added to the - * repeated field. - * @param {function(new:T_CHILD, ?Array=)} ctor The constructor of the - * message type. - * @param {number|undefined} index Index at which to insert the value. - * @return {T_CHILD_NOT_UNDEFINED} proto that was inserted to the repeated field - * @template MessageType - * Use go/closure-ttl to declare a non-undefined version of T_CHILD. Replace the - * undefined in blah|undefined with none. This is necessary because the compiler - * will infer T_CHILD to be |undefined. - * @template T_CHILD - * @template T_CHILD_NOT_UNDEFINED := - * cond(isUnknown(T_CHILD), unknown(), - * mapunion(T_CHILD, (X) => - * cond(eq(X, 'undefined'), none(), X))) - * =: - * @protected - */ -jspb.Message.addToRepeatedWrapperField = function( - msg, fieldNumber, value, ctor, index) { - jspb.Message.wrapRepeatedField_(msg, ctor, fieldNumber); - var wrapperArray = msg.wrappers_[fieldNumber]; - if (!wrapperArray) { - wrapperArray = msg.wrappers_[fieldNumber] = []; - } - var insertedValue = value ? value : new ctor(); - var array = jspb.Message.getRepeatedField(msg, fieldNumber); - if (index != undefined) { - wrapperArray.splice(index, 0, insertedValue); - array.splice(index, 0, insertedValue.toArray()); - } else { - wrapperArray.push(insertedValue); - array.push(insertedValue.toArray()); - } - return insertedValue; -}; - - -/** - * Converts a JsPb repeated message field into a map. The map will contain - * protos unless an optional toObject function is given, in which case it will - * contain objects suitable for Soy rendering. - * @param {!Array} field The repeated message field to be - * converted. - * @param {function() : string?} mapKeyGetterFn The function to get the key of - * the map. - * @param {?function(boolean=): Object| - * function((boolean|undefined),T): Object} opt_toObjectFn The - * toObject function for this field. We need to pass this for effective - * dead code removal. - * @param {boolean=} opt_includeInstance Whether to include the JSPB instance - * for transitional soy proto support: http://goto/soy-param-migration - * @return {!Object} A map of proto or Soy objects. - * @template T - */ -jspb.Message.toMap = function( - field, mapKeyGetterFn, opt_toObjectFn, opt_includeInstance) { - var result = {}; - for (var i = 0; i < field.length; i++) { - result[mapKeyGetterFn.call(field[i])] = opt_toObjectFn ? - opt_toObjectFn.call(field[i], opt_includeInstance, - /** @type {!jspb.Message} */ (field[i])) : field[i]; - } - return result; -}; - - -/** - * Syncs all map fields' contents back to their underlying arrays. - * @private - */ -jspb.Message.prototype.syncMapFields_ = function() { - // This iterates over submessage, map, and repeated fields, which is intended. - // Submessages can contain maps which also need to be synced. - // - // There is a lot of opportunity for optimization here. For example we could - // statically determine that some messages have no submessages with maps and - // optimize this method away for those just by generating one extra static - // boolean per message type. - if (this.wrappers_) { - for (var fieldNumber in this.wrappers_) { - var val = this.wrappers_[fieldNumber]; - if (Array.isArray(val)) { - for (var i = 0; i < val.length; i++) { - if (val[i]) { - val[i].toArray(); - } - } - } else { - // Works for submessages and maps. - if (val) { - val.toArray(); - } - } - } - } -}; - - -/** - * Returns the internal array of this proto. - *

Note: If you use this array to construct a second proto, the content - * would then be partially shared between the two protos. - * @return {!Array} The proto represented as an array. - */ -jspb.Message.prototype.toArray = function() { - this.syncMapFields_(); - return this.array; -}; - - - -if (jspb.Message.GENERATE_TO_STRING) { - -/** - * Creates a string representation of the internal data array of this proto. - *

NOTE: This string is *not* suitable for use in server requests. - * @return {string} A string representation of this proto. - * @override - */ -jspb.Message.prototype.toString = function() { - this.syncMapFields_(); - return this.array.toString(); -}; - -} - -/** - * Gets the value of the extension field from the extended object. - * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to get. - * @return {T} The value of the field. - * @template T - */ -jspb.Message.prototype.getExtension = function(fieldInfo) { - if (!this.extensionObject_) { - return undefined; - } - if (!this.wrappers_) { - this.wrappers_ = {}; - } - var fieldNumber = fieldInfo.fieldIndex; - if (fieldInfo.isRepeated) { - if (fieldInfo.isMessageType()) { - if (!this.wrappers_[fieldNumber]) { - this.wrappers_[fieldNumber] = - goog.array.map(this.extensionObject_[fieldNumber] || [], - function(arr) { - return new fieldInfo.ctor(arr); - }); - } - return this.wrappers_[fieldNumber]; - } else { - return this.extensionObject_[fieldNumber]; - } - } else { - if (fieldInfo.isMessageType()) { - if (!this.wrappers_[fieldNumber] && this.extensionObject_[fieldNumber]) { - this.wrappers_[fieldNumber] = new fieldInfo.ctor( - /** @type {Array|undefined} */ ( - this.extensionObject_[fieldNumber])); - } - return this.wrappers_[fieldNumber]; - } else { - return this.extensionObject_[fieldNumber]; - } - } -}; - - -/** - * Sets the value of the extension field in the extended object. - * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set. - * @param {jspb.Message|string|Uint8Array|number|boolean|Array?} value The value - * to set. - * @return {THIS} For chaining - * @this {THIS} - * @template THIS - */ -jspb.Message.prototype.setExtension = function(fieldInfo, value) { - // Cast self, since the inferred THIS is unknown inside the function body. - // https://github.com/google/closure-compiler/issues/1411#issuecomment-232442220 - var self = /** @type {!jspb.Message} */ (this); - if (!self.wrappers_) { - self.wrappers_ = {}; - } - jspb.Message.maybeInitEmptyExtensionObject_(self); - var fieldNumber = fieldInfo.fieldIndex; - if (fieldInfo.isRepeated) { - value = value || []; - if (fieldInfo.isMessageType()) { - self.wrappers_[fieldNumber] = value; - self.extensionObject_[fieldNumber] = goog.array.map( - /** @type {!Array} */ (value), function(msg) { - return msg.toArray(); - }); - } else { - self.extensionObject_[fieldNumber] = value; - } - } else { - if (fieldInfo.isMessageType()) { - self.wrappers_[fieldNumber] = value; - self.extensionObject_[fieldNumber] = - value ? /** @type {!jspb.Message} */ (value).toArray() : value; - } else { - self.extensionObject_[fieldNumber] = value; - } - } - return self; -}; - - -/** - * Creates a difference object between two messages. - * - * The result will contain the top-level fields of m2 that differ from those of - * m1 at any level of nesting. No data is cloned, the result object will - * share its top-level elements with m2 (but not with m1). - * - * Note that repeated fields should not have null/undefined elements, but if - * they do, this operation will treat repeated fields of different length as - * the same if the only difference between them is due to trailing - * null/undefined values. - * - * @param {!jspb.Message} m1 The first message object. - * @param {!jspb.Message} m2 The second message object. - * @return {!jspb.Message} The difference returned as a proto message. - * Note that the returned message may be missing required fields. This is - * currently tolerated in Js, but would cause an error if you tried to - * send such a proto to the server. You can access the raw difference - * array with result.toArray(). - * @throws {Error} If the messages are responses with different types. - */ -jspb.Message.difference = function(m1, m2) { - if (!(m1 instanceof m2.constructor)) { - throw new Error('Messages have different types.'); - } - var arr1 = m1.toArray(); - var arr2 = m2.toArray(); - var res = []; - var start = 0; - var length = arr1.length > arr2.length ? arr1.length : arr2.length; - if (m1.getJsPbMessageId()) { - res[0] = m1.getJsPbMessageId(); - start = 1; - } - for (var i = start; i < length; i++) { - if (!jspb.Message.compareFields(arr1[i], arr2[i])) { - res[i] = arr2[i]; - } - } - return new m1.constructor(res); -}; - - -/** - * Tests whether two messages are equal. - * @param {jspb.Message|undefined} m1 The first message object. - * @param {jspb.Message|undefined} m2 The second message object. - * @return {boolean} true if both messages are null/undefined, or if both are - * of the same type and have the same field values. - */ -jspb.Message.equals = function(m1, m2) { - return m1 == m2 || (!!(m1 && m2) && (m1 instanceof m2.constructor) && - jspb.Message.compareFields(m1.toArray(), m2.toArray())); -}; - - -/** - * Compares two message extension fields recursively. - * @param {!Object} extension1 The first field. - * @param {!Object} extension2 The second field. - * @return {boolean} true if the extensions are null/undefined, or otherwise - * equal. - */ -jspb.Message.compareExtensions = function(extension1, extension2) { - extension1 = extension1 || {}; - extension2 = extension2 || {}; - - var keys = {}; - for (var name in extension1) { - keys[name] = 0; - } - for (var name in extension2) { - keys[name] = 0; - } - for (name in keys) { - if (!jspb.Message.compareFields(extension1[name], extension2[name])) { - return false; - } - } - return true; -}; - - -/** - * Compares two message fields recursively. - * @param {*} field1 The first field. - * @param {*} field2 The second field. - * @return {boolean} true if the fields are null/undefined, or otherwise equal. - */ -jspb.Message.compareFields = function(field1, field2) { - // If the fields are trivially equal, they're equal. - if (field1 == field2) return true; - - if (!goog.isObject(field1) || !goog.isObject(field2)) { - // NaN != NaN so we cover this case. - if ((typeof field1 === 'number' && isNaN(field1)) || - (typeof field2 === 'number' && isNaN(field2))) { - // One of the fields might be a string 'NaN'. - return String(field1) == String(field2); - } - // If the fields aren't trivially equal and one of them isn't an object, - // they can't possibly be equal. - return false; - } - - // We have two objects. If they're different types, they're not equal. - field1 = /** @type {!Object} */(field1); - field2 = /** @type {!Object} */(field2); - if (field1.constructor != field2.constructor) return false; - - // If both are Uint8Arrays, compare them element-by-element. - if (jspb.Message.SUPPORTS_UINT8ARRAY_ && field1.constructor === Uint8Array) { - var bytes1 = /** @type {!Uint8Array} */(field1); - var bytes2 = /** @type {!Uint8Array} */(field2); - if (bytes1.length != bytes2.length) return false; - for (var i = 0; i < bytes1.length; i++) { - if (bytes1[i] != bytes2[i]) return false; - } - return true; - } - - // If they're both Arrays, compare them element by element except for the - // optional extension objects at the end, which we compare separately. - if (field1.constructor === Array) { - var typedField1 = /** @type {!Array} */ (field1); - var typedField2 = /** @type {!Array} */ (field2); - var extension1 = undefined; - var extension2 = undefined; - - var length = Math.max(typedField1.length, typedField2.length); - for (var i = 0; i < length; i++) { - var val1 = typedField1[i]; - var val2 = typedField2[i]; - - if (val1 && (val1.constructor == Object)) { - goog.asserts.assert(extension1 === undefined); - goog.asserts.assert(i === typedField1.length - 1); - extension1 = val1; - val1 = undefined; - } - - if (val2 && (val2.constructor == Object)) { - goog.asserts.assert(extension2 === undefined); - goog.asserts.assert(i === typedField2.length - 1); - extension2 = val2; - val2 = undefined; - } - - if (!jspb.Message.compareFields(val1, val2)) { - return false; - } - } - - if (extension1 || extension2) { - extension1 = extension1 || {}; - extension2 = extension2 || {}; - return jspb.Message.compareExtensions(extension1, extension2); - } - - return true; - } - - // If they're both plain Objects (i.e. extensions), compare them as - // extensions. - if (field1.constructor === Object) { - return jspb.Message.compareExtensions(field1, field2); - } - - throw new Error('Invalid type in JSPB array'); -}; - - -/** - * Templated, type-safe cloneMessage definition. - * @return {THIS} - * @this {THIS} - * @template THIS - */ -jspb.Message.prototype.cloneMessage = function() { - return jspb.Message.cloneMessage(/** @type {!jspb.Message} */ (this)); -}; - -/** - * Alias clone to cloneMessage. goog.object.unsafeClone uses clone to - * efficiently copy objects. Without this alias, copying jspb messages comes - * with a large performance penalty. - * @return {THIS} - * @this {THIS} - * @template THIS - */ -jspb.Message.prototype.clone = function() { - return jspb.Message.cloneMessage(/** @type {!jspb.Message} */ (this)); -}; - -/** - * Static clone function. NOTE: A type-safe method called "cloneMessage" - * exists - * on each generated JsPb class. Do not call this function directly. - * @param {!jspb.Message} msg A message to clone. - * @return {!jspb.Message} A deep clone of the given message. - */ -jspb.Message.clone = function(msg) { - // Although we could include the wrappers, we leave them out here. - return jspb.Message.cloneMessage(msg); -}; - - -/** - * @param {!jspb.Message} msg A message to clone. - * @return {!jspb.Message} A deep clone of the given message. - * @protected - */ -jspb.Message.cloneMessage = function(msg) { - // Although we could include the wrappers, we leave them out here. - return new msg.constructor(jspb.Message.clone_(msg.toArray())); -}; - - -/** - * Takes 2 messages of the same type and copies the contents of the first - * message into the second. After this the 2 messages will equals in terms of - * value semantics but share no state. All data in the destination message will - * be overridden. - * - * @param {MESSAGE} fromMessage Message that will be copied into toMessage. - * @param {MESSAGE} toMessage Message which will receive a copy of fromMessage - * as its contents. - * @template MESSAGE - */ -jspb.Message.copyInto = function(fromMessage, toMessage) { - goog.asserts.assertInstanceof(fromMessage, jspb.Message); - goog.asserts.assertInstanceof(toMessage, jspb.Message); - goog.asserts.assert(fromMessage.constructor == toMessage.constructor, - 'Copy source and target message should have the same type.'); - var copyOfFrom = jspb.Message.clone(fromMessage); - - var to = toMessage.toArray(); - var from = copyOfFrom.toArray(); - - // Empty destination in case it has more values at the end of the array. - to.length = 0; - // and then copy everything from the new to the existing message. - for (var i = 0; i < from.length; i++) { - to[i] = from[i]; - } - - // This is either null or empty for a fresh copy. - toMessage.wrappers_ = copyOfFrom.wrappers_; - // Just a reference into the shared array. - toMessage.extensionObject_ = copyOfFrom.extensionObject_; -}; - - -/** - * Helper for cloning an internal JsPb object. - * @param {!Object} obj A JsPb object, eg, a field, to be cloned. - * @return {!Object} A clone of the input object. - * @private - */ -jspb.Message.clone_ = function(obj) { - var o; - if (Array.isArray(obj)) { - // Allocate array of correct size. - var clonedArray = new Array(obj.length); - // Use array iteration where possible because it is faster than for-in. - for (var i = 0; i < obj.length; i++) { - o = obj[i]; - if (o != null) { - // NOTE:redundant null check existing for NTI compatibility. - // see b/70515949 - clonedArray[i] = (typeof o == 'object') ? - jspb.Message.clone_(goog.asserts.assert(o)) : - o; - } - } - return clonedArray; - } - if (jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array) { - return new Uint8Array(obj); - } - var clone = {}; - for (var key in obj) { - o = obj[key]; - if (o != null) { - // NOTE:redundant null check existing for NTI compatibility. - // see b/70515949 - clone[key] = (typeof o == 'object') ? - jspb.Message.clone_(goog.asserts.assert(o)) : - o; - } - } - return clone; -}; - - -/** - * Registers a JsPb message type id with its constructor. - * @param {string} id The id for this type of message. - * @param {Function} constructor The message constructor. - */ -jspb.Message.registerMessageType = function(id, constructor) { - // This is needed so we can later access messageId directly on the constructor, - // otherwise it is not available due to 'property collapsing' by the compiler. - /** - * @suppress {strictMissingProperties} messageId is not defined on Function - */ - constructor.messageId = id; -}; -/** - * The extensions registered on MessageSet. This is a map of extension - * field number to field info object. This should be considered as a - * private API. - * - * This is similar to [jspb class name].extensions object for - * non-MessageSet. We special case MessageSet so that we do not need - * to goog.require MessageSet from classes that extends MessageSet. - * - * @type {!Object} - */ -jspb.Message.messageSetExtensions = {}; - -/** - * @type {!Object} - */ -jspb.Message.messageSetExtensionsBinary = {}; diff --git a/js/message_test.js b/js/message_test.js deleted file mode 100644 index 2a524deeb..000000000 --- a/js/message_test.js +++ /dev/null @@ -1,1111 +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. - -// Test suite is written using Jasmine -- see http://jasmine.github.io/ - -goog.setTestOnly(); - -goog.require('goog.testing.PropertyReplacer'); -goog.require('goog.testing.asserts'); -goog.require('goog.userAgent'); - -// CommonJS-LoadFromFile: google-protobuf jspb -goog.require('jspb.Message'); - -// CommonJS-LoadFromFile: test15_pb proto.jspb.filenametest.package1 -goog.require('proto.jspb.filenametest.package1.b'); - -// CommonJS-LoadFromFile: test14_pb proto.jspb.filenametest.package2 -goog.require('proto.jspb.filenametest.package2.TestMessage'); - -// CommonJS-LoadFromFile: test13_pb proto.jspb.filenametest.package1 -goog.require('proto.jspb.filenametest.package1.a'); -goog.require('proto.jspb.filenametest.package1.TestMessage'); - -// CommonJS-LoadFromFile: test12_pb proto.jspb.circulartest -goog.require('proto.jspb.circulartest.ExtensionContainingType1'); -goog.require('proto.jspb.circulartest.ExtensionContainingType2'); -goog.require('proto.jspb.circulartest.ExtensionField1'); -goog.require('proto.jspb.circulartest.ExtensionField2'); -goog.require('proto.jspb.circulartest.ExtensionField3'); -goog.require('proto.jspb.circulartest.MapField1'); -goog.require('proto.jspb.circulartest.MapField2'); -goog.require('proto.jspb.circulartest.MessageField1'); -goog.require('proto.jspb.circulartest.MessageField2'); -goog.require('proto.jspb.circulartest.NestedEnum1'); -goog.require('proto.jspb.circulartest.NestedEnum2'); -goog.require('proto.jspb.circulartest.NestedMessage1'); -goog.require('proto.jspb.circulartest.NestedMessage2'); -goog.require('proto.jspb.circulartest.RepeatedMessageField1'); -goog.require('proto.jspb.circulartest.RepeatedMessageField2'); - -// CommonJS-LoadFromFile: test11_pb proto.jspb.exttest.reverse -goog.require('proto.jspb.exttest.reverse.TestExtensionReverseOrderMessage1'); -goog.require('proto.jspb.exttest.reverse.TestExtensionReverseOrderMessage2'); -goog.require('proto.jspb.exttest.reverse.c'); - -// CommonJS-LoadFromFile: test8_pb proto.jspb.exttest.nested -goog.require('proto.jspb.exttest.nested.TestNestedExtensionsMessage'); -goog.require('proto.jspb.exttest.nested.TestOuterMessage'); - -// CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta -goog.require('proto.jspb.exttest.beta.floatingStrField'); - -// CommonJS-LoadFromFile: test3_pb proto.jspb.exttest -goog.require('proto.jspb.exttest.floatingMsgField'); - -// CommonJS-LoadFromFile: test4_pb proto.jspb.exttest -goog.require('proto.jspb.exttest.floatingMsgFieldTwo'); - -// CommonJS-LoadFromFile: test_pb proto.jspb.test -goog.require('proto.jspb.test.BooleanFields'); -goog.require('proto.jspb.test.CloneExtension'); -goog.require('proto.jspb.test.Complex'); -goog.require('proto.jspb.test.DefaultValues'); -goog.require('proto.jspb.test.Empty'); -goog.require('proto.jspb.test.EnumContainer'); -goog.require('proto.jspb.test.floatingMsgField'); -goog.require('proto.jspb.test.FloatingPointFields'); -goog.require('proto.jspb.test.floatingStrField'); -goog.require('proto.jspb.test.HasExtensions'); -goog.require('proto.jspb.test.IndirectExtension'); -goog.require('proto.jspb.test.IsExtension'); -goog.require('proto.jspb.test.OptionalFields'); -goog.require('proto.jspb.test.OuterEnum'); -goog.require('proto.jspb.test.OuterMessage.Complex'); -goog.require('proto.jspb.test.Simple1'); -goog.require('proto.jspb.test.Simple2'); -goog.require('proto.jspb.test.SpecialCases'); -goog.require('proto.jspb.test.TestClone'); -goog.require('proto.jspb.test.TestCloneExtension'); -goog.require('proto.jspb.test.TestEndsWithBytes'); -goog.require('proto.jspb.test.TestGroup'); -goog.require('proto.jspb.test.TestGroup1'); -goog.require('proto.jspb.test.TestLastFieldBeforePivot'); -goog.require('proto.jspb.test.TestMessageWithOneof'); -goog.require('proto.jspb.test.TestReservedNames'); -goog.require('proto.jspb.test.TestReservedNamesExtension'); - -// CommonJS-LoadFromFile: test2_pb proto.jspb.test -goog.require('proto.jspb.test.ExtensionMessage'); -goog.require('proto.jspb.test.TestExtensionsMessage'); - -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(); - - beforeEach(function() { - stubs.set(jspb.Message, 'SERIALIZE_EMPTY_TRAILING_FIELDS', false); - }); - - afterEach(function() { - stubs.reset(); - }); - - it('testEmptyProto', function() { - var empty1 = new proto.jspb.test.Empty([]); - var empty2 = new proto.jspb.test.Empty([]); - assertObjectEquals({}, empty1.toObject()); - assertObjectEquals('Message should not be corrupted:', empty2, empty1); - }); - - it('testTopLevelEnum', function() { - var response = new proto.jspb.test.EnumContainer([]); - response.setOuterEnum(proto.jspb.test.OuterEnum.FOO); - assertEquals(proto.jspb.test.OuterEnum.FOO, response.getOuterEnum()); - }); - - it('testByteStrings', function() { - var data = new proto.jspb.test.DefaultValues([]); - data.setBytesField('some_bytes'); - assertEquals('some_bytes', data.getBytesField()); - }); - - it('testComplexConversion', function() { - var data1 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , 1]; - var data2 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , 1]; - var foo = new proto.jspb.test.Complex(data1); - var bar = new proto.jspb.test.Complex(data2); - var result = foo.toObject(); - assertObjectEquals( - { - aString: 'a', - anOutOfOrderBool: true, - aNestedMessage: {anInt: 11}, - aRepeatedMessageList: [{anInt: 22}, {anInt: 33}], - aRepeatedStringList: ['s1', 's2'], - aFloatingPointField: undefined, - }, - 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'], - aFloatingPointField: undefined, - $jspbMessageInstance: foo - }, - result); - }); - - it('testMissingFields', function() { - var foo = new proto.jspb.test.Complex([ - undefined, undefined, undefined, [], undefined, undefined, undefined, - undefined - ]); - var bar = new proto.jspb.test.Complex([ - undefined, undefined, undefined, [], undefined, undefined, undefined, - undefined - ]); - var result = foo.toObject(); - assertObjectEquals( - { - aString: undefined, - anOutOfOrderBool: undefined, - aNestedMessage: {anInt: undefined}, - // Note: JsPb converts undefined repeated fields to empty arrays. - aRepeatedMessageList: [], - aRepeatedStringList: [], - aFloatingPointField: undefined, - }, - result); - }); - - it('testNestedComplexMessage', function() { - // Instantiate the message and set a unique field, just to ensure that we - // are not getting jspb.test.Complex instead. - var msg = new proto.jspb.test.OuterMessage.Complex(); - msg.setInnerComplexField(5); - }); - - it('testSpecialCases', function() { - // Note: Some property names are reserved in JavaScript. - // These names are converted to the Js property named pb_. - var special = new proto.jspb.test.SpecialCases( - ['normal', 'default', 'function', 'var']); - var result = special.toObject(); - assertObjectEquals( - { - normal: 'normal', - pb_default: 'default', - pb_function: 'function', - pb_var: 'var' - }, - result); - }); - - it('testDefaultValues', function() { - var defaultString = 'default<>\'"abc'; - var response = new proto.jspb.test.DefaultValues(); - - // Test toObject - var expectedObject = { - stringField: defaultString, - boolField: true, - intField: 11, - enumField: 13, - emptyField: '', - bytesField: 'bW9v' - }; - assertObjectEquals(expectedObject, response.toObject()); - - - // Test getters - response = new proto.jspb.test.DefaultValues(); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertEquals('', response.getEmptyField()); - assertEquals('bW9v', response.getBytesField()); - - function makeDefault(values) { - return new proto.jspb.test.DefaultValues(values); - } - - // Test with undefined values, - // Use push to workaround IE treating undefined array elements as holes. - response = makeDefault([undefined, undefined, undefined, undefined]); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - - // Test with null values, as would be returned by a JSON serializer. - response = makeDefault([null, null, null, null]); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - - // Test with false-like values. - response = makeDefault(['', false, 0, 0]); - assertEquals('', response.getStringField()); - assertEquals(false, response.getBoolField()); - assertEquals(true, response.getIntField() == 0); - assertEquals(true, response.getEnumField() == 0); - assertTrue(response.hasStringField()); - assertTrue(response.hasBoolField()); - assertTrue(response.hasIntField()); - assertTrue(response.hasEnumField()); - - // Test that clearing the values reverts them to the default state. - response = makeDefault(['blah', false, 111, 77]); - response.clearStringField(); - response.clearBoolField(); - response.clearIntField(); - response.clearEnumField(); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - - // Test that setFoo(null) clears the values. - response = makeDefault(['blah', false, 111, 77]); - response.setStringField(null); - response.setBoolField(null); - response.setIntField(undefined); - response.setEnumField(undefined); - assertEquals(defaultString, response.getStringField()); - assertEquals(true, response.getBoolField()); - assertEquals(11, response.getIntField()); - assertEquals(13, response.getEnumField()); - assertFalse(response.hasStringField()); - assertFalse(response.hasBoolField()); - assertFalse(response.hasIntField()); - assertFalse(response.hasEnumField()); - }); - - it('testEqualsSimple', function() { - var s1 = new proto.jspb.test.Simple1(['hi']); - assertTrue(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi']))); - assertFalse(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['bye']))); - var s1b = new proto.jspb.test.Simple1(['hi', ['hello']]); - assertTrue(jspb.Message.equals( - s1b, new proto.jspb.test.Simple1(['hi', ['hello']]))); - assertTrue(jspb.Message.equals(s1b, new proto.jspb.test.Simple1([ - 'hi', ['hello', undefined, undefined, undefined] - ]))); - assertFalse(jspb.Message.equals( - s1b, new proto.jspb.test.Simple1(['no', ['hello']]))); - // Test with messages of different types - var s2 = new proto.jspb.test.Simple2(['hi']); - assertFalse(jspb.Message.equals(s1, s2)); - }); - - it('testEquals_softComparison', function() { - var s1 = new proto.jspb.test.Simple1(['hi', [], null]); - assertTrue( - jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi', []]))); - - var s1b = new proto.jspb.test.Simple1(['hi', [], true]); - assertTrue( - jspb.Message.equals(s1b, new proto.jspb.test.Simple1(['hi', [], 1]))); - }); - - it('testEqualsComplex', function() { - var data1 = ['a', , , [, 11], [[, 22], [, 33]], , ['s1', 's2'], , 1]; - var data2 = ['a', , , [, 11], [[, 22], [, 34]], , ['s1', 's2'], , 1]; - var data3 = ['a', , , [, 11], [[, 22]], , ['s1', 's2'], , 1]; - var data4 = ['hi']; - var c1a = new proto.jspb.test.Complex(data1); - var c1b = new proto.jspb.test.Complex(data1); - var c2 = new proto.jspb.test.Complex(data2); - var c3 = new proto.jspb.test.Complex(data3); - var s1 = new proto.jspb.test.Simple1(data4); - - assertTrue(jspb.Message.equals(c1a, c1b)); - assertFalse(jspb.Message.equals(c1a, c2)); - assertFalse(jspb.Message.equals(c2, c3)); - assertFalse(jspb.Message.equals(c1a, s1)); - }); - - it('testEqualsExtensionsConstructed', function() { - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([]), - new proto.jspb.test.HasExtensions([{}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]))); - assertFalse(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions([, , , {100: [{200: 'a'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions([, , , {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', , , {100: [{200: 'a'}]}]))); - assertTrue(jspb.Message.equals( - new proto.jspb.test.HasExtensions(['hi', , , {100: [{200: 'a'}]}]), - new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]))); - }); - - it('testEqualsExtensionsUnconstructed', function() { - assertTrue(jspb.Message.compareFields([], [{}])); - assertTrue(jspb.Message.compareFields([, , , {}], [])); - assertTrue(jspb.Message.compareFields([, , , {}], [, , {}])); - assertTrue(jspb.Message.compareFields( - ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}])); - assertFalse(jspb.Message.compareFields( - ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'b'}]}])); - assertTrue(jspb.Message.compareFields( - [{100: [{200: 'a'}]}], [{100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - [{100: [{200: 'a'}]}], [, , , {100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - [, , , {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - ['hi', {100: [{200: 'a'}]}], ['hi', , , {100: [{200: 'a'}]}])); - assertTrue(jspb.Message.compareFields( - ['hi', , , {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}])); - }); - - it('testInitializeMessageWithLastFieldNull', function() { - // This tests for regression to bug http://b/117298778 - var msg = new proto.jspb.test.TestLastFieldBeforePivot([null]); - assertNotUndefined(msg.getLastFieldBeforePivot()); - }); - - it('testEqualsNonFinite', function() { - assertTrue(jspb.Message.compareFields(NaN, NaN)); - assertTrue(jspb.Message.compareFields(NaN, 'NaN')); - assertTrue(jspb.Message.compareFields('NaN', NaN)); - assertTrue(jspb.Message.compareFields(Infinity, Infinity)); - assertTrue(jspb.Message.compareFields(Infinity, 'Infinity')); - assertTrue(jspb.Message.compareFields('-Infinity', -Infinity)); - assertTrue(jspb.Message.compareFields([NaN], ['NaN'])); - assertFalse(jspb.Message.compareFields(undefined, NaN)); - assertFalse(jspb.Message.compareFields(NaN, undefined)); - }); - - it('testToMap', function() { - var p1 = new proto.jspb.test.Simple1(['k', ['v']]); - var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]); - var soymap = jspb.Message.toMap( - [p1, p2], proto.jspb.test.Simple1.prototype.getAString, - proto.jspb.test.Simple1.prototype.toObject); - assertEquals('k', soymap['k'].aString); - assertArrayEquals(['v'], soymap['k'].aRepeatedStringList); - var protomap = jspb.Message.toMap( - [p1, p2], proto.jspb.test.Simple1.prototype.getAString); - assertEquals('k', protomap['k'].getAString()); - assertArrayEquals(['v'], protomap['k'].getARepeatedStringList()); - }); - - it('testClone', function() { - var supportsUint8Array = - !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'); - var original = new proto.jspb.test.TestClone(); - original.setStr('v1'); - var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]); - var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]); - var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]); - original.setSimple1(simple1); - original.setSimple2List([simple2, simple3]); - var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123'; - original.setBytesField(bytes1); - var extension = new proto.jspb.test.CloneExtension(); - extension.setExt('e1'); - original.setExtension(proto.jspb.test.IsExtension.extField, extension); - var clone = original.clone(); - assertArrayEquals( - [ - 'v1', , ['x1', ['y1', 'z1']], , - [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1, , - {100: [, 'e1']} - ], - clone.toArray()); - clone.setStr('v2'); - var simple4 = new proto.jspb.test.Simple1(['a1', ['b1', 'c1']]); - var simple5 = new proto.jspb.test.Simple1(['a2', ['b2', 'c2']]); - var simple6 = new proto.jspb.test.Simple1(['a3', ['b3', 'c3']]); - clone.setSimple1(simple4); - clone.setSimple2List([simple5, simple6]); - if (supportsUint8Array) { - clone.getBytesField()[0] = 4; - assertObjectEquals(bytes1, original.getBytesField()); - } - var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456'; - clone.setBytesField(bytes2); - var newExtension = new proto.jspb.test.CloneExtension(); - newExtension.setExt('e2'); - clone.setExtension(proto.jspb.test.CloneExtension.extField, newExtension); - assertArrayEquals( - [ - 'v2', , ['a1', ['b1', 'c1']], , - [['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]], bytes2, , - {100: [, 'e2']} - ], - clone.toArray()); - assertArrayEquals( - [ - 'v1', , ['x1', ['y1', 'z1']], , - [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1, , - {100: [, 'e1']} - ], - original.toArray()); - }); - - it('testCopyInto', function() { - var supportsUint8Array = - !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10'); - var original = new proto.jspb.test.TestClone(); - original.setStr('v1'); - var dest = new proto.jspb.test.TestClone(); - dest.setStr('override'); - var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]); - var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]); - var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]); - var destSimple1 = new proto.jspb.test.Simple1(['ox1', ['oy1', 'oz1']]); - var destSimple2 = new proto.jspb.test.Simple1(['ox2', ['oy2', 'oz2']]); - var destSimple3 = new proto.jspb.test.Simple1(['ox3', ['oy3', 'oz3']]); - original.setSimple1(simple1); - original.setSimple2List([simple2, simple3]); - dest.setSimple1(destSimple1); - dest.setSimple2List([destSimple2, destSimple3]); - var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123'; - var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456'; - original.setBytesField(bytes1); - dest.setBytesField(bytes2); - var extension = new proto.jspb.test.CloneExtension(); - extension.setExt('e1'); - original.setExtension(proto.jspb.test.CloneExtension.extField, extension); - - jspb.Message.copyInto(original, dest); - assertArrayEquals(original.toArray(), dest.toArray()); - assertEquals('x1', dest.getSimple1().getAString()); - assertEquals( - 'e1', - dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt()); - dest.getSimple1().setAString('new value'); - assertNotEquals( - dest.getSimple1().getAString(), original.getSimple1().getAString()); - if (supportsUint8Array) { - dest.getBytesField()[0] = 7; - assertObjectEquals(bytes1, original.getBytesField()); - assertObjectEquals(new Uint8Array([7, 2, 3]), dest.getBytesField()); - } else { - dest.setBytesField('789'); - assertObjectEquals(bytes1, original.getBytesField()); - assertObjectEquals('789', dest.getBytesField()); - } - dest.getExtension(proto.jspb.test.CloneExtension.extField) - .setExt('new value'); - assertNotEquals( - dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt(), - original.getExtension(proto.jspb.test.CloneExtension.extField) - .getExt()); - }); - - it('testCopyInto_notSameType', function() { - var a = new proto.jspb.test.TestClone(); - var b = new proto.jspb.test.Simple1(['str', ['s1', 's2']]); - - var e = assertThrows(function() { - jspb.Message.copyInto(a, b); - }); - assertContains('should have the same type', e.message); - }); - - it('testExtensions', function() { - var extension1 = new proto.jspb.test.IsExtension(['ext1field']); - var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2']]); - var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); - extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1); - extendable.setExtension( - proto.jspb.test.IndirectExtension.simple, extension2); - extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy'); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedStrList, ['a', 'b']); - var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]); - var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2']]); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedSimpleList, [s1, s2]); - assertObjectEquals( - extension1, - extendable.getExtension(proto.jspb.test.IsExtension.extField)); - assertObjectEquals( - extension2, - extendable.getExtension(proto.jspb.test.IndirectExtension.simple)); - assertObjectEquals( - 'xyzzy', - extendable.getExtension(proto.jspb.test.IndirectExtension.str)); - assertObjectEquals( - ['a', 'b'], - extendable.getExtension( - proto.jspb.test.IndirectExtension.repeatedStrList)); - assertObjectEquals( - [s1, s2], - extendable.getExtension( - proto.jspb.test.IndirectExtension.repeatedSimpleList)); - // Not supported yet, but it should work... - extendable.setExtension(proto.jspb.test.IndirectExtension.simple, null); - assertNull( - extendable.getExtension(proto.jspb.test.IndirectExtension.simple)); - extendable.setExtension(proto.jspb.test.IndirectExtension.str, null); - assertNull(extendable.getExtension(proto.jspb.test.IndirectExtension.str)); - - - // Extension fields with jspb.ignore = true are ignored. - assertUndefined(proto.jspb.test.IndirectExtension['ignored']); - assertUndefined(proto.jspb.test.HasExtensions['ignoredFloating']); - }); - - it('testFloatingExtensions', function() { - // From an autogenerated container. - var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); - var extension = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]); - extendable.setExtension(proto.jspb.test.simple1, extension); - assertObjectEquals( - extension, extendable.getExtension(proto.jspb.test.simple1)); - - // From _lib mode. - extension = new proto.jspb.test.ExtensionMessage(['s1']); - extendable = new proto.jspb.test.TestExtensionsMessage([16]); - extendable.setExtension(proto.jspb.test.floatingMsgField, extension); - extendable.setExtension(proto.jspb.test.floatingStrField, 's2'); - assertObjectEquals( - extension, extendable.getExtension(proto.jspb.test.floatingMsgField)); - assertObjectEquals( - 's2', extendable.getExtension(proto.jspb.test.floatingStrField)); - assertNotUndefined(proto.jspb.exttest.floatingMsgField); - assertNotUndefined(proto.jspb.exttest.floatingMsgFieldTwo); - assertNotUndefined(proto.jspb.exttest.beta.floatingStrField); - }); - - it('testNestedExtensions', function() { - var extendable = - new proto.jspb.exttest.nested.TestNestedExtensionsMessage(); - var extension = - new proto.jspb.exttest.nested.TestOuterMessage.NestedExtensionMessage( - ['s1']); - extendable.setExtension( - proto.jspb.exttest.nested.TestOuterMessage.innerExtension, extension); - assertObjectEquals( - extension, - extendable.getExtension( - proto.jspb.exttest.nested.TestOuterMessage.innerExtension)); - }); - - it('testToObject_extendedObject', function() { - var extension1 = new proto.jspb.test.IsExtension(['ext1field']); - var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2'], true]); - var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']); - extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1); - extendable.setExtension( - proto.jspb.test.IndirectExtension.simple, extension2); - extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy'); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedStrList, ['a', 'b']); - var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2'], true]); - var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2'], false]); - extendable.setExtension( - proto.jspb.test.IndirectExtension.repeatedSimpleList, [s1, s2]); - assertObjectEquals( - { - str1: 'v1', - str2: 'v2', - str3: 'v3', - extField: {ext1: 'ext1field'}, - simple: { - aString: 'str', - aRepeatedStringList: ['s1', 's2'], - aBoolean: true - }, - str: 'xyzzy', - repeatedStrList: ['a', 'b'], - repeatedSimpleList: [ - {aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true}, - {aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false} - ] - }, - extendable.toObject()); - - // Now, with instances included. - assertObjectEquals( - { - str1: 'v1', - str2: 'v2', - str3: 'v3', - extField: { - ext1: 'ext1field', - $jspbMessageInstance: - extendable.getExtension(proto.jspb.test.IsExtension.extField) - }, - simple: { - aString: 'str', - aRepeatedStringList: ['s1', 's2'], - aBoolean: true, - $jspbMessageInstance: extendable.getExtension( - proto.jspb.test.IndirectExtension.simple) - }, - str: 'xyzzy', - repeatedStrList: ['a', 'b'], - repeatedSimpleList: [ - { - aString: 'foo', - aRepeatedStringList: ['s1', 's2'], - aBoolean: true, - $jspbMessageInstance: s1 - }, - { - aString: 'bar', - aRepeatedStringList: ['t1', 't2'], - aBoolean: false, - $jspbMessageInstance: s2 - } - ], - $jspbMessageInstance: extendable - }, - extendable.toObject(true /* opt_includeInstance */)); - }); - - it('testInitialization_emptyArray', function() { - var msg = new proto.jspb.test.HasExtensions([]); - assertArrayEquals([], msg.toArray()); - }); - - it('testInitialization_justExtensionObject', function() { - var msg = new proto.jspb.test.Empty([{1: 'hi'}]); - // The extensionObject is not moved from its original location. - assertArrayEquals([{1: 'hi'}], msg.toArray()); - }); - - it('testInitialization_incompleteList', function() { - var msg = new proto.jspb.test.Empty([1, {4: 'hi'}]); - // The extensionObject is not moved from its original location. - assertArrayEquals([1, {4: 'hi'}], msg.toArray()); - }); - - it('testInitialization_forwardCompatible', function() { - var msg = new proto.jspb.test.Empty([1, 2, 3, {1: 'hi'}]); - assertArrayEquals([1, 2, 3, {1: 'hi'}], msg.toArray()); - }); - - it('testExtendedMessageEnsureObject', - /** @suppress {visibility} */ function() { - var data = - new proto.jspb.test.HasExtensions(['str1', {'a_key': 'an_object'}]); - assertEquals('an_object', data.extensionObject_['a_key']); - }); - - it('testToObject_hasExtensionField', function() { - var data = - new proto.jspb.test.HasExtensions(['str1', {100: ['ext1'], 102: ''}]); - var obj = data.toObject(); - assertEquals('str1', obj.str1); - assertEquals('ext1', obj.extField.ext1); - assertEquals('', obj.str); - }); - - it('testGetExtension', function() { - var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]); - assertEquals('str1', data.getStr1()); - var extension = data.getExtension(proto.jspb.test.IsExtension.extField); - assertNotNull(extension); - assertEquals('ext1', extension.getExt1()); - }); - - it('testSetExtension', function() { - var data = new proto.jspb.test.HasExtensions(); - var extensionMessage = new proto.jspb.test.IsExtension(['is_extension']); - data.setExtension(proto.jspb.test.IsExtension.extField, extensionMessage); - var obj = data.toObject(); - assertNotNull(data.getExtension(proto.jspb.test.IsExtension.extField)); - assertEquals('is_extension', obj.extField.ext1); - }); - - /** - * Note that group is long deprecated, we only support it because JsPb has - * a goal of being able to generate JS classes for all proto descriptors. - */ - it('testGroups', function() { - var group = new proto.jspb.test.TestGroup(); - var someGroup = new proto.jspb.test.TestGroup.RepeatedGroup(); - someGroup.setId('g1'); - someGroup.setSomeBoolList([true, false]); - group.setRepeatedGroupList([someGroup]); - var groups = group.getRepeatedGroupList(); - assertEquals('g1', groups[0].getId()); - assertObjectEquals([true, false], groups[0].getSomeBoolList()); - assertObjectEquals( - {id: 'g1', someBoolList: [true, false]}, groups[0].toObject()); - assertObjectEquals( - { - repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}], - requiredGroup: {id: undefined}, - optionalGroup: undefined, - requiredSimple: {aRepeatedStringList: [], aString: undefined}, - optionalSimple: undefined, - id: undefined - }, - group.toObject()); - var group1 = new proto.jspb.test.TestGroup1(); - group1.setGroup(someGroup); - assertEquals(someGroup, group1.getGroup()); - }); - - it('testNonExtensionFieldsAfterExtensionRange', function() { - var data = [{'1': 'a_string'}]; - var message = new proto.jspb.test.Complex(data); - assertArrayEquals([], message.getARepeatedStringList()); - }); - - it('testReservedGetterNames', function() { - var message = new proto.jspb.test.TestReservedNames(); - message.setExtension$(11); - message.setExtension(proto.jspb.test.TestReservedNamesExtension.foo, 12); - assertEquals(11, message.getExtension$()); - assertEquals( - 12, - message.getExtension(proto.jspb.test.TestReservedNamesExtension.foo)); - assertObjectEquals({extension: 11, foo: 12}, message.toObject()); - }); - - it('testInitializeMessageWithUnsetOneof', function() { - var message = new proto.jspb.test.TestMessageWithOneof([]); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase - .PARTIAL_ONEOF_NOT_SET, - message.getPartialOneofCase()); - assertEquals( - proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase - .RECURSIVE_ONEOF_NOT_SET, - message.getRecursiveOneofCase()); - }); - - it('testUnsetsOneofCaseWhenFieldIsCleared', function() { - var message = new proto.jspb.test.TestMessageWithOneof; - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase - .PARTIAL_ONEOF_NOT_SET, - message.getPartialOneofCase()); - - message.setPone('hi'); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, - message.getPartialOneofCase()); - - message.clearPone(); - assertEquals( - proto.jspb.test.TestMessageWithOneof.PartialOneofCase - .PARTIAL_ONEOF_NOT_SET, - message.getPartialOneofCase()); - }); - - it('testFloatingPointFieldsSupportNan', function() { - var assertNan = function(x) { - assertTrue( - 'Expected ' + x + ' (' + goog.typeOf(x) + ') to be NaN.', - typeof x === 'number' && isNaN(x)); - }; - - var message = new proto.jspb.test.FloatingPointFields([ - 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN', 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN' - ]); - assertNan(message.getOptionalFloatField()); - assertNan(message.getRequiredFloatField()); - assertNan(message.getRepeatedFloatFieldList()[0]); - assertNan(message.getRepeatedFloatFieldList()[1]); - assertNan(message.getDefaultFloatField()); - assertNan(message.getOptionalDoubleField()); - assertNan(message.getRequiredDoubleField()); - assertNan(message.getRepeatedDoubleFieldList()[0]); - assertNan(message.getRepeatedDoubleFieldList()[1]); - assertNan(message.getDefaultDoubleField()); - }); - - it('testFloatingPointsAreConvertedFromStringInput', function() { - var assertInf = function(x) { - assertTrue( - 'Expected ' + x + ' (' + goog.typeOf(x) + ') to be Infinity.', - x === Infinity); - }; - var message = new proto.jspb.test.FloatingPointFields([ - Infinity, 'Infinity', ['Infinity', Infinity], 'Infinity', 'Infinity', - 'Infinity', ['Infinity', Infinity], 'Infinity' - ]); - assertInf(message.getOptionalFloatField()); - assertInf(message.getRequiredFloatField()); - assertInf(message.getRepeatedFloatFieldList()[0]); - assertInf(message.getRepeatedFloatFieldList()[1]); - assertInf(message.getDefaultFloatField()); - assertInf(message.getOptionalDoubleField()); - assertInf(message.getRequiredDoubleField()); - assertInf(message.getRepeatedDoubleFieldList()[0]); - assertInf(message.getRepeatedDoubleFieldList()[1]); - assertInf(message.getDefaultDoubleField()); - }); - - it('testBooleansAreConvertedFromNumberInput', function() { - var assertBooleanFieldTrue = function(x) { - assertTrue( - 'Expected ' + x + ' (' + goog.typeOf(x) + ') to be True.', - x === true); - }; - var message = new proto.jspb.test.BooleanFields([1, 1, [true, 1]]); - assertBooleanFieldTrue(message.getOptionalBooleanField()); - assertBooleanFieldTrue(message.getRequiredBooleanField()); - assertBooleanFieldTrue(message.getRepeatedBooleanFieldList()[0]); - assertBooleanFieldTrue(message.getRepeatedBooleanFieldList()[1]); - assertBooleanFieldTrue(message.getDefaultBooleanField()); - - var assertBooleanFieldFalse = function(x) { - assertTrue( - 'Expected ' + x + ' (' + goog.typeOf(x) + ') to be False.', - x === false); - }; - message = new proto.jspb.test.BooleanFields([0, 0, [0, 0]]); - assertBooleanFieldFalse(message.getOptionalBooleanField()); - assertBooleanFieldFalse(message.getRequiredBooleanField()); - assertBooleanFieldFalse(message.getRepeatedBooleanFieldList()[0]); - assertBooleanFieldFalse(message.getRepeatedBooleanFieldList()[1]); - }); - - it('testExtensionReverseOrder', function() { - var message2 = - new proto.jspb.exttest.reverse.TestExtensionReverseOrderMessage2; - - message2.setExtension( - proto.jspb.exttest.reverse.TestExtensionReverseOrderMessage1.a, 233); - message2.setExtension( - proto.jspb.exttest.reverse.TestExtensionReverseOrderMessage1 - .TestExtensionReverseOrderNestedMessage1.b, - 2333); - message2.setExtension(proto.jspb.exttest.reverse.c, 23333); - - assertEquals( - 233, - message2.getExtension( - proto.jspb.exttest.reverse.TestExtensionReverseOrderMessage1.a)); - assertEquals( - 2333, - message2.getExtension( - proto.jspb.exttest.reverse.TestExtensionReverseOrderMessage1 - .TestExtensionReverseOrderNestedMessage1.b)); - assertEquals(23333, message2.getExtension(proto.jspb.exttest.reverse.c)); - }); - - it('testCircularDepsBaseOnMessageField', function() { - var nestMessage1 = new proto.jspb.circulartest.MessageField1; - var nestMessage2 = new proto.jspb.circulartest.MessageField2; - var message1 = new proto.jspb.circulartest.MessageField1; - var message2 = new proto.jspb.circulartest.MessageField2; - - nestMessage1.setA(1); - nestMessage2.setA(2); - message1.setB(nestMessage2); - message2.setB(nestMessage1); - - - assertEquals(2, message1.getB().getA()); - assertEquals(1, message2.getB().getA()); - }); - - - it('testCircularDepsBaseOnRepeatedMessageField', function() { - var nestMessage1 = new proto.jspb.circulartest.RepeatedMessageField1; - var nestMessage2 = new proto.jspb.circulartest.RepeatedMessageField2; - var message1 = new proto.jspb.circulartest.RepeatedMessageField1; - var message2 = new proto.jspb.circulartest.RepeatedMessageField2; - - nestMessage1.setA(1); - nestMessage2.setA(2); - message1.setB(nestMessage2); - message2.addB(nestMessage1); - - - assertEquals(2, message1.getB().getA()); - assertEquals(1, message2.getBList()[0].getA()); - }); - - it('testCircularDepsBaseOnMapField', function() { - var nestMessage1 = new proto.jspb.circulartest.MapField1; - var nestMessage2 = new proto.jspb.circulartest.MapField2; - var message1 = new proto.jspb.circulartest.MapField1; - var message2 = new proto.jspb.circulartest.MapField2; - - nestMessage1.setA(1); - nestMessage2.setA(2); - message1.setB(nestMessage2); - message2.getBMap().set(1, nestMessage1); - - - assertEquals(2, message1.getB().getA()); - assertEquals(1, message2.getBMap().get(1).getA()); - }); - - it('testCircularDepsBaseOnNestedMessage', function() { - var nestMessage1 = - new proto.jspb.circulartest.NestedMessage1.NestedNestedMessage; - var nestMessage2 = new proto.jspb.circulartest.NestedMessage2; - var message1 = new proto.jspb.circulartest.NestedMessage1; - var message2 = new proto.jspb.circulartest.NestedMessage2; - - nestMessage1.setA(1); - nestMessage2.setA(2); - message1.setB(nestMessage2); - message2.setB(nestMessage1); - - - assertEquals(2, message1.getB().getA()); - assertEquals(1, message2.getB().getA()); - }); - - it('testCircularDepsBaseOnNestedEnum', function() { - var nestMessage2 = new proto.jspb.circulartest.NestedEnum2; - var message1 = new proto.jspb.circulartest.NestedEnum1; - var message2 = new proto.jspb.circulartest.NestedEnum2; - - nestMessage2.setA(2); - message1.setB(nestMessage2); - message2.setB(proto.jspb.circulartest.NestedEnum1.NestedNestedEnum.VALUE_1); - - - assertEquals(2, message1.getB().getA()); - assertEquals( - proto.jspb.circulartest.NestedEnum1.NestedNestedEnum.VALUE_1, - message2.getB()); - }); - - it('testCircularDepsBaseOnExtensionContainingType', function() { - var nestMessage2 = new proto.jspb.circulartest.ExtensionContainingType2; - var message1 = new proto.jspb.circulartest.ExtensionContainingType1; - - nestMessage2.setA(2); - message1.setB(nestMessage2); - message1.setExtension( - proto.jspb.circulartest.ExtensionContainingType2.c, 1); - - - assertEquals(2, message1.getB().getA()); - assertEquals( - 1, - message1.getExtension( - proto.jspb.circulartest.ExtensionContainingType2.c)); - }); - - it('testCircularDepsBaseOnExtensionField', function() { - var nestMessage2 = new proto.jspb.circulartest.ExtensionField2; - var message1 = new proto.jspb.circulartest.ExtensionField1; - var message3 = new proto.jspb.circulartest.ExtensionField3; - - nestMessage2.setA(2); - message1.setB(nestMessage2); - message3.setExtension(proto.jspb.circulartest.ExtensionField2.c, message1); - - - assertEquals( - 2, - message3.getExtension(proto.jspb.circulartest.ExtensionField2.c) - .getB() - .getA()); - }); - - it('testSameMessageNameOuputs', function() { - var package1Message = new proto.jspb.filenametest.package1.TestMessage; - var package2Message = new proto.jspb.filenametest.package2.TestMessage; - - package1Message.setExtension(proto.jspb.filenametest.package1.a, 10); - package1Message.setExtension(proto.jspb.filenametest.package1.b, 11); - package2Message.setA(12); - - assertEquals( - 10, package1Message.getExtension(proto.jspb.filenametest.package1.a)); - assertEquals( - 11, package1Message.getExtension(proto.jspb.filenametest.package1.b)); - assertEquals(12, package2Message.getA()); - }); - - - it('testMessageWithLargeFieldNumbers', function() { - var message = new proto.jspb.test.MessageWithLargeFieldNumbers; - - message.setAString('string'); - assertEquals('string', message.getAString()); - - message.setAString(''); - assertEquals('', message.getAString()); - - message.setAString('new string'); - assertEquals('new string', message.getAString()); - - message.setABoolean(true); - assertEquals(true, message.getABoolean()); - - message.setABoolean(false); - assertEquals(false, message.getABoolean()); - - message.setABoolean(true); - assertEquals(true, message.getABoolean()); - - message.setAInt(42); - assertEquals(42, message.getAInt()); - - message.setAInt(0); - assertEquals(0, message.getAInt()); - - message.setAInt(42); - assertEquals(42, message.getAInt()); - }); -}); diff --git a/js/node_loader.js b/js/node_loader.js deleted file mode 100644 index 79211adda..000000000 --- a/js/node_loader.js +++ /dev/null @@ -1,49 +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. - -/** - * @fileoverview Loader that handles goog.require() for Node.JS. - */ - -var oldLoader = goog.global.CLOSURE_IMPORT_SCRIPT; - -goog.global.CLOSURE_IMPORT_SCRIPT = function(src, opt_sourceText) { - if (opt_sourceText === undefined) { - try { - // Load from the current directory. - require("./" + src); - return true; - } catch (e) { - // Fall back to the Closure loader. - } - } - - return oldLoader(src, opt_sourceText); -}; diff --git a/js/package.json b/js/package.json deleted file mode 100644 index f3c0e724f..000000000 --- a/js/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "google-protobuf", - "version": "3.20.1", - "description": "Protocol Buffers for JavaScript", - "main": "google-protobuf.js", - "files": [ - "google" - ], - "dependencies": {}, - "devDependencies": { - "glob": "~7.1.4", - "google-closure-compiler": "~20190819.0.0", - "google-closure-deps": "^20210406.0.0", - "google-closure-library": "~20190819.0.0", - "gulp": "~4.0.2", - "jasmine": "~3.4.0" - }, - "scripts": { - "test": "node ./node_modules/gulp/bin/gulp.js test" - }, - "repository": { - "type": "git", - "url": "https://github.com/protocolbuffers/protobuf/tree/main/js" - }, - "author": "Google Protocol Buffers Team", - "license": "BSD-3-Clause" -} diff --git a/js/proto3_test.js b/js/proto3_test.js deleted file mode 100644 index 8de157524..000000000 --- a/js/proto3_test.js +++ /dev/null @@ -1,478 +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. - -goog.require('goog.crypt.base64'); -goog.require('goog.testing.asserts'); -// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test -goog.require('proto.jspb.test.ForeignMessage'); -// CommonJS-LoadFromFile: proto3_test_pb proto.jspb.test -goog.require('proto.jspb.test.Proto3Enum'); -goog.require('proto.jspb.test.TestProto3'); -// CommonJS-LoadFromFile: google/protobuf/any_pb proto.google.protobuf -goog.require('proto.google.protobuf.Any'); -// CommonJS-LoadFromFile: google/protobuf/timestamp_pb proto.google.protobuf -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); - - -/** - * Helper: compare a bytes field to an expected value - * @param {Uint8Array|string} arr - * @param {Uint8Array} expected - * @return {boolean} - */ -function bytesCompare(arr, expected) { - if (typeof arr === 'string') { - arr = goog.crypt.base64.decodeStringToUint8Array(arr); - } - if (arr.length != expected.length) { - return false; - } - for (var i = 0; i < arr.length; i++) { - if (arr[i] != expected[i]) { - return false; - } - } - return true; -} - - -describe('proto3Test', function() { - /** - * Test default values don't affect equality test. - */ - it('testEqualsProto3', function() { - var msg1 = new proto.jspb.test.TestProto3(); - var msg2 = new proto.jspb.test.TestProto3(); - msg2.setSingularString(''); - - assertTrue(jspb.Message.equals(msg1, msg2)); - }); - - - /** - * Test setting when a field has default semantics. - */ - it('testSetProto3ToValueAndBackToDefault', function() { - var msg = new proto.jspb.test.TestProto3(); - - // Setting should work normally. - msg.setSingularString('optionalString'); - assertEquals(msg.getSingularString(), 'optionalString'); - - // Clearing should work too ... - msg.setSingularString(''); - assertEquals(msg.getSingularString(), ''); - - // ... and shouldn't affect the equality with a brand new message. - assertTrue(jspb.Message.equals(msg, new proto.jspb.test.TestProto3())); - }); - - /** - * Test defaults for proto3 message fields. - */ - it('testProto3FieldDefaults', function() { - var msg = new proto.jspb.test.TestProto3(); - - assertEquals(msg.getSingularInt32(), 0); - assertEquals(msg.getSingularInt64(), 0); - assertEquals(msg.getSingularUint32(), 0); - assertEquals(msg.getSingularUint64(), 0); - assertEquals(msg.getSingularSint32(), 0); - assertEquals(msg.getSingularSint64(), 0); - assertEquals(msg.getSingularFixed32(), 0); - assertEquals(msg.getSingularFixed64(), 0); - assertEquals(msg.getSingularSfixed32(), 0); - assertEquals(msg.getSingularSfixed64(), 0); - assertEquals(msg.getSingularFloat(), 0); - assertEquals(msg.getSingularDouble(), 0); - assertEquals(msg.getSingularString(), ''); - - // TODO(b/26173701): when we change bytes fields default getter to return - // Uint8Array, we'll want to switch this assertion to match the u8 case. - assertEquals(typeof msg.getSingularBytes(), 'string'); - assertEquals(msg.getSingularBytes_asU8() instanceof Uint8Array, true); - assertEquals(typeof msg.getSingularBytes_asB64(), 'string'); - assertEquals(msg.getSingularBytes().length, 0); - assertEquals(msg.getSingularBytes_asU8().length, 0); - assertEquals(msg.getSingularBytes_asB64(), ''); - - assertEquals( - msg.getSingularForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_FOO); - assertEquals(msg.getSingularForeignMessage(), undefined); - assertEquals(msg.getSingularForeignMessage(), undefined); - - assertEquals(msg.getRepeatedInt32List().length, 0); - assertEquals(msg.getRepeatedInt64List().length, 0); - assertEquals(msg.getRepeatedUint32List().length, 0); - assertEquals(msg.getRepeatedUint64List().length, 0); - assertEquals(msg.getRepeatedSint32List().length, 0); - assertEquals(msg.getRepeatedSint64List().length, 0); - assertEquals(msg.getRepeatedFixed32List().length, 0); - assertEquals(msg.getRepeatedFixed64List().length, 0); - assertEquals(msg.getRepeatedSfixed32List().length, 0); - assertEquals(msg.getRepeatedSfixed64List().length, 0); - assertEquals(msg.getRepeatedFloatList().length, 0); - assertEquals(msg.getRepeatedDoubleList().length, 0); - assertEquals(msg.getRepeatedStringList().length, 0); - assertEquals(msg.getRepeatedBytesList().length, 0); - assertEquals(msg.getRepeatedForeignEnumList().length, 0); - assertEquals(msg.getRepeatedForeignMessageList().length, 0); - }); - - /** - * Test presence for proto3 optional fields. - */ - it('testProto3Optional', function() { - var msg = new proto.jspb.test.TestProto3(); - - assertEquals(msg.getOptionalInt32(), 0); - assertEquals(msg.getOptionalInt64(), 0); - assertEquals(msg.getOptionalUint32(), 0); - assertEquals(msg.getOptionalUint64(), 0); - assertEquals(msg.getOptionalSint32(), 0); - assertEquals(msg.getOptionalSint64(), 0); - assertEquals(msg.getOptionalFixed32(), 0); - assertEquals(msg.getOptionalFixed64(), 0); - assertEquals(msg.getOptionalSfixed32(), 0); - assertEquals(msg.getOptionalSfixed64(), 0); - assertEquals(msg.getOptionalFloat(), 0); - assertEquals(msg.getOptionalDouble(), 0); - assertEquals(msg.getOptionalString(), ''); - - // TODO(b/26173701): when we change bytes fields default getter to return - // Uint8Array, we'll want to switch this assertion to match the u8 case. - assertEquals(typeof msg.getOptionalBytes(), 'string'); - assertEquals(msg.getOptionalBytes_asU8() instanceof Uint8Array, true); - assertEquals(typeof msg.getOptionalBytes_asB64(), 'string'); - assertEquals(msg.getOptionalBytes().length, 0); - assertEquals(msg.getOptionalBytes_asU8().length, 0); - assertEquals(msg.getOptionalBytes_asB64(), ''); - - assertEquals( - msg.getOptionalForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_FOO); - assertEquals(msg.getOptionalForeignMessage(), undefined); - assertEquals(msg.getOptionalForeignMessage(), undefined); - - // Serializing an empty proto yields the empty string. - assertEquals(msg.serializeBinary().length, 0); - - // Values start as unset, but can be explicitly set even to default values - // like 0. - assertFalse(msg.hasOptionalInt32()); - msg.setOptionalInt32(0); - assertTrue(msg.hasOptionalInt32()); - - assertFalse(msg.hasOptionalInt64()); - msg.setOptionalInt64(0); - assertTrue(msg.hasOptionalInt64()); - - assertFalse(msg.hasOptionalString()); - msg.setOptionalString(''); - assertTrue(msg.hasOptionalString()); - - // Now the proto will have a non-zero size, even though its values are 0. - var serialized = msg.serializeBinary(); - assertNotEquals(serialized.length, 0); - - var msg2 = proto.jspb.test.TestProto3.deserializeBinary(serialized); - assertTrue(msg2.hasOptionalInt32()); - assertTrue(msg2.hasOptionalInt64()); - assertTrue(msg2.hasOptionalString()); - - // We can clear fields to go back to empty. - msg2.clearOptionalInt32(); - assertFalse(msg2.hasOptionalInt32()); - - msg2.clearOptionalString(); - assertFalse(msg2.hasOptionalString()); - }); - - /** - * Test that all fields can be set ,and read via a serialization roundtrip. - */ - it('testProto3FieldSetGet', function() { - var msg = new proto.jspb.test.TestProto3(); - - msg.setSingularInt32(-42); - msg.setSingularInt64(-0x7fffffff00000000); - msg.setSingularUint32(0x80000000); - msg.setSingularUint64(0xf000000000000000); - msg.setSingularSint32(-100); - msg.setSingularSint64(-0x8000000000000000); - msg.setSingularFixed32(1234); - msg.setSingularFixed64(0x1234567800000000); - msg.setSingularSfixed32(-1234); - msg.setSingularSfixed64(-0x1234567800000000); - msg.setSingularFloat(1.5); - msg.setSingularDouble(-1.5); - msg.setSingularBool(true); - msg.setSingularString('hello world'); - msg.setSingularBytes(BYTES); - var submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(16); - msg.setSingularForeignMessage(submsg); - msg.setSingularForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); - - msg.setRepeatedInt32List([-42]); - msg.setRepeatedInt64List([-0x7fffffff00000000]); - msg.setRepeatedUint32List([0x80000000]); - msg.setRepeatedUint64List([0xf000000000000000]); - msg.setRepeatedSint32List([-100]); - msg.setRepeatedSint64List([-0x8000000000000000]); - msg.setRepeatedFixed32List([1234]); - msg.setRepeatedFixed64List([0x1234567800000000]); - msg.setRepeatedSfixed32List([-1234]); - msg.setRepeatedSfixed64List([-0x1234567800000000]); - msg.setRepeatedFloatList([1.5]); - msg.setRepeatedDoubleList([-1.5]); - msg.setRepeatedBoolList([true]); - msg.setRepeatedStringList(['hello world']); - msg.setRepeatedBytesList([BYTES]); - submsg = new proto.jspb.test.ForeignMessage(); - submsg.setC(1000); - msg.setRepeatedForeignMessageList([submsg]); - msg.setRepeatedForeignEnumList([proto.jspb.test.Proto3Enum.PROTO3_BAR]); - - msg.setOneofString('asdf'); - - var serialized = msg.serializeBinary(); - msg = proto.jspb.test.TestProto3.deserializeBinary(serialized); - - assertEquals(msg.getSingularInt32(), -42); - assertEquals(msg.getSingularInt64(), -0x7fffffff00000000); - assertEquals(msg.getSingularUint32(), 0x80000000); - assertEquals(msg.getSingularUint64(), 0xf000000000000000); - assertEquals(msg.getSingularSint32(), -100); - assertEquals(msg.getSingularSint64(), -0x8000000000000000); - assertEquals(msg.getSingularFixed32(), 1234); - assertEquals(msg.getSingularFixed64(), 0x1234567800000000); - assertEquals(msg.getSingularSfixed32(), -1234); - assertEquals(msg.getSingularSfixed64(), -0x1234567800000000); - assertEquals(msg.getSingularFloat(), 1.5); - assertEquals(msg.getSingularDouble(), -1.5); - assertEquals(msg.getSingularBool(), true); - assertEquals(msg.getSingularString(), 'hello world'); - assertEquals(true, bytesCompare(msg.getSingularBytes(), BYTES)); - assertEquals(msg.getSingularForeignMessage().getC(), 16); - assertEquals( - msg.getSingularForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_BAR); - - assertElementsEquals(msg.getRepeatedInt32List(), [-42]); - assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]); - assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]); - assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]); - assertElementsEquals(msg.getRepeatedSint32List(), [-100]); - assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]); - assertElementsEquals(msg.getRepeatedFixed32List(), [1234]); - assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]); - assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]); - assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]); - assertElementsEquals(msg.getRepeatedFloatList(), [1.5]); - assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]); - assertElementsEquals(msg.getRepeatedBoolList(), [true]); - assertElementsEquals(msg.getRepeatedStringList(), ['hello world']); - assertEquals(msg.getRepeatedBytesList().length, 1); - assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES)); - assertEquals(msg.getRepeatedForeignMessageList().length, 1); - assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000); - assertElementsEquals( - msg.getRepeatedForeignEnumList(), - [proto.jspb.test.Proto3Enum.PROTO3_BAR]); - - assertEquals(msg.getOneofString(), 'asdf'); - }); - - - /** - * Test that oneofs continue to have a notion of field presence. - */ - it('testOneofs', function() { - // Default instance. - var msg = new proto.jspb.test.TestProto3(); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes(), ''); - - assertFalse(msg.hasOneofUint32()); - assertFalse(msg.hasOneofForeignMessage()); - assertFalse(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - // Integer field. - msg.setOneofUint32(42); - assertEquals(msg.getOneofUint32(), 42); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes(), ''); - - assertTrue(msg.hasOneofUint32()); - assertFalse(msg.hasOneofForeignMessage()); - assertFalse(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - // Sub-message field. - var submsg = new proto.jspb.test.ForeignMessage(); - msg.setOneofForeignMessage(submsg); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), submsg); - assertEquals(msg.getOneofString(), ''); - assertEquals(msg.getOneofBytes(), ''); - - assertFalse(msg.hasOneofUint32()); - assertTrue(msg.hasOneofForeignMessage()); - assertFalse(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - // String field. - msg.setOneofString('hello'); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), 'hello'); - assertEquals(msg.getOneofBytes(), ''); - - assertFalse(msg.hasOneofUint32()); - assertFalse(msg.hasOneofForeignMessage()); - assertTrue(msg.hasOneofString()); - assertFalse(msg.hasOneofBytes()); - - // Bytes field. - msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); - assertEquals(msg.getOneofUint32(), 0); - assertEquals(msg.getOneofForeignMessage(), undefined); - assertEquals(msg.getOneofString(), ''); - assertEquals( - msg.getOneofBytes_asB64(), - goog.crypt.base64.encodeString('\u00FF\u00FF')); - - assertFalse(msg.hasOneofUint32()); - assertFalse(msg.hasOneofForeignMessage()); - assertFalse(msg.hasOneofString()); - assertTrue(msg.hasOneofBytes()); - }); - - - /** - * Test that "default"-valued primitive fields are not emitted on the wire. - */ - it('testNoSerializeDefaults', function() { - var msg = new proto.jspb.test.TestProto3(); - - // Set each primitive to a non-default value, then back to its default, to - // ensure that the serialization is actually checking the value and not just - // whether it has ever been set. - msg.setSingularInt32(42); - msg.setSingularInt32(0); - msg.setSingularDouble(3.14); - msg.setSingularDouble(0.0); - msg.setSingularBool(true); - msg.setSingularBool(false); - msg.setSingularString('hello world'); - msg.setSingularString(''); - msg.setSingularBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); - msg.setSingularBytes(''); - msg.setSingularForeignMessage(new proto.jspb.test.ForeignMessage()); - msg.setSingularForeignMessage(null); - msg.setSingularForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); - msg.setSingularForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO); - msg.setOneofUint32(32); - msg.clearOneofUint32(); - - - var serialized = msg.serializeBinary(); - assertEquals(0, serialized.length); - }); - - /** - * Test that base64 string and Uint8Array are interchangeable in bytes fields. - */ - it('testBytesFieldsInterop', function() { - var msg = new proto.jspb.test.TestProto3(); - // Set as a base64 string and check all the getters work. - msg.setSingularBytes(BYTES_B64); - assertTrue(bytesCompare(msg.getSingularBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getSingularBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getSingularBytes(), BYTES)); - - // Test binary serialize round trip doesn't break it. - msg = proto.jspb.test.TestProto3.deserializeBinary(msg.serializeBinary()); - assertTrue(bytesCompare(msg.getSingularBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getSingularBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getSingularBytes(), BYTES)); - - msg = new proto.jspb.test.TestProto3(); - // Set as a Uint8Array and check all the getters work. - msg.setSingularBytes(BYTES); - assertTrue(bytesCompare(msg.getSingularBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getSingularBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getSingularBytes(), BYTES)); - }); - - it('testTimestampWellKnownType', function() { - var msg = new proto.google.protobuf.Timestamp(); - msg.fromDate(new Date(123456789)); - assertEquals(123456, msg.getSeconds()); - assertEquals(789000000, msg.getNanos()); - var date = msg.toDate(); - assertEquals(123456789, date.getTime()); - var anotherMsg = proto.google.protobuf.Timestamp.fromDate(date); - assertEquals(msg.getSeconds(), anotherMsg.getSeconds()); - assertEquals(msg.getNanos(), anotherMsg.getNanos()); - }); - - it('testStructWellKnownType', function() { - var jsObj = { - 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'] - }; - - var struct = proto.google.protobuf.Struct.fromJavaScript(jsObj); - var jsObj2 = struct.toJavaScript(); - - 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(4, jsObj2.complicatedKey[0].xyz.abc[1]); - }); -}); diff --git a/js/proto3_test.proto b/js/proto3_test.proto deleted file mode 100644 index 14f104ef5..000000000 --- a/js/proto3_test.proto +++ /dev/null @@ -1,108 +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. - -syntax = "proto3"; - -package jspb.test; - -import "testbinary.proto"; - -message TestProto3 { - int32 singular_int32 = 1; - int64 singular_int64 = 2; - uint32 singular_uint32 = 3; - uint64 singular_uint64 = 4; - sint32 singular_sint32 = 5; - sint64 singular_sint64 = 6; - fixed32 singular_fixed32 = 7; - fixed64 singular_fixed64 = 8; - sfixed32 singular_sfixed32 = 9; - sfixed64 singular_sfixed64 = 10; - float singular_float = 11; - double singular_double = 12; - bool singular_bool = 13; - string singular_string = 14; - bytes singular_bytes = 15; - - ForeignMessage singular_foreign_message = 19; - Proto3Enum singular_foreign_enum = 22; - - optional int32 optional_int32 = 121; - optional int64 optional_int64 = 122; - optional uint32 optional_uint32 = 123; - optional uint64 optional_uint64 = 124; - optional sint32 optional_sint32 = 125; - optional sint64 optional_sint64 = 126; - optional fixed32 optional_fixed32 = 127; - optional fixed64 optional_fixed64 = 128; - optional sfixed32 optional_sfixed32 = 129; - optional sfixed64 optional_sfixed64 = 130; - optional float optional_float = 131; - optional double optional_double = 132; - optional bool optional_bool = 133; - optional string optional_string = 134; - optional bytes optional_bytes = 135; - - optional ForeignMessage optional_foreign_message = 136; - optional Proto3Enum optional_foreign_enum = 137; - - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated ForeignMessage repeated_foreign_message = 49; - repeated Proto3Enum repeated_foreign_enum = 52; - - oneof oneof_field { - uint32 oneof_uint32 = 111; - ForeignMessage oneof_foreign_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } -} - -enum Proto3Enum { - PROTO3_FOO = 0; - PROTO3_BAR = 1; - PROTO3_BAZ = 2; - MSG_PROTO3_BAH = 3; -} diff --git a/js/test.proto b/js/test.proto deleted file mode 100644 index 7c0578a4f..000000000 --- a/js/test.proto +++ /dev/null @@ -1,322 +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. - -// LINT: LEGACY_NAMES -// Author: mwr@google.com (Mark Rawling) - -syntax = "proto2"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -import "google/protobuf/descriptor.proto"; - -package jspb.test; - -message Empty {} - -enum OuterEnum { - FOO = 1; - BAR = 2; -} - -message EnumContainer { - optional OuterEnum outer_enum = 1; -} - -message Simple1 { - required string a_string = 1; - repeated string a_repeated_string = 2; - optional bool a_boolean = 3; -} - -// A message that differs from Simple1 only by name -message Simple2 { - required string a_string = 1; - repeated string a_repeated_string = 2; -} - -message SpecialCases { - required string normal = 1; - // Examples of Js reserved names that are converted to pb_. - required string default = 2; - required string function = 3; - required string var = 4; -} - -message OptionalFields { - message Nested { - optional int32 an_int = 1; - } - optional string a_string = 1; - required bool a_bool = 2; - optional Nested a_nested_message = 3; - repeated Nested a_repeated_message = 4; - repeated string a_repeated_string = 5; -} - -message HasExtensions { - optional string str1 = 1; - optional string str2 = 2; - optional string str3 = 3; - extensions 10 to max; -} - -message Complex { - message Nested { - required int32 an_int = 2; - } - required string a_string = 1; - optional bool an_out_of_order_bool = 9; - optional Nested a_nested_message = 4; - repeated Nested a_repeated_message = 5; - repeated string a_repeated_string = 7; - optional double a_floating_point_field = 10; -} - -message OuterMessage { - // Make sure this doesn't conflict with the other Complex message. - message Complex { - optional int32 inner_complex_field = 1; - } -} - -message MineField { - // document.cookie is a banned property in a couple of conformance check - // configs at Google. Verify that having a field called cookie doesn't confuse - // the compiler and break the build. - optional string cookie = 1; -} - -message IsExtension { - extend HasExtensions { - optional IsExtension ext_field = 100; - } - optional string ext1 = 1; - - // Extensions of proto2 Descriptor messages will be ignored. - extend google.protobuf.EnumOptions { - optional string simple_option = 42113038; - } -} - -message IndirectExtension { - extend HasExtensions { - optional Simple1 simple = 101; - optional string str = 102; - repeated string repeated_str = 103; - repeated Simple1 repeated_simple = 104; - } -} - -extend HasExtensions { - optional Simple1 simple1 = 105; -} - -message DefaultValues { - enum Enum { - E1 = 13; - E2 = 77; - } - optional string string_field = 1 [default = "default<>\'\"abc"]; - optional bool bool_field = 2 [default = true]; - optional int64 int_field = 3 [default = 11]; - optional Enum enum_field = 4 [default = E1]; - optional string empty_field = 6 [default = ""]; - optional bytes bytes_field = 8 - [default = "moo"]; // Base64 encoding is "bW9v" -} - -message FloatingPointFields { - optional float optional_float_field = 1; - required float required_float_field = 2; - repeated float repeated_float_field = 3; - optional float default_float_field = 4 [default = 2.0]; - optional double optional_double_field = 5; - required double required_double_field = 6; - repeated double repeated_double_field = 7; - optional double default_double_field = 8 [default = 2.0]; -} - -message BooleanFields { - optional bool optional_boolean_field = 1; - required bool required_boolean_field = 2; - repeated bool repeated_boolean_field = 3; - optional bool default_boolean_field = 4 [default = true]; -} - -message TestClone { - optional string str = 1; - optional Simple1 simple1 = 3; - repeated Simple1 simple2 = 5; - optional bytes bytes_field = 6; - optional string unused = 7; - extensions 10 to max; -} - -message TestCloneExtension { - extend TestClone { - optional TestCloneExtension low_ext = 11; - } - optional int32 f = 1; -} - -message CloneExtension { - extend TestClone { - optional CloneExtension ext_field = 100; - } - optional string ext = 2; -} - -message TestGroup { - repeated group RepeatedGroup = 1 { - required string id = 1; - repeated bool some_bool = 2; - } - required group RequiredGroup = 2 { - required string id = 1; - } - optional group OptionalGroup = 3 { - required string id = 1; - } - optional string id = 4; - required Simple2 required_simple = 5; - optional Simple2 optional_simple = 6; -} - -message TestGroup1 { - optional TestGroup.RepeatedGroup group = 1; -} - -message TestReservedNames { - optional int32 extension = 1; - extensions 10 to max; -} - -message TestReservedNamesExtension { - extend TestReservedNames { - optional int32 foo = 10; - } -} - -message TestMessageWithOneof { - - oneof partial_oneof { - string pone = 3; - string pthree = 5; - } - - oneof recursive_oneof { - TestMessageWithOneof rone = 6; - string rtwo = 7; - } - - optional bool normal_field = 8; - repeated string repeated_field = 9; - - oneof default_oneof_a { - int32 aone = 10 [default = 1234]; - int32 atwo = 11; - } - - oneof default_oneof_b { - int32 bone = 12; - int32 btwo = 13 [default = 1234]; - } -} - -message TestEndsWithBytes { - optional int32 value = 1; - optional bytes data = 2; -} - -// This message is for testing extension handling doesn't affect fields before -// pivot. Don't add new field to this message. See b/117298778 for more detail. -message TestLastFieldBeforePivot { - optional int32 last_field_before_pivot = 1; - extensions 100 to max; -} - -extend TestLastFieldBeforePivot { - optional int32 extend_test_last_field_before_pivot_field = 101; -} - - -message Int64Types { - optional int64 int64_normal = 1 [jstype = JS_NORMAL]; - optional sint64 int64_string = 2 [jstype = JS_STRING]; - optional uint64 int64_number = 3 [jstype = JS_NUMBER]; - -} - -message TestMapFieldsNoBinary { - map map_string_string = 1; - map map_string_int32 = 2; - map map_string_int64 = 3; - map map_string_bool = 4; - map map_string_double = 5; - map map_string_enum = 6; - map map_string_msg = 7; - - map map_int32_string = 8; - map map_int64_string = 9; - map map_bool_string = 10; - - optional TestMapFieldsNoBinary test_map_fields = 11; - map map_string_testmapfields = 12; -} - -enum MapValueEnumNoBinary { - MAP_VALUE_FOO_NOBINARY = 0; - MAP_VALUE_BAR_NOBINARY = 1; - MAP_VALUE_BAZ_NOBINARY = 2; -} - -message MapValueMessageNoBinary { - optional int32 foo = 1; -} - -message Deeply { - message Nested { - message Message { - optional int32 count = 1; - } - } -} - - - -enum TestAllowAliasEnum { - option allow_alias = true; - - TEST_ALLOW_ALIAS_DEFAULT = 0; - VALUE1 = 1; - value1 = 1; -} diff --git a/js/test10.proto b/js/test10.proto deleted file mode 100644 index 9fa5256c5..000000000 --- a/js/test10.proto +++ /dev/null @@ -1,39 +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. - -syntax = "proto3"; - -package jspb.exttest.strict.ten; - -import "test9.proto"; - -message Simple10 { - jspb.exttest.strict.nine.Simple9 a = 1; -} diff --git a/js/test11.proto b/js/test11.proto deleted file mode 100644 index ae65a46a7..000000000 --- a/js/test11.proto +++ /dev/null @@ -1,52 +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. - -syntax = "proto2"; - -package jspb.exttest.reverse; - -message TestExtensionReverseOrderMessage1 { - extend TestExtensionReverseOrderMessage2 { - optional int32 a = 1; - } - message TestExtensionReverseOrderNestedMessage1 { - extend TestExtensionReverseOrderMessage2 { - optional int32 b = 2; - } - } -} - -extend TestExtensionReverseOrderMessage2 { - optional int32 c = 3; -} - -message TestExtensionReverseOrderMessage2 { - extensions 1 to 100; -} diff --git a/js/test12.proto b/js/test12.proto deleted file mode 100644 index 4ece1d063..000000000 --- a/js/test12.proto +++ /dev/null @@ -1,119 +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. - -syntax = "proto2"; - - -package jspb.circulartest; - -message MessageField1 { - optional int32 a = 1; - optional MessageField2 b = 2; -} - -message MessageField2 { - optional int32 a = 1; - optional MessageField1 b = 2; -} - - -message RepeatedMessageField1 { - optional int32 a = 1; - optional RepeatedMessageField2 b = 2; -} - -message RepeatedMessageField2 { - optional int32 a = 1; - repeated RepeatedMessageField1 b = 2; -} - -message MapField1 { - optional int32 a = 1; - optional MapField2 b = 2; -} - -message MapField2 { - optional int32 a = 1; - map b = 2; -} - -message NestedMessage1 { - optional NestedMessage2 b = 2; - message NestedNestedMessage { - optional int32 a = 1; - } -} - -message NestedMessage2 { - optional int32 a = 1; - optional NestedMessage1.NestedNestedMessage b = 2; -} - -message NestedEnum1 { - optional NestedEnum2 b = 2; - enum NestedNestedEnum { - UNDEFINED = 0; - VALUE_1 = 1; - } -} - -message NestedEnum2 { - optional int32 a = 1; - optional NestedEnum1.NestedNestedEnum b = 2; -} - -message ExtensionContainingType1 { - optional int32 a = 1; - optional ExtensionContainingType2 b = 2; - extensions 99 to 100; -} - -message ExtensionContainingType2 { - optional int32 a = 1; - extend ExtensionContainingType1 { - optional int32 c = 99; - } -} - -message ExtensionField1 { - optional int32 a = 1; - optional ExtensionField2 b = 2; -} - -message ExtensionField2 { - optional int32 a = 1; - extend ExtensionField3 { - optional ExtensionField1 c = 99; - } -} - -message ExtensionField3 { - extensions 99 to 100; -} diff --git a/js/test13.proto b/js/test13.proto deleted file mode 100644 index b9895d87a..000000000 --- a/js/test13.proto +++ /dev/null @@ -1,70 +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. - -syntax = "proto2"; - -package jspb.filenametest.package1; - -message TestMessage { - extensions 1 to 100; -} - -extend TestMessage { - optional int32 a = 1; -} - -enum TestEnum { - VALUE_0 = 0; - VALUE_1 = 1; -} - -message TestLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName1 { - optional TestLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName2 - a = 1; - optional int32 b = 2; -} - -message TestLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName2 { - optional TestLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName3 - a = 1; - optional int32 b = 2; -} - -message TestLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName3 { - optional TestLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName4 - a = 1; - optional int32 b = 2; -} - -message TestLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName4 { - optional TestLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName1 - a = 1; - optional int32 b = 2; -} diff --git a/js/test14.proto b/js/test14.proto deleted file mode 100644 index 2447eb140..000000000 --- a/js/test14.proto +++ /dev/null @@ -1,43 +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. - -syntax = "proto2"; - -package jspb.filenametest.package2; - -message TestMessage { - optional int32 a = 1; -} - -enum TestEnum { - VALUE_0 = 0; - VALUE_1 = 1; - VALUE_2 = 2; -} diff --git a/js/test15.proto b/js/test15.proto deleted file mode 100644 index b48111651..000000000 --- a/js/test15.proto +++ /dev/null @@ -1,39 +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. - -syntax = "proto2"; - -package jspb.filenametest.package1; - -import "test13.proto"; - -extend TestMessage { - optional int32 b = 2; -} diff --git a/js/test2.proto b/js/test2.proto deleted file mode 100644 index e9457e7c7..000000000 --- a/js/test2.proto +++ /dev/null @@ -1,60 +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. - -syntax = "proto2"; - -package jspb.test; - -import "test.proto"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -message TestExtensionsMessage { - optional int32 intfield = 1; - extensions 100 to max; -} - -message ExtensionMessage { - extend TestExtensionsMessage { - optional ExtensionMessage ext_field = 100; - } - optional string ext1 = 1; -} - -// Floating extensions are only supported when generating a _lib.js library. -extend TestExtensionsMessage { - optional ExtensionMessage floating_msg_field = 101; - optional string floating_str_field = 102; -} - -message ForeignNestedFieldMessage { - optional Deeply.Nested.Message deeply_nested_message = 1; -} diff --git a/js/test3.proto b/js/test3.proto deleted file mode 100644 index 3fa037dfb..000000000 --- a/js/test3.proto +++ /dev/null @@ -1,53 +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. - -syntax = "proto2"; - -package jspb.exttest; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -message TestExtensionsMessage { - optional int32 intfield = 1; - extensions 100 to max; -} - -message ExtensionMessage { - extend TestExtensionsMessage { - optional ExtensionMessage ext_field = 100; - } - optional string ext1 = 1; -} - -extend TestExtensionsMessage { - optional ExtensionMessage floating_msg_field = 101; - optional string floating_str_field = 102; -} diff --git a/js/test4.proto b/js/test4.proto deleted file mode 100644 index c3c834241..000000000 --- a/js/test4.proto +++ /dev/null @@ -1,42 +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. - -syntax = "proto2"; - -package jspb.exttest; - -import "test3.proto"; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -extend TestExtensionsMessage { - optional ExtensionMessage floating_msg_field_two = 103; -} diff --git a/js/test5.proto b/js/test5.proto deleted file mode 100644 index db297213a..000000000 --- a/js/test5.proto +++ /dev/null @@ -1,44 +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. - -syntax = "proto2"; - -package jspb.exttest.beta; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -message TestBetaExtensionsMessage { - extensions 100 to max; -} - -extend TestBetaExtensionsMessage { - optional string floating_str_field = 101; -} diff --git a/js/test8.proto b/js/test8.proto deleted file mode 100644 index 7dbb6eff1..000000000 --- a/js/test8.proto +++ /dev/null @@ -1,50 +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. - -syntax = "proto2"; - -package jspb.exttest.nested; - -option java_package = "com.google.apps.jspb.proto"; -option java_multiple_files = true; - -message TestNestedExtensionsMessage { - optional int32 intfield = 1; - extensions 100 to max; -} - -message TestOuterMessage { - message NestedExtensionMessage { - optional string ext1 = 1; - } - extend TestNestedExtensionsMessage { - optional NestedExtensionMessage inner_extension = 100; - } -} diff --git a/js/test9.proto b/js/test9.proto deleted file mode 100644 index 9f6808528..000000000 --- a/js/test9.proto +++ /dev/null @@ -1,39 +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. - -syntax = "proto2"; - -package jspb.exttest.strict.nine; - -message Simple9 { - required string a_string = 1; - repeated string a_repeated_string = 2; - optional bool a_boolean = 3; -} diff --git a/js/test_bootstrap.js b/js/test_bootstrap.js deleted file mode 100644 index 9d00a1c43..000000000 --- a/js/test_bootstrap.js +++ /dev/null @@ -1,41 +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. - -/** - * @fileoverview Sets flags for uncompiled JSUnit tests. - */ - -/** - * Set uncompiled flags. - */ -var CLOSURE_DEFINES = { - // Enable the fromObject method on the message class. - 'jspb.Message.GENERATE_FROM_OBJECT': true -}; diff --git a/js/testbinary.proto b/js/testbinary.proto deleted file mode 100644 index a14128564..000000000 --- a/js/testbinary.proto +++ /dev/null @@ -1,294 +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. - -// LINT: ALLOW_GROUPS - -syntax = "proto2"; - - -package jspb.test; - -// These types are borrowed from `unittest.proto` in the protobuf tree. We want -// to ensure that the binary-format support will handle all field types -// properly. -message TestAllTypes { - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - optional group OptionalGroup = 16 { - optional int32 a = 17; - } - - optional ForeignMessage optional_foreign_message = 19; - optional ForeignEnum optional_foreign_enum = 22; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } - - repeated ForeignMessage repeated_foreign_message = 49; - repeated ForeignEnum repeated_foreign_enum = 52; - - // Packed repeated - repeated int32 packed_repeated_int32 = 61 [packed = true]; - repeated int64 packed_repeated_int64 = 62 [packed = true]; - repeated uint32 packed_repeated_uint32 = 63 [packed = true]; - repeated uint64 packed_repeated_uint64 = 64 [packed = true]; - repeated sint32 packed_repeated_sint32 = 65 [packed = true]; - repeated sint64 packed_repeated_sint64 = 66 [packed = true]; - repeated fixed32 packed_repeated_fixed32 = 67 [packed = true]; - repeated fixed64 packed_repeated_fixed64 = 68 [packed = true]; - repeated sfixed32 packed_repeated_sfixed32 = 69 [packed = true]; - repeated sfixed64 packed_repeated_sfixed64 = 70 [packed = true]; - repeated float packed_repeated_float = 71 [packed = true]; - repeated double packed_repeated_double = 72 [packed = true]; - repeated bool packed_repeated_bool = 73 [packed = true]; - - oneof oneof_field { - uint32 oneof_uint32 = 111; - ForeignMessage oneof_foreign_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - } - -} - -message ForeignMessage { - optional int32 c = 1; -} - -enum ForeignEnum { - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -message TestExtendable { - extensions 1 to max; -} - -message ExtendsWithMessage { - extend TestExtendable { - optional ExtendsWithMessage optional_extension = 19; - repeated ExtendsWithMessage repeated_extension = 49; - } - optional int32 foo = 1; -} - -extend TestExtendable { - optional int32 extend_optional_int32 = 1; - optional int64 extend_optional_int64 = 2; - optional uint32 extend_optional_uint32 = 3; - optional uint64 extend_optional_uint64 = 4; - optional sint32 extend_optional_sint32 = 5; - optional sint64 extend_optional_sint64 = 6; - optional fixed32 extend_optional_fixed32 = 7; - optional fixed64 extend_optional_fixed64 = 8; - optional sfixed32 extend_optional_sfixed32 = 9; - optional sfixed64 extend_optional_sfixed64 = 10; - optional float extend_optional_float = 11; - optional double extend_optional_double = 12; - optional bool extend_optional_bool = 13; - optional string extend_optional_string = 14; - optional bytes extend_optional_bytes = 15; - optional ForeignEnum extend_optional_foreign_enum = 22; - - repeated int32 extend_repeated_int32 = 31; - repeated int64 extend_repeated_int64 = 32; - repeated uint32 extend_repeated_uint32 = 33; - repeated uint64 extend_repeated_uint64 = 34; - repeated sint32 extend_repeated_sint32 = 35; - repeated sint64 extend_repeated_sint64 = 36; - repeated fixed32 extend_repeated_fixed32 = 37; - repeated fixed64 extend_repeated_fixed64 = 38; - repeated sfixed32 extend_repeated_sfixed32 = 39; - repeated sfixed64 extend_repeated_sfixed64 = 40; - repeated float extend_repeated_float = 41; - repeated double extend_repeated_double = 42; - repeated bool extend_repeated_bool = 43; - repeated string extend_repeated_string = 44; - repeated bytes extend_repeated_bytes = 45; - repeated ForeignEnum extend_repeated_foreign_enum = 52; - - repeated int32 extend_packed_repeated_int32 = 61 [packed = true]; - repeated int64 extend_packed_repeated_int64 = 62 [packed = true]; - repeated uint32 extend_packed_repeated_uint32 = 63 [packed = true]; - repeated uint64 extend_packed_repeated_uint64 = 64 [packed = true]; - repeated sint32 extend_packed_repeated_sint32 = 65 [packed = true]; - repeated sint64 extend_packed_repeated_sint64 = 66 [packed = true]; - repeated fixed32 extend_packed_repeated_fixed32 = 67 [packed = true]; - repeated fixed64 extend_packed_repeated_fixed64 = 68 [packed = true]; - repeated sfixed32 extend_packed_repeated_sfixed32 = 69 [packed = true]; - repeated sfixed64 extend_packed_repeated_sfixed64 = 70 [packed = true]; - repeated float extend_packed_repeated_float = 71 [packed = true]; - repeated double extend_packed_repeated_double = 72 [packed = true]; - repeated bool extend_packed_repeated_bool = 73 [packed = true]; - repeated ForeignEnum extend_packed_repeated_foreign_enum = 82 [packed = true]; - -} - -message TestMapFields { - map map_string_string = 1; - map map_string_int32 = 2; - map map_string_int64 = 3; - map map_string_bool = 4; - map map_string_double = 5; - map map_string_enum = 6; - map map_string_msg = 7; - - map map_int32_string = 8; - map map_int64_string = 9; - map map_bool_string = 10; - - optional TestMapFields test_map_fields = 11; - map map_string_testmapfields = 12; -} - -// These proto are 'mock map' entries to test the above map deserializing with -// undefined keys. Make sure TestMapFieldsOptionalKeys is written to be -// deserialized by TestMapFields -message MapEntryOptionalKeysStringKey { - optional string key = 1; - optional string value = 2; -} - -message MapEntryOptionalKeysInt32Key { - optional int32 key = 1; - optional string value = 2; -} - -message MapEntryOptionalKeysInt64Key { - optional int64 key = 1; - optional string value = 2; -} - -message MapEntryOptionalKeysBoolKey { - optional bool key = 1; - optional string value = 2; -} - -message TestMapFieldsOptionalKeys { - optional MapEntryOptionalKeysStringKey map_string_string = 1; - optional MapEntryOptionalKeysInt32Key map_int32_string = 8; - optional MapEntryOptionalKeysInt64Key map_int64_string = 9; - optional MapEntryOptionalKeysBoolKey map_bool_string = 10; -} - -// End mock-map entries - -// These proto are 'mock map' entries to test the above map deserializing with -// undefined values. Make sure TestMapFieldsOptionalValues is written to be -// deserialized by TestMapFields -message MapEntryOptionalValuesStringValue { - optional string key = 1; - optional string value = 2; -} - -message MapEntryOptionalValuesInt32Value { - optional string key = 1; - optional int32 value = 2; -} - -message MapEntryOptionalValuesInt64Value { - optional string key = 1; - optional int64 value = 2; -} - -message MapEntryOptionalValuesBoolValue { - optional string key = 1; - optional bool value = 2; -} - -message MapEntryOptionalValuesDoubleValue { - optional string key = 1; - optional double value = 2; -} - -message MapEntryOptionalValuesEnumValue { - optional string key = 1; - optional MapValueEnum value = 2; -} - -message MapEntryOptionalValuesMessageValue { - optional string key = 1; - optional MapValueMessage value = 2; -} - -message TestMapFieldsOptionalValues { - optional MapEntryOptionalValuesStringValue map_string_string = 1; - optional MapEntryOptionalValuesInt32Value map_string_int32 = 2; - optional MapEntryOptionalValuesInt64Value map_string_int64 = 3; - optional MapEntryOptionalValuesBoolValue map_string_bool = 4; - optional MapEntryOptionalValuesDoubleValue map_string_double = 5; - optional MapEntryOptionalValuesEnumValue map_string_enum = 6; - optional MapEntryOptionalValuesMessageValue map_string_msg = 7; -} - -// End mock-map entries - -enum MapValueEnum { - MAP_VALUE_FOO = 0; - MAP_VALUE_BAR = 1; - MAP_VALUE_BAZ = 2; -} - -message MapValueMessage { - optional int32 foo = 1; -} - diff --git a/js/testempty.proto b/js/testempty.proto deleted file mode 100644 index 6161753fd..000000000 --- a/js/testempty.proto +++ /dev/null @@ -1,33 +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. - -syntax = "proto2"; - -package javatests.com.google.apps.jspb; diff --git a/js/testlargenumbers.proto b/js/testlargenumbers.proto deleted file mode 100644 index 47aef3579..000000000 --- a/js/testlargenumbers.proto +++ /dev/null @@ -1,40 +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. - -syntax = "proto3"; - -package jspb.test; - - -message MessageWithLargeFieldNumbers { - string a_string = 1; - bool a_boolean = 900; - int32 a_int = 5000; -} diff --git a/kokoro/linux/aarch64/javascript_build_and_run_tests_with_qemu_aarch64.sh b/kokoro/linux/aarch64/javascript_build_and_run_tests_with_qemu_aarch64.sh deleted file mode 100755 index c4eb7d8f0..000000000 --- a/kokoro/linux/aarch64/javascript_build_and_run_tests_with_qemu_aarch64.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -set -ex - -# install the same version of node as in /tests.sh -NODE_VERSION=node-v12.16.3-linux-arm64 -NODE_TGZ="$NODE_VERSION.tar.gz" -pushd /tmp -curl -OL https://nodejs.org/dist/v12.16.3/$NODE_TGZ -tar zxvf $NODE_TGZ -export PATH=$PATH:`pwd`/$NODE_VERSION/bin -popd - -# go to the repo root -cd $(dirname $0)/../../.. - -cd js -npm install -npm test diff --git a/kokoro/linux/aarch64/test_javascript_aarch64.sh b/kokoro/linux/aarch64/test_javascript_aarch64.sh deleted file mode 100755 index 3156e6e9c..000000000 --- a/kokoro/linux/aarch64/test_javascript_aarch64.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -set -ex - -# go to the repo root -cd $(dirname $0)/../../.. - -if [[ -t 0 ]]; then - DOCKER_TTY_ARGS="-it" -else - # The input device on kokoro is not a TTY, so -it does not work. - DOCKER_TTY_ARGS= -fi - -# crosscompile protoc as we will later need it for the javascript build. -# we build it under the dockcross/manylinux2014-aarch64 image so that the resulting protoc binary is compatible -# with a wide range of linux distros (including any docker images we will use later to build and test javascript) -kokoro/linux/aarch64/dockcross_helpers/run_dockcross_manylinux2014_aarch64.sh kokoro/linux/aarch64/protoc_crosscompile_aarch64.sh - -# use an actual aarch64 docker image (with a real aarch64 nodejs) to run build & test protobuf javascript under an emulator -# * mount the protobuf root as /work to be able to access the crosscompiled files -# * to avoid running the process inside docker as root (which can pollute the workspace with files owned by root), we force -# running under current user's UID and GID. To be able to do that, we need to provide a home directory for the user -# otherwise the UID would be homeless under the docker container and pip install wouldn't work. For simplicity, -# we just run map the user's home to a throwaway temporary directory -# Note that the docker image used for running the tests is arm64v8/openjdk, not arm64v8/node -# This is because some of the node tests require java to be available and adding node -# binary distribution into a java image is easier than vice versa. -docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work arm64v8/openjdk:11-jdk-buster kokoro/linux/aarch64/javascript_build_and_run_tests_with_qemu_aarch64.sh diff --git a/kokoro/linux/dockerfile/test/javascript/Dockerfile b/kokoro/linux/dockerfile/test/javascript/Dockerfile deleted file mode 100644 index 184828fb5..000000000 --- a/kokoro/linux/dockerfile/test/javascript/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM ubuntu:latest - -RUN apt-get update && apt-get install -y gnupg - -# Install dependencies. We start with the basic ones require to build protoc -# and the C++ build -RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ - 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 - - -################## -# Javascript dependencies. -# We need to set these environment variables so that the Docker build does not -# have to ask for this information while it is installing the tzdata package. -RUN DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles" \ - apt-get install -y \ - # -- For javascript and closure compiler -- \ - npm \ - default-jre \ - python diff --git a/kokoro/linux/javascript/build.sh b/kokoro/linux/javascript/build.sh deleted file mode 100755 index e1e172310..000000000 --- a/kokoro/linux/javascript/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/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/javascript -export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh -export OUTPUT_DIR=testoutput -export TEST_SET="javascript" -./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/javascript/continuous.cfg b/kokoro/linux/javascript/continuous.cfg deleted file mode 100644 index b42f522fe..000000000 --- a/kokoro/linux/javascript/continuous.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/javascript/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/javascript/presubmit.cfg b/kokoro/linux/javascript/presubmit.cfg deleted file mode 100644 index b42f522fe..000000000 --- a/kokoro/linux/javascript/presubmit.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/javascript/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/javascript_aarch64/build.sh b/kokoro/linux/javascript_aarch64/build.sh deleted file mode 100755 index dd9f8af86..000000000 --- a/kokoro/linux/javascript_aarch64/build.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# -# This is the top-level script we give to Kokoro as the entry point for -# running the "continuous" and "presubmit" jobs. - -set -ex - -# Change to repo root -cd $(dirname $0)/../../.. - -# Initialize any submodules. -git submodule update --init --recursive - -kokoro/linux/aarch64/qemu_helpers/prepare_qemu.sh - -kokoro/linux/aarch64/test_javascript_aarch64.sh diff --git a/kokoro/linux/javascript_aarch64/continuous.cfg b/kokoro/linux/javascript_aarch64/continuous.cfg deleted file mode 100644 index 947bc759d..000000000 --- a/kokoro/linux/javascript_aarch64/continuous.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/javascript_aarch64/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/javascript_aarch64/presubmit.cfg b/kokoro/linux/javascript_aarch64/presubmit.cfg deleted file mode 100644 index 947bc759d..000000000 --- a/kokoro/linux/javascript_aarch64/presubmit.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/javascript_aarch64/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/macos/javascript/build.sh b/kokoro/macos/javascript/build.sh deleted file mode 100755 index 016832a32..000000000 --- a/kokoro/macos/javascript/build.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# -# Build file to set up and run tests - -# Change to repo root -cd $(dirname $0)/../../.. - -# Prepare worker environment to run tests -source kokoro/macos/prepare_build_macos_rc - -./tests.sh javascript diff --git a/kokoro/macos/javascript/continuous.cfg b/kokoro/macos/javascript/continuous.cfg deleted file mode 100644 index b478cc193..000000000 --- a/kokoro/macos/javascript/continuous.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/javascript/build.sh" -timeout_mins: 1440 diff --git a/kokoro/macos/javascript/presubmit.cfg b/kokoro/macos/javascript/presubmit.cfg deleted file mode 100644 index b478cc193..000000000 --- a/kokoro/macos/javascript/presubmit.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/javascript/build.sh" -timeout_mins: 1440 diff --git a/pkg/BUILD b/pkg/BUILD index b455cec37..2d398c023 100644 --- a/pkg/BUILD +++ b/pkg/BUILD @@ -181,30 +181,6 @@ pkg_zip( package_variables = ":protobuf_pkg_naming", ) -pkg_filegroup( - name = "js_srcs", - srcs = [ - ":dist_common", - "//js:dist_files", - ], -) - -pkg_tar( - name = "dist_js_tar", - srcs = [":js_srcs"], - extension = "tar.gz", - package_dir = "protobuf-{version}", - package_file_name = "protobuf-js-{version}.tar.gz", - package_variables = ":protobuf_pkg_naming", -) - -pkg_zip( - name = "dist_js_zip", - srcs = [":js_srcs"], - package_file_name = "protobuf-js-{version}.zip", - package_variables = ":protobuf_pkg_naming", -) - pkg_filegroup( name = "objectivec_srcs", srcs = [ @@ -309,7 +285,6 @@ pkg_filegroup( ":cpp_srcs", ":csharp_srcs", ":java_srcs", - ":js_srcs", ":objectivec_srcs", ":php_srcs", ":python_srcs", diff --git a/post_process_dist.sh b/post_process_dist.sh index 116824dd9..2630f9754 100755 --- a/post_process_dist.sh +++ b/post_process_dist.sh @@ -27,7 +27,7 @@ fi set -ex -LANGUAGES="cpp csharp java js objectivec python ruby php all" +LANGUAGES="cpp csharp java objectivec python ruby php all" BASENAME=`basename $1 .tar.gz` VERSION=${BASENAME:9} diff --git a/src/Makefile.am b/src/Makefile.am index 4e9742cf1..8cb05f78c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -86,7 +86,6 @@ nobase_include_HEADERS = \ google/protobuf/compiler/java/generator.h \ google/protobuf/compiler/java/kotlin_generator.h \ google/protobuf/compiler/java/names.h \ - google/protobuf/compiler/js/js_generator.h \ google/protobuf/compiler/objectivec/objectivec_generator.h \ google/protobuf/compiler/objectivec/objectivec_helpers.h \ google/protobuf/compiler/parser.h \ @@ -442,9 +441,6 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/java/string_field.h \ google/protobuf/compiler/java/string_field_lite.cc \ google/protobuf/compiler/java/string_field_lite.h \ - google/protobuf/compiler/js/js_generator.cc \ - google/protobuf/compiler/js/well_known_types_embed.cc \ - google/protobuf/compiler/js/well_known_types_embed.h \ google/protobuf/compiler/objectivec/objectivec_enum.cc \ google/protobuf/compiler/objectivec/objectivec_enum.h \ google/protobuf/compiler/objectivec/objectivec_enum_field.cc \ diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc deleted file mode 100644 index 8c20b7959..000000000 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ /dev/null @@ -1,3937 +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. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace compiler { -namespace js { - -// Sorted list of JavaScript keywords. These cannot be used as names. If they -// appear, we prefix them with "pb_". -const char* kKeyword[] = { - "abstract", "boolean", "break", "byte", "case", - "catch", "char", "class", "const", "continue", - "debugger", "default", "delete", "do", "double", - "else", "enum", "export", "extends", "false", - "final", "finally", "float", "for", "function", - "goto", "if", "implements", "import", "in", - "instanceof", "int", "interface", "long", "native", - "new", "null", "package", "private", "protected", - "public", "return", "short", "static", "super", - "switch", "synchronized", "this", "throw", "throws", - "transient", "try", "typeof", "var", "void", - "volatile", "while", "with", -}; - -static const int kNumKeyword = sizeof(kKeyword) / sizeof(char*); - -namespace { - -// The mode of operation for bytes fields. Historically JSPB always carried -// bytes as JS {string}, containing base64 content by convention. With binary -// and proto3 serialization the new convention is to represent it as binary -// data in Uint8Array. See b/26173701 for background on the migration. -enum BytesMode { - BYTES_DEFAULT, // Default type for getBytesField to return. - BYTES_B64, // Explicitly coerce to base64 string where needed. - BYTES_U8, // Explicitly coerce to Uint8Array where needed. -}; - -bool IsReserved(const std::string& ident) { - for (int i = 0; i < kNumKeyword; i++) { - if (ident == kKeyword[i]) { - return true; - } - } - return false; -} - -std::string GetSnakeFilename(const std::string& filename) { - std::string snake_name = filename; - ReplaceCharacters(&snake_name, "/", '_'); - return snake_name; -} - -// Given a filename like foo/bar/baz.proto, returns the corresponding JavaScript -// file foo/bar/baz.js. -std::string GetJSFilename(const GeneratorOptions& options, - const std::string& filename) { - return StripProto(filename) + options.GetFileNameExtension(); -} - -// Given a filename like foo/bar/baz.proto, returns the root directory -// path ../../ -std::string GetRootPath(const std::string& from_filename, - const std::string& to_filename) { - if (to_filename.find("google/protobuf") == 0) { - // Well-known types (.proto files in the google/protobuf directory) are - // assumed to come from the 'google-protobuf' npm package. We may want to - // generalize this exception later by letting others put generated code in - // their own npm packages. - return "google-protobuf/"; - } - - size_t slashes = std::count(from_filename.begin(), from_filename.end(), '/'); - if (slashes == 0) { - return "./"; - } - std::string result = ""; - for (size_t i = 0; i < slashes; i++) { - result += "../"; - } - return result; -} - -// Returns the alias we assign to the module of the given .proto filename -// when importing. -std::string ModuleAlias(const std::string& filename) { - // This scheme could technically cause problems if a file includes any 2 of: - // foo/bar_baz.proto - // foo_bar_baz.proto - // foo_bar/baz.proto - // - // We'll worry about this problem if/when we actually see it. This name isn't - // exposed to users so we can change it later if we need to. - std::string basename = StripProto(filename); - ReplaceCharacters(&basename, "-", '$'); - ReplaceCharacters(&basename, "/", '_'); - ReplaceCharacters(&basename, ".", '_'); - return basename + "_pb"; -} - -// Returns the fully normalized JavaScript namespace for the given -// file descriptor's package. -std::string GetNamespace(const GeneratorOptions& options, - const FileDescriptor* file) { - if (!options.namespace_prefix.empty()) { - return options.namespace_prefix; - } else if (!file->package().empty()) { - return "proto." + file->package(); - } else { - return "proto"; - } -} - -// Returns the name of the message with a leading dot and taking into account -// nesting, for example ".OuterMessage.InnerMessage", or returns empty if -// descriptor is null. This function does not handle namespacing, only message -// nesting. -std::string GetNestedMessageName(const Descriptor* descriptor) { - if (descriptor == NULL) { - return ""; - } - std::string result = - StripPrefixString(descriptor->full_name(), descriptor->file()->package()); - // Add a leading dot if one is not already present. - if (!result.empty() && result[0] != '.') { - result = "." + result; - } - return result; -} - -// Returns the path prefix for a message or enumeration that -// lives under the given file and containing type. -std::string GetPrefix(const GeneratorOptions& options, - const FileDescriptor* file_descriptor, - const Descriptor* containing_type) { - std::string prefix = GetNamespace(options, file_descriptor) + - GetNestedMessageName(containing_type); - if (!prefix.empty()) { - prefix += "."; - } - return prefix; -} - -// Returns the fully normalized JavaScript path prefix for the given -// message descriptor. -std::string GetMessagePathPrefix(const GeneratorOptions& options, - const Descriptor* descriptor) { - return GetPrefix(options, descriptor->file(), descriptor->containing_type()); -} - -// Returns the fully normalized JavaScript path for the given -// message descriptor. -std::string GetMessagePath(const GeneratorOptions& options, - const Descriptor* descriptor) { - return GetMessagePathPrefix(options, descriptor) + descriptor->name(); -} - -// Returns the fully normalized JavaScript path prefix for the given -// enumeration descriptor. -std::string GetEnumPathPrefix(const GeneratorOptions& options, - const EnumDescriptor* enum_descriptor) { - return GetPrefix(options, enum_descriptor->file(), - enum_descriptor->containing_type()); -} - -// Returns the fully normalized JavaScript path for the given -// enumeration descriptor. -std::string GetEnumPath(const GeneratorOptions& options, - const EnumDescriptor* enum_descriptor) { - return GetEnumPathPrefix(options, enum_descriptor) + enum_descriptor->name(); -} - -std::string MaybeCrossFileRef(const GeneratorOptions& options, - const FileDescriptor* from_file, - const Descriptor* to_message) { - if ((options.import_style == GeneratorOptions::kImportCommonJs || - options.import_style == GeneratorOptions::kImportCommonJsStrict) && - from_file != to_message->file()) { - // Cross-file ref in CommonJS needs to use the module alias instead of - // the global name. - return ModuleAlias(to_message->file()->name()) + - GetNestedMessageName(to_message->containing_type()) + "." + - to_message->name(); - } else { - // Within a single file we use a full name. - return GetMessagePath(options, to_message); - } -} - -std::string SubmessageTypeRef(const GeneratorOptions& options, - const FieldDescriptor* field) { - GOOGLE_CHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE); - return MaybeCrossFileRef(options, field->file(), field->message_type()); -} - -// - Object field name: LOWER_UNDERSCORE -> LOWER_CAMEL, except for group fields -// (UPPER_CAMEL -> LOWER_CAMEL), with "List" (or "Map") appended if appropriate, -// and with reserved words triggering a "pb_" prefix. -// - Getters/setters: LOWER_UNDERSCORE -> UPPER_CAMEL, except for group fields -// (use the name directly), then append "List" if appropriate, then append "$" -// if resulting name is equal to a reserved word. -// - Enums: just uppercase. - -// Locale-independent version of ToLower that deals only with ASCII A-Z. -char ToLowerASCII(char c) { - if (c >= 'A' && c <= 'Z') { - return (c - 'A') + 'a'; - } else { - return c; - } -} - -std::vector ParseLowerUnderscore(const std::string& input) { - std::vector words; - std::string running = ""; - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { - if (!running.empty()) { - words.push_back(running); - running.clear(); - } - } else { - running += ToLowerASCII(input[i]); - } - } - if (!running.empty()) { - words.push_back(running); - } - return words; -} - -std::vector ParseUpperCamel(const std::string& input) { - std::vector words; - std::string running = ""; - for (int i = 0; i < input.size(); i++) { - if (input[i] >= 'A' && input[i] <= 'Z' && !running.empty()) { - words.push_back(running); - running.clear(); - } - running += ToLowerASCII(input[i]); - } - if (!running.empty()) { - words.push_back(running); - } - return words; -} - -std::string ToLowerCamel(const std::vector& words) { - std::string result; - for (int i = 0; i < words.size(); i++) { - std::string word = words[i]; - if (i == 0 && (word[0] >= 'A' && word[0] <= 'Z')) { - word[0] = (word[0] - 'A') + 'a'; - } else if (i != 0 && (word[0] >= 'a' && word[0] <= 'z')) { - word[0] = (word[0] - 'a') + 'A'; - } - result += word; - } - return result; -} - -std::string ToUpperCamel(const std::vector& words) { - std::string result; - for (int i = 0; i < words.size(); i++) { - std::string word = words[i]; - if (word[0] >= 'a' && word[0] <= 'z') { - word[0] = (word[0] - 'a') + 'A'; - } - result += word; - } - return result; -} - -// Based on code from descriptor.cc (Thanks Kenton!) -// Uppercases the entire string, turning ValueName into -// VALUENAME. -std::string ToEnumCase(const std::string& input) { - std::string result; - result.reserve(input.size()); - - for (int i = 0; i < input.size(); i++) { - if ('a' <= input[i] && input[i] <= 'z') { - result.push_back(input[i] - 'a' + 'A'); - } else { - result.push_back(input[i]); - } - } - - return result; -} - -std::string ToLower(const std::string& input) { - std::string result; - result.reserve(input.size()); - - for (int i = 0; i < input.size(); i++) { - if ('A' <= input[i] && input[i] <= 'Z') { - result.push_back(input[i] - 'A' + 'a'); - } else { - result.push_back(input[i]); - } - } - - return result; -} - -// When we're generating one output file per SCC, this is the filename -// that top-level extensions should go in. -// e.g. one proto file (test.proto): -// package a; -// extends Foo { -// ... -// } -// If "with_filename" equals true, the extension filename will be -// "proto.a_test_extensions.js", otherwise will be "proto.a.js" -std::string GetExtensionFileName(const GeneratorOptions& options, - const FileDescriptor* file, - bool with_filename) { - std::string snake_name = StripProto(GetSnakeFilename(file->name())); - return options.output_dir + "/" + ToLower(GetNamespace(options, file)) + - (with_filename ? ("_" + snake_name + "_extensions") : "") + - options.GetFileNameExtension(); -} -// When we're generating one output file per SCC, this is the filename -// that all messages in the SCC should go in. -// If with_package equals true, filename will have package prefix, -// If the filename length is longer than 200, the filename will be the -// SCC's proto filename with suffix "_long_sccs_(index)" (if with_package equals -// true it still has package prefix) -std::string GetMessagesFileName(const GeneratorOptions& options, const SCC* scc, - bool with_package) { - static std::map* long_name_dict = - new std::map(); - std::string package_base = - with_package - ? ToLower(GetNamespace(options, scc->GetRepresentative()->file()) + - "_") - : ""; - std::string filename_base = ""; - std::vector all_message_names; - for (auto one_desc : scc->descriptors) { - if (one_desc->containing_type() == nullptr) { - all_message_names.push_back(ToLower(one_desc->name())); - } - } - sort(all_message_names.begin(), all_message_names.end()); - for (auto one_message : all_message_names) { - if (!filename_base.empty()) { - filename_base += "_"; - } - filename_base += one_message; - } - if (filename_base.size() + package_base.size() > 200) { - if ((*long_name_dict).find(scc->GetRepresentative()) == - (*long_name_dict).end()) { - std::string snake_name = StripProto( - GetSnakeFilename(scc->GetRepresentative()->file()->name())); - (*long_name_dict)[scc->GetRepresentative()] = - StrCat(snake_name, "_long_sccs_", - static_cast((*long_name_dict).size())); - } - filename_base = (*long_name_dict)[scc->GetRepresentative()]; - } - return options.output_dir + "/" + package_base + filename_base + - options.GetFileNameExtension(); -} - -// When we're generating one output file per type name, this is the filename -// that a top-level enum should go in. -// If with_package equals true, filename will have package prefix. -std::string GetEnumFileName(const GeneratorOptions& options, - const EnumDescriptor* desc, bool with_package) { - return options.output_dir + "/" + - (with_package ? ToLower(GetNamespace(options, desc->file()) + "_") - : "") + - ToLower(desc->name()) + options.GetFileNameExtension(); -} - -// Returns the message/response ID, if set. -std::string GetMessageId(const Descriptor* desc) { return std::string(); } - -bool IgnoreExtensionField(const FieldDescriptor* field) { - // Exclude descriptor extensions from output "to avoid clutter" (from original - // codegen). - if (!field->is_extension()) return false; - const FileDescriptor* file = field->containing_type()->file(); - return file->name() == "net/proto2/proto/descriptor.proto" || - file->name() == "google/protobuf/descriptor.proto"; -} - -// Used inside Google only -- do not remove. -bool IsResponse(const Descriptor* desc) { return false; } - -bool IgnoreField(const FieldDescriptor* field) { - return IgnoreExtensionField(field); -} - -// Do we ignore this message type? -bool IgnoreMessage(const Descriptor* d) { return d->options().map_entry(); } - -// Does JSPB ignore this entire oneof? True only if all fields are ignored. -bool IgnoreOneof(const OneofDescriptor* oneof) { - if (oneof->is_synthetic()) return true; - for (int i = 0; i < oneof->field_count(); i++) { - if (!IgnoreField(oneof->field(i))) { - return false; - } - } - return true; -} - -std::string JSIdent(const GeneratorOptions& options, - const FieldDescriptor* field, bool is_upper_camel, - bool is_map, bool drop_list) { - std::string result; - if (field->type() == FieldDescriptor::TYPE_GROUP) { - result = is_upper_camel - ? ToUpperCamel(ParseUpperCamel(field->message_type()->name())) - : ToLowerCamel(ParseUpperCamel(field->message_type()->name())); - } else { - result = is_upper_camel ? ToUpperCamel(ParseLowerUnderscore(field->name())) - : ToLowerCamel(ParseLowerUnderscore(field->name())); - } - if (is_map || field->is_map()) { - // JSPB-style or proto3-style map. - result += "Map"; - } else if (!drop_list && field->is_repeated()) { - // Repeated field. - result += "List"; - } - return result; -} - -std::string JSObjectFieldName(const GeneratorOptions& options, - const FieldDescriptor* field) { - std::string name = JSIdent(options, field, - /* is_upper_camel = */ false, - /* is_map = */ false, - /* drop_list = */ false); - if (IsReserved(name)) { - name = "pb_" + name; - } - return name; -} - -std::string JSByteGetterSuffix(BytesMode bytes_mode) { - switch (bytes_mode) { - case BYTES_DEFAULT: - return ""; - case BYTES_B64: - return "B64"; - case BYTES_U8: - return "U8"; - default: - assert(false); - } - return ""; -} - -// Returns the field name as a capitalized portion of a getter/setter method -// name, e.g. MyField for .getMyField(). -std::string JSGetterName(const GeneratorOptions& options, - const FieldDescriptor* field, - BytesMode bytes_mode = BYTES_DEFAULT, - bool drop_list = false) { - std::string name = JSIdent(options, field, - /* is_upper_camel = */ true, - /* is_map = */ false, drop_list); - if (field->type() == FieldDescriptor::TYPE_BYTES) { - std::string suffix = JSByteGetterSuffix(bytes_mode); - if (!suffix.empty()) { - name += "_as" + suffix; - } - } - if (name == "Extension" || name == "JsPbMessageId") { - // Avoid conflicts with base-class names. - name += "$"; - } - return name; -} - -std::string JSOneofName(const OneofDescriptor* oneof) { - return ToUpperCamel(ParseLowerUnderscore(oneof->name())); -} - -// Returns the index corresponding to this field in the JSPB array (underlying -// data storage array). -std::string JSFieldIndex(const FieldDescriptor* field) { - // Determine whether this field is a member of a group. Group fields are a bit - // wonky: their "containing type" is a message type created just for the - // group, and that type's parent type has a field with the group-message type - // as its message type and TYPE_GROUP as its field type. For such fields, the - // index we use is relative to the field number of the group submessage field. - // For all other fields, we just use the field number. - const Descriptor* containing_type = field->containing_type(); - const Descriptor* parent_type = containing_type->containing_type(); - if (parent_type != NULL) { - for (int i = 0; i < parent_type->field_count(); i++) { - if (parent_type->field(i)->type() == FieldDescriptor::TYPE_GROUP && - parent_type->field(i)->message_type() == containing_type) { - return StrCat(field->number() - parent_type->field(i)->number()); - } - } - } - return StrCat(field->number()); -} - -std::string JSOneofIndex(const OneofDescriptor* oneof) { - int index = -1; - for (int i = 0; i < oneof->containing_type()->oneof_decl_count(); i++) { - const OneofDescriptor* o = oneof->containing_type()->oneof_decl(i); - if (o->is_synthetic()) continue; - // If at least one field in this oneof is not JSPB-ignored, count the oneof. - for (int j = 0; j < o->field_count(); j++) { - const FieldDescriptor* f = o->field(j); - if (!IgnoreField(f)) { - index++; - break; // inner loop - } - } - if (o == oneof) { - break; - } - } - return StrCat(index); -} - -// Decodes a codepoint in \x0000 -- \xFFFF. -uint16_t DecodeUTF8Codepoint(uint8_t* bytes, size_t* length) { - if (*length == 0) { - return 0; - } - size_t expected = 0; - if ((*bytes & 0x80) == 0) { - expected = 1; - } else if ((*bytes & 0xe0) == 0xc0) { - expected = 2; - } else if ((*bytes & 0xf0) == 0xe0) { - expected = 3; - } else { - // Too long -- don't accept. - *length = 0; - return 0; - } - - if (*length < expected) { - // Not enough bytes -- don't accept. - *length = 0; - return 0; - } - - *length = expected; - switch (expected) { - case 1: - return bytes[0]; - case 2: - return ((bytes[0] & 0x1F) << 6) | ((bytes[1] & 0x3F) << 0); - case 3: - return ((bytes[0] & 0x0F) << 12) | ((bytes[1] & 0x3F) << 6) | - ((bytes[2] & 0x3F) << 0); - default: - return 0; - } -} - -// Escapes the contents of a string to be included within double-quotes ("") in -// JavaScript. The input data should be a UTF-8 encoded C++ string of chars. -// Returns false if |out| was truncated because |in| contained invalid UTF-8 or -// codepoints outside the BMP. -// TODO(b/115551870): Support codepoints outside the BMP. -bool EscapeJSString(const std::string& in, std::string* out) { - size_t decoded = 0; - for (size_t i = 0; i < in.size(); i += decoded) { - uint16_t codepoint = 0; - // Decode the next UTF-8 codepoint. - size_t have_bytes = in.size() - i; - uint8_t bytes[3] = { - static_cast(in[i]), - static_cast(((i + 1) < in.size()) ? in[i + 1] : 0), - static_cast(((i + 2) < in.size()) ? in[i + 2] : 0), - }; - codepoint = DecodeUTF8Codepoint(bytes, &have_bytes); - if (have_bytes == 0) { - return false; - } - decoded = have_bytes; - - switch (codepoint) { - case '\'': - *out += "\\x27"; - break; - case '"': - *out += "\\x22"; - break; - case '<': - *out += "\\x3c"; - break; - case '=': - *out += "\\x3d"; - break; - case '>': - *out += "\\x3e"; - break; - case '&': - *out += "\\x26"; - break; - case '\b': - *out += "\\b"; - break; - case '\t': - *out += "\\t"; - break; - case '\n': - *out += "\\n"; - break; - case '\f': - *out += "\\f"; - break; - case '\r': - *out += "\\r"; - break; - case '\\': - *out += "\\\\"; - break; - default: - // TODO(b/115551870): Once we're supporting codepoints outside the BMP, - // use a single Unicode codepoint escape if the output language is - // ECMAScript 2015 or above. Otherwise, use a surrogate pair. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals - if (codepoint >= 0x20 && codepoint <= 0x7e) { - *out += static_cast(codepoint); - } else if (codepoint >= 0x100) { - *out += StringPrintf("\\u%04x", codepoint); - } else { - *out += StringPrintf("\\x%02x", codepoint); - } - break; - } - } - return true; -} - -std::string EscapeBase64(const std::string& in) { - static const char* kAlphabet = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - std::string result; - - for (size_t i = 0; i < in.size(); i += 3) { - int value = (in[i] << 16) | (((i + 1) < in.size()) ? (in[i + 1] << 8) : 0) | - (((i + 2) < in.size()) ? (in[i + 2] << 0) : 0); - result += kAlphabet[(value >> 18) & 0x3f]; - result += kAlphabet[(value >> 12) & 0x3f]; - if ((i + 1) < in.size()) { - result += kAlphabet[(value >> 6) & 0x3f]; - } else { - result += '='; - } - if ((i + 2) < in.size()) { - result += kAlphabet[(value >> 0) & 0x3f]; - } else { - result += '='; - } - } - - return result; -} - -// Post-process the result of SimpleFtoa/SimpleDtoa to *exactly* match the -// original codegen's formatting (which is just .toString() on java.lang.Double -// or java.lang.Float). -std::string PostProcessFloat(std::string result) { - // If inf, -inf or nan, replace with +Infinity, -Infinity or NaN. - if (result == "inf") { - return "Infinity"; - } else if (result == "-inf") { - return "-Infinity"; - } else if (result == "nan") { - return "NaN"; - } - - // If scientific notation (e.g., "1e10"), (i) capitalize the "e", (ii) - // ensure that the mantissa (portion prior to the "e") has at least one - // fractional digit (after the decimal point), and (iii) strip any unnecessary - // leading zeroes and/or '+' signs from the exponent. - std::string::size_type exp_pos = result.find('e'); - if (exp_pos != std::string::npos) { - std::string mantissa = result.substr(0, exp_pos); - std::string exponent = result.substr(exp_pos + 1); - - // Add ".0" to mantissa if no fractional part exists. - if (mantissa.find('.') == std::string::npos) { - mantissa += ".0"; - } - - // Strip the sign off the exponent and store as |exp_neg|. - bool exp_neg = false; - if (!exponent.empty() && exponent[0] == '+') { - exponent = exponent.substr(1); - } else if (!exponent.empty() && exponent[0] == '-') { - exp_neg = true; - exponent = exponent.substr(1); - } - - // Strip any leading zeroes off the exponent. - while (exponent.size() > 1 && exponent[0] == '0') { - exponent = exponent.substr(1); - } - - return mantissa + "E" + std::string(exp_neg ? "-" : "") + exponent; - } - - // Otherwise, this is an ordinary decimal number. Append ".0" if result has no - // decimal/fractional part in order to match output of original codegen. - if (result.find('.') == std::string::npos) { - result += ".0"; - } - - return result; -} - -std::string FloatToString(float value) { - std::string result = SimpleFtoa(value); - return PostProcessFloat(result); -} - -std::string DoubleToString(double value) { - std::string result = SimpleDtoa(value); - return PostProcessFloat(result); -} - -bool InRealOneof(const FieldDescriptor* field) { - return field->containing_oneof() && - !field->containing_oneof()->is_synthetic(); -} - -// Return true if this is an integral field that should be represented as string -// in JS. -bool IsIntegralFieldWithStringJSType(const FieldDescriptor* field) { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT64: - case FieldDescriptor::CPPTYPE_UINT64: - // The default value of JSType is JS_NORMAL, which behaves the same as - // JS_NUMBER. - return field->options().jstype() == FieldOptions::JS_STRING; - default: - return false; - } -} - -std::string MaybeNumberString(const FieldDescriptor* field, - const std::string& orig) { - return IsIntegralFieldWithStringJSType(field) ? ("\"" + orig + "\"") : orig; -} - -std::string JSFieldDefault(const FieldDescriptor* field) { - if (field->is_repeated()) { - return "[]"; - } - - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - return MaybeNumberString(field, StrCat(field->default_value_int32())); - case FieldDescriptor::CPPTYPE_UINT32: - // The original codegen is in Java, and Java protobufs store unsigned - // integer values as signed integer values. In order to exactly match the - // output, we need to reinterpret as base-2 signed. Ugh. - return MaybeNumberString( - field, StrCat(static_cast(field->default_value_uint32()))); - case FieldDescriptor::CPPTYPE_INT64: - return MaybeNumberString(field, StrCat(field->default_value_int64())); - case FieldDescriptor::CPPTYPE_UINT64: - // See above note for uint32 -- reinterpreting as signed. - return MaybeNumberString( - field, StrCat(static_cast(field->default_value_uint64()))); - case FieldDescriptor::CPPTYPE_ENUM: - return StrCat(field->default_value_enum()->number()); - case FieldDescriptor::CPPTYPE_BOOL: - return field->default_value_bool() ? "true" : "false"; - case FieldDescriptor::CPPTYPE_FLOAT: - return FloatToString(field->default_value_float()); - case FieldDescriptor::CPPTYPE_DOUBLE: - return DoubleToString(field->default_value_double()); - case FieldDescriptor::CPPTYPE_STRING: - if (field->type() == FieldDescriptor::TYPE_STRING) { - std::string out; - bool is_valid = EscapeJSString(field->default_value_string(), &out); - if (!is_valid) { - // TODO(b/115551870): Decide whether this should be a hard error. - GOOGLE_LOG(WARNING) - << "The default value for field " << field->full_name() - << " was truncated since it contained invalid UTF-8 or" - " codepoints outside the basic multilingual plane."; - } - return "\"" + out + "\""; - } else { // Bytes - return "\"" + EscapeBase64(field->default_value_string()) + "\""; - } - case FieldDescriptor::CPPTYPE_MESSAGE: - return "null"; - } - GOOGLE_LOG(FATAL) << "Shouldn't reach here."; - return ""; -} - -std::string ProtoTypeName(const GeneratorOptions& options, - const FieldDescriptor* field) { - switch (field->type()) { - case FieldDescriptor::TYPE_BOOL: - return "bool"; - case FieldDescriptor::TYPE_INT32: - return "int32"; - case FieldDescriptor::TYPE_UINT32: - return "uint32"; - case FieldDescriptor::TYPE_SINT32: - return "sint32"; - case FieldDescriptor::TYPE_FIXED32: - return "fixed32"; - case FieldDescriptor::TYPE_SFIXED32: - return "sfixed32"; - case FieldDescriptor::TYPE_INT64: - return "int64"; - case FieldDescriptor::TYPE_UINT64: - return "uint64"; - case FieldDescriptor::TYPE_SINT64: - return "sint64"; - case FieldDescriptor::TYPE_FIXED64: - return "fixed64"; - case FieldDescriptor::TYPE_SFIXED64: - return "sfixed64"; - case FieldDescriptor::TYPE_FLOAT: - return "float"; - case FieldDescriptor::TYPE_DOUBLE: - return "double"; - case FieldDescriptor::TYPE_STRING: - return "string"; - case FieldDescriptor::TYPE_BYTES: - return "bytes"; - case FieldDescriptor::TYPE_GROUP: - return GetMessagePath(options, field->message_type()); - case FieldDescriptor::TYPE_ENUM: - return GetEnumPath(options, field->enum_type()); - case FieldDescriptor::TYPE_MESSAGE: - return GetMessagePath(options, field->message_type()); - default: - return ""; - } -} - -std::string JSIntegerTypeName(const FieldDescriptor* field) { - return IsIntegralFieldWithStringJSType(field) ? "string" : "number"; -} - -std::string JSStringTypeName(const GeneratorOptions& options, - const FieldDescriptor* field, - BytesMode bytes_mode) { - if (field->type() == FieldDescriptor::TYPE_BYTES) { - switch (bytes_mode) { - case BYTES_DEFAULT: - return "(string|Uint8Array)"; - case BYTES_B64: - return "string"; - case BYTES_U8: - return "Uint8Array"; - default: - assert(false); - } - } - return "string"; -} - -std::string JSTypeName(const GeneratorOptions& options, - const FieldDescriptor* field, BytesMode bytes_mode) { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_BOOL: - return "boolean"; - case FieldDescriptor::CPPTYPE_INT32: - return JSIntegerTypeName(field); - case FieldDescriptor::CPPTYPE_INT64: - return JSIntegerTypeName(field); - case FieldDescriptor::CPPTYPE_UINT32: - return JSIntegerTypeName(field); - case FieldDescriptor::CPPTYPE_UINT64: - return JSIntegerTypeName(field); - case FieldDescriptor::CPPTYPE_FLOAT: - return "number"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return "number"; - case FieldDescriptor::CPPTYPE_STRING: - return JSStringTypeName(options, field, bytes_mode); - case FieldDescriptor::CPPTYPE_ENUM: - return GetEnumPath(options, field->enum_type()); - case FieldDescriptor::CPPTYPE_MESSAGE: - return GetMessagePath(options, field->message_type()); - default: - return ""; - } -} - -// Used inside Google only -- do not remove. -bool UseBrokenPresenceSemantics(const GeneratorOptions& options, - const FieldDescriptor* field) { - return false; -} - -// Returns true for fields that return "null" from accessors when they are -// unset. This should normally only be true for non-repeated submessages, but we -// have legacy users who relied on old behavior where accessors behaved this -// way. -bool ReturnsNullWhenUnset(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - field->is_optional()) { - return true; - } - - // TODO(haberman): remove this case and unconditionally return false. - return UseBrokenPresenceSemantics(options, field) && !field->is_repeated() && - !field->has_default_value(); -} - -// In a sane world, this would be the same as ReturnsNullWhenUnset(). But in -// the status quo, some fields declare that they never return null/undefined -// even though they actually do: -// * required fields -// * optional enum fields -// * proto3 primitive fields. -bool DeclaredReturnTypeIsNullable(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (field->is_required() || field->type() == FieldDescriptor::TYPE_ENUM) { - return false; - } - - if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 && - field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - return false; - } - - return ReturnsNullWhenUnset(options, field); -} - -bool SetterAcceptsUndefined(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (ReturnsNullWhenUnset(options, field)) { - return true; - } - - // Broken presence semantics always accepts undefined for setters. - return UseBrokenPresenceSemantics(options, field); -} - -bool SetterAcceptsNull(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (ReturnsNullWhenUnset(options, field)) { - return true; - } - - // With broken presence semantics, fields with defaults accept "null" for - // setters, but other fields do not. This is a strange quirk of the old - // codegen. - return UseBrokenPresenceSemantics(options, field) && - field->has_default_value(); -} - -// Returns types which are known to by non-nullable by default. -// The style guide requires that we omit "!" in this case. -bool IsPrimitive(const std::string& type) { - return type == "undefined" || type == "string" || type == "number" || - type == "boolean"; -} - -std::string JSFieldTypeAnnotation(const GeneratorOptions& options, - const FieldDescriptor* field, - bool is_setter_argument, bool force_present, - bool singular_if_not_packed, - BytesMode bytes_mode = BYTES_DEFAULT, - bool force_singular = false) { - std::string jstype = JSTypeName(options, field, bytes_mode); - - if (!force_singular && field->is_repeated() && - (field->is_packed() || !singular_if_not_packed)) { - if (field->type() == FieldDescriptor::TYPE_BYTES && - bytes_mode == BYTES_DEFAULT) { - jstype = "(Array|Array)"; - } else { - if (!IsPrimitive(jstype)) { - jstype = "!" + jstype; - } - jstype = "Array<" + jstype + ">"; - } - } - - bool is_null_or_undefined = false; - - if (is_setter_argument) { - if (SetterAcceptsNull(options, field)) { - jstype = "?" + jstype; - is_null_or_undefined = true; - } - - if (SetterAcceptsUndefined(options, field)) { - jstype += "|undefined"; - is_null_or_undefined = true; - } - } else if (force_present) { - // Don't add null or undefined. - } else { - if (DeclaredReturnTypeIsNullable(options, field)) { - jstype = "?" + jstype; - is_null_or_undefined = true; - } - } - - if (!is_null_or_undefined && !IsPrimitive(jstype)) { - jstype = "!" + jstype; - } - - return jstype; -} - -std::string JSBinaryReaderMethodType(const FieldDescriptor* field) { - std::string name = field->type_name(); - if (name[0] >= 'a' && name[0] <= 'z') { - name[0] = (name[0] - 'a') + 'A'; - } - return IsIntegralFieldWithStringJSType(field) ? (name + "String") : name; -} - -std::string JSBinaryReadWriteMethodName(const FieldDescriptor* field, - bool is_writer) { - std::string name = JSBinaryReaderMethodType(field); - if (field->is_packed()) { - name = "Packed" + name; - } else if (is_writer && field->is_repeated()) { - name = "Repeated" + name; - } - return name; -} - -std::string JSBinaryReaderMethodName(const GeneratorOptions& options, - const FieldDescriptor* field) { - return "jspb.BinaryReader.prototype.read" + - JSBinaryReadWriteMethodName(field, /* is_writer = */ false); -} - -std::string JSBinaryWriterMethodName(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (field->containing_type() && - field->containing_type()->options().message_set_wire_format()) { - return "jspb.BinaryWriter.prototype.writeMessageSet"; - } - return "jspb.BinaryWriter.prototype.write" + - JSBinaryReadWriteMethodName(field, /* is_writer = */ true); -} - -std::string JSTypeTag(const FieldDescriptor* desc) { - switch (desc->type()) { - case FieldDescriptor::TYPE_DOUBLE: - case FieldDescriptor::TYPE_FLOAT: - return "Float"; - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_UINT32: - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_UINT64: - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_SINT32: - case FieldDescriptor::TYPE_SINT64: - case FieldDescriptor::TYPE_SFIXED32: - case FieldDescriptor::TYPE_SFIXED64: - if (IsIntegralFieldWithStringJSType(desc)) { - return "StringInt"; - } else { - return "Int"; - } - case FieldDescriptor::TYPE_BOOL: - return "Boolean"; - case FieldDescriptor::TYPE_STRING: - return "String"; - case FieldDescriptor::TYPE_BYTES: - return "Bytes"; - case FieldDescriptor::TYPE_ENUM: - return "Enum"; - default: - assert(false); - } - return ""; -} - -bool HasRepeatedFields(const GeneratorOptions& options, - const Descriptor* desc) { - for (int i = 0; i < desc->field_count(); i++) { - if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) { - return true; - } - } - return false; -} - -static const char* kRepeatedFieldArrayName = ".repeatedFields_"; - -std::string RepeatedFieldsArrayName(const GeneratorOptions& options, - const Descriptor* desc) { - return HasRepeatedFields(options, desc) - ? (GetMessagePath(options, desc) + kRepeatedFieldArrayName) - : "null"; -} - -bool HasOneofFields(const Descriptor* desc) { - for (int i = 0; i < desc->field_count(); i++) { - if (InRealOneof(desc->field(i))) { - return true; - } - } - return false; -} - -static const char* kOneofGroupArrayName = ".oneofGroups_"; - -std::string OneofFieldsArrayName(const GeneratorOptions& options, - const Descriptor* desc) { - return HasOneofFields(desc) - ? (GetMessagePath(options, desc) + kOneofGroupArrayName) - : "null"; -} - -std::string RepeatedFieldNumberList(const GeneratorOptions& options, - const Descriptor* desc) { - std::vector numbers; - for (int i = 0; i < desc->field_count(); i++) { - if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) { - numbers.push_back(JSFieldIndex(desc->field(i))); - } - } - return "[" + Join(numbers, ",") + "]"; -} - -std::string OneofGroupList(const Descriptor* desc) { - // List of arrays (one per oneof), each of which is a list of field indices - std::vector oneof_entries; - for (int i = 0; i < desc->oneof_decl_count(); i++) { - const OneofDescriptor* oneof = desc->oneof_decl(i); - if (IgnoreOneof(oneof)) { - continue; - } - - std::vector oneof_fields; - for (int j = 0; j < oneof->field_count(); j++) { - if (IgnoreField(oneof->field(j))) { - continue; - } - oneof_fields.push_back(JSFieldIndex(oneof->field(j))); - } - oneof_entries.push_back("[" + Join(oneof_fields, ",") + "]"); - } - return "[" + Join(oneof_entries, ",") + "]"; -} - -std::string JSOneofArray(const GeneratorOptions& options, - const FieldDescriptor* field) { - return OneofFieldsArrayName(options, field->containing_type()) + "[" + - JSOneofIndex(field->containing_oneof()) + "]"; -} - -std::string RelativeTypeName(const FieldDescriptor* field) { - assert(field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM || - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE); - // For a field with an enum or message type, compute a name relative to the - // path name of the message type containing this field. - std::string package = field->file()->package(); - std::string containing_type = field->containing_type()->full_name() + "."; - std::string type = (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) - ? field->enum_type()->full_name() - : field->message_type()->full_name(); - - // |prefix| is advanced as we find separators '.' past the common package - // prefix that yield common prefixes in the containing type's name and this - // type's name. - int prefix = 0; - for (int i = 0; i < type.size() && i < containing_type.size(); i++) { - if (type[i] != containing_type[i]) { - break; - } - if (type[i] == '.' && i >= package.size()) { - prefix = i + 1; - } - } - - return type.substr(prefix); -} - -std::string JSExtensionsObjectName(const GeneratorOptions& options, - const FileDescriptor* from_file, - const Descriptor* desc) { - if (desc->full_name() == "google.protobuf.bridge.MessageSet") { - // TODO(haberman): fix this for the kImportCommonJs case. - return "jspb.Message.messageSetExtensions"; - } else { - return MaybeCrossFileRef(options, from_file, desc) + ".extensions"; - } -} - -static const int kMapKeyField = 1; -static const int kMapValueField = 2; - -const FieldDescriptor* MapFieldKey(const FieldDescriptor* field) { - assert(field->is_map()); - return field->message_type()->FindFieldByNumber(kMapKeyField); -} - -const FieldDescriptor* MapFieldValue(const FieldDescriptor* field) { - assert(field->is_map()); - return field->message_type()->FindFieldByNumber(kMapValueField); -} - -std::string FieldDefinition(const GeneratorOptions& options, - const FieldDescriptor* field) { - if (field->is_map()) { - const FieldDescriptor* key_field = MapFieldKey(field); - const FieldDescriptor* value_field = MapFieldValue(field); - std::string key_type = ProtoTypeName(options, key_field); - std::string value_type; - if (value_field->type() == FieldDescriptor::TYPE_ENUM || - value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - value_type = RelativeTypeName(value_field); - } else { - value_type = ProtoTypeName(options, value_field); - } - return StringPrintf("map<%s, %s> %s = %d;", key_type.c_str(), - value_type.c_str(), field->name().c_str(), - field->number()); - } else { - std::string qualifier = - field->is_repeated() ? "repeated" - : (field->is_optional() ? "optional" : "required"); - std::string type, name; - if (field->type() == FieldDescriptor::TYPE_ENUM || - field->type() == FieldDescriptor::TYPE_MESSAGE) { - type = RelativeTypeName(field); - name = field->name(); - } else if (field->type() == FieldDescriptor::TYPE_GROUP) { - type = "group"; - name = field->message_type()->name(); - } else { - type = ProtoTypeName(options, field); - name = field->name(); - } - return StringPrintf("%s %s %s = %d;", qualifier.c_str(), type.c_str(), - name.c_str(), field->number()); - } -} - -std::string FieldComments(const FieldDescriptor* field, BytesMode bytes_mode) { - std::string comments; - if (field->type() == FieldDescriptor::TYPE_BYTES && bytes_mode == BYTES_U8) { - comments += - " * Note that Uint8Array is not supported on all browsers.\n" - " * @see http://caniuse.com/Uint8Array\n"; - } - return comments; -} - -bool ShouldGenerateExtension(const FieldDescriptor* field) { - return field->is_extension() && !IgnoreField(field); -} - -bool HasExtensions(const Descriptor* desc) { - for (int i = 0; i < desc->extension_count(); i++) { - if (ShouldGenerateExtension(desc->extension(i))) { - return true; - } - } - for (int i = 0; i < desc->nested_type_count(); i++) { - if (HasExtensions(desc->nested_type(i))) { - return true; - } - } - return false; -} - -bool HasExtensions(const FileDescriptor* file) { - for (int i = 0; i < file->extension_count(); i++) { - if (ShouldGenerateExtension(file->extension(i))) { - return true; - } - } - for (int i = 0; i < file->message_type_count(); i++) { - if (HasExtensions(file->message_type(i))) { - return true; - } - } - return false; -} - -bool HasMap(const GeneratorOptions& options, const Descriptor* desc) { - for (int i = 0; i < desc->field_count(); i++) { - if (desc->field(i)->is_map()) { - return true; - } - } - for (int i = 0; i < desc->nested_type_count(); i++) { - if (HasMap(options, desc->nested_type(i))) { - return true; - } - } - return false; -} - -bool FileHasMap(const GeneratorOptions& options, const FileDescriptor* desc) { - for (int i = 0; i < desc->message_type_count(); i++) { - if (HasMap(options, desc->message_type(i))) { - return true; - } - } - return false; -} - -bool IsExtendable(const Descriptor* desc) { - return desc->extension_range_count() > 0; -} - -// Returns the max index in the underlying data storage array beyond which the -// extension object is used. -std::string GetPivot(const Descriptor* desc) { - static const int kDefaultPivot = 500; - - // Find the max field number - int max_field_number = 0; - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i)) && - desc->field(i)->number() > max_field_number) { - max_field_number = desc->field(i)->number(); - } - } - - int pivot = -1; - if (IsExtendable(desc) || (max_field_number >= kDefaultPivot)) { - pivot = ((max_field_number + 1) < kDefaultPivot) ? (max_field_number + 1) - : kDefaultPivot; - } - - return StrCat(pivot); -} - -// Whether this field represents presence. For fields with presence, we -// generate extra methods (clearFoo() and hasFoo()) for this field. -bool HasFieldPresence(const GeneratorOptions& options, - const FieldDescriptor* field) { - // This returns false for repeated fields and maps, but we still do - // generate clearFoo() methods for these through a special case elsewhere. - return field->has_presence(); -} - -// We use this to implement the semantics that same file can be generated -// multiple times, but only the last one keep the short name. Others all use -// long name with extra information to distinguish (For message and enum, the -// extra information is package name, for file level extension, the extra -// information is proto's filename). -// We never actually write the files, but we keep a set of which descriptors -// were the final one for a given filename. -class FileDeduplicator { - public: - explicit FileDeduplicator(const GeneratorOptions& options) {} - - // params: - // filenames: a pair of {short filename, full filename} - // (short filename don't have extra information, full filename - // contains extra information) - // desc: The Descriptor or SCC pointer or EnumDescriptor. - bool AddFile(const std::pair filenames, - const void* desc) { - if (descs_by_shortname_.find(filenames.first) != - descs_by_shortname_.end()) { - // Change old pointer's actual name to full name. - auto short_name_desc = descs_by_shortname_[filenames.first]; - allowed_descs_actual_name_[short_name_desc] = - allowed_descs_full_name_[short_name_desc]; - } - descs_by_shortname_[filenames.first] = desc; - allowed_descs_actual_name_[desc] = filenames.first; - allowed_descs_full_name_[desc] = filenames.second; - - return true; - } - - void GetAllowedMap(std::map* allowed_set) { - *allowed_set = allowed_descs_actual_name_; - } - - private: - // The map that restores all the descs that are using short name as filename. - std::map descs_by_shortname_; - // The final actual filename map. - std::map allowed_descs_actual_name_; - // The full name map. - std::map allowed_descs_full_name_; -}; - -void DepthFirstSearch(const FileDescriptor* file, - std::vector* list, - std::set* seen) { - if (!seen->insert(file).second) { - return; - } - - // Add all dependencies. - for (int i = 0; i < file->dependency_count(); i++) { - DepthFirstSearch(file->dependency(i), list, seen); - } - - // Add this file. - list->push_back(file); -} - -// A functor for the predicate to remove_if() below. Returns true if a given -// FileDescriptor is not in the given set. -class NotInSet { - public: - explicit NotInSet(const std::set& file_set) - : file_set_(file_set) {} - - bool operator()(const FileDescriptor* file) { - return file_set_.count(file) == 0; - } - - private: - const std::set& file_set_; -}; - -// This function generates an ordering of the input FileDescriptors that matches -// the logic of the old code generator. The order is significant because two -// different input files can generate the same output file, and the last one -// needs to win. -void GenerateJspbFileOrder(const std::vector& input, - std::vector* ordered) { - // First generate an ordering of all reachable files (including dependencies) - // with depth-first search. This mimics the behavior of --include_imports, - // which is what the old codegen used. - ordered->clear(); - std::set seen; - std::set input_set; - for (int i = 0; i < input.size(); i++) { - DepthFirstSearch(input[i], ordered, &seen); - input_set.insert(input[i]); - } - - // Now remove the entries that are not actually in our input list. - ordered->erase( - std::remove_if(ordered->begin(), ordered->end(), NotInSet(input_set)), - ordered->end()); -} - -// If we're generating code in file-per-type mode, avoid overwriting files -// by choosing the last descriptor that writes each filename and permitting -// only those to generate code. - -struct DepsGenerator { - std::vector operator()(const Descriptor* desc) const { - std::vector deps; - auto maybe_add = [&](const Descriptor* d) { - if (d) deps.push_back(d); - }; - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i))) { - maybe_add(desc->field(i)->message_type()); - } - } - for (int i = 0; i < desc->extension_count(); i++) { - maybe_add(desc->extension(i)->message_type()); - maybe_add(desc->extension(i)->containing_type()); - } - for (int i = 0; i < desc->nested_type_count(); i++) { - maybe_add(desc->nested_type(i)); - } - maybe_add(desc->containing_type()); - - return deps; - } -}; - -bool GenerateJspbAllowedMap(const GeneratorOptions& options, - const std::vector& files, - std::map* allowed_set, - SCCAnalyzer* analyzer) { - std::vector files_ordered; - GenerateJspbFileOrder(files, &files_ordered); - - // Choose the last descriptor for each filename. - FileDeduplicator dedup(options); - std::set added; - for (int i = 0; i < files_ordered.size(); i++) { - for (int j = 0; j < files_ordered[i]->message_type_count(); j++) { - const Descriptor* desc = files_ordered[i]->message_type(j); - if (added.insert(analyzer->GetSCC(desc)).second && - !dedup.AddFile( - std::make_pair( - GetMessagesFileName(options, analyzer->GetSCC(desc), false), - GetMessagesFileName(options, analyzer->GetSCC(desc), true)), - analyzer->GetSCC(desc))) { - return false; - } - } - for (int j = 0; j < files_ordered[i]->enum_type_count(); j++) { - const EnumDescriptor* desc = files_ordered[i]->enum_type(j); - if (!dedup.AddFile(std::make_pair(GetEnumFileName(options, desc, false), - GetEnumFileName(options, desc, true)), - desc)) { - return false; - } - } - - // Pull out all free-floating extensions and generate files for those too. - bool has_extension = false; - - for (int j = 0; j < files_ordered[i]->extension_count(); j++) { - if (ShouldGenerateExtension(files_ordered[i]->extension(j))) { - has_extension = true; - } - } - - if (has_extension) { - if (!dedup.AddFile( - std::make_pair( - GetExtensionFileName(options, files_ordered[i], false), - GetExtensionFileName(options, files_ordered[i], true)), - files_ordered[i])) { - return false; - } - } - } - - dedup.GetAllowedMap(allowed_set); - - return true; -} - -// Embeds base64 encoded GeneratedCodeInfo proto in a comment at the end of -// file. -void EmbedCodeAnnotations(const GeneratedCodeInfo& annotations, - io::Printer* printer) { - // Serialize annotations proto into base64 string. - std::string meta_content; - annotations.SerializeToString(&meta_content); - std::string meta_64; - Base64Escape(meta_content, &meta_64); - - // Print base64 encoded annotations at the end of output file in - // a comment. - printer->Print("\n// Below is base64 encoded GeneratedCodeInfo proto"); - printer->Print("\n// $encoded_proto$\n", "encoded_proto", meta_64); -} - -bool IsWellKnownTypeFile(const FileDescriptor* file) { - return HasPrefixString(file->name(), "google/protobuf/"); -} - -} // anonymous namespace - -void Generator::GenerateHeader(const GeneratorOptions& options, - const FileDescriptor* file, - io::Printer* printer) const { - if (file != nullptr) { - printer->Print("// source: $filename$\n", "filename", file->name()); - } - printer->Print( - "/**\n" - " * @fileoverview\n" - " * @enhanceable\n" - // TODO(b/152440355): requireType/requires diverged from internal version. - " * @suppress {missingRequire} reports error on implicit type usages.\n" - " * @suppress {messageConventions} JS Compiler reports an " - "error if a variable or\n" - " * field starts with 'MSG_' and isn't a translatable " - "message.\n" - " * @public\n" - " */\n" - "// GENERATED CODE -- DO NOT EDIT!\n" - "/* eslint-disable */\n" - "// @ts-nocheck\n" - "\n"); -} - -void Generator::FindProvidesForFile(const GeneratorOptions& options, - io::Printer* printer, - const FileDescriptor* file, - std::set* provided) const { - for (int i = 0; i < file->message_type_count(); i++) { - FindProvidesForMessage(options, printer, file->message_type(i), provided); - } - for (int i = 0; i < file->enum_type_count(); i++) { - FindProvidesForEnum(options, printer, file->enum_type(i), provided); - } -} - -void Generator::FindProvides(const GeneratorOptions& options, - io::Printer* printer, - const std::vector& files, - std::set* provided) const { - for (int i = 0; i < files.size(); i++) { - FindProvidesForFile(options, printer, files[i], provided); - } - - printer->Print("\n"); -} - -void FindProvidesForOneOfEnum(const GeneratorOptions& options, - const OneofDescriptor* oneof, - std::set* provided) { - std::string name = GetMessagePath(options, oneof->containing_type()) + "." + - JSOneofName(oneof) + "Case"; - provided->insert(name); -} - -void FindProvidesForOneOfEnums(const GeneratorOptions& options, - io::Printer* printer, const Descriptor* desc, - std::set* provided) { - if (HasOneofFields(desc)) { - for (int i = 0; i < desc->oneof_decl_count(); i++) { - if (IgnoreOneof(desc->oneof_decl(i))) { - continue; - } - FindProvidesForOneOfEnum(options, desc->oneof_decl(i), provided); - } - } -} - -void Generator::FindProvidesForMessage(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc, - std::set* provided) const { - if (IgnoreMessage(desc)) { - return; - } - - std::string name = GetMessagePath(options, desc); - provided->insert(name); - - for (int i = 0; i < desc->enum_type_count(); i++) { - FindProvidesForEnum(options, printer, desc->enum_type(i), provided); - } - - FindProvidesForOneOfEnums(options, printer, desc, provided); - - for (int i = 0; i < desc->nested_type_count(); i++) { - FindProvidesForMessage(options, printer, desc->nested_type(i), provided); - } -} -void Generator::FindProvidesForEnum(const GeneratorOptions& options, - io::Printer* printer, - const EnumDescriptor* enumdesc, - std::set* provided) const { - std::string name = GetEnumPath(options, enumdesc); - provided->insert(name); -} - -void Generator::FindProvidesForFields( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& fields, - std::set* provided) const { - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - - if (IgnoreField(field)) { - continue; - } - - std::string name = GetNamespace(options, field->file()) + "." + - JSObjectFieldName(options, field); - provided->insert(name); - } -} - -void Generator::GenerateProvides(const GeneratorOptions& options, - io::Printer* printer, - std::set* provided) const { - for (std::set::iterator it = provided->begin(); - it != provided->end(); ++it) { - if (options.import_style == GeneratorOptions::kImportClosure) { - printer->Print("goog.provide('$name$');\n", "name", *it); - } else { - // We aren't using Closure's import system, but we use goog.exportSymbol() - // to construct the expected tree of objects, eg. - // - // goog.exportSymbol('foo.bar.Baz', null, this); - // - // // Later generated code expects foo.bar = {} to exist: - // foo.bar.Baz = function() { /* ... */ } - - // Do not use global scope in strict mode - if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { - std::string namespaceObject = *it; - // Remove "proto." from the namespace object - GOOGLE_CHECK_EQ(0, namespaceObject.compare(0, 6, "proto.")); - namespaceObject.erase(0, 6); - printer->Print("goog.exportSymbol('$name$', null, proto);\n", "name", - namespaceObject); - } else { - printer->Print("goog.exportSymbol('$name$', null, global);\n", "name", - *it); - } - } - } -} - -void Generator::GenerateRequiresForSCC(const GeneratorOptions& options, - io::Printer* printer, const SCC* scc, - std::set* provided) const { - std::set required; - std::set forwards; - bool have_message = false; - bool has_extension = false; - bool has_map = false; - for (auto desc : scc->descriptors) { - if (desc->containing_type() == nullptr) { - FindRequiresForMessage(options, desc, &required, &forwards, - &have_message); - has_extension = (has_extension || HasExtensions(desc)); - has_map = (has_map || HasMap(options, desc)); - } - } - - GenerateRequiresImpl(options, printer, &required, &forwards, provided, - /* require_jspb = */ have_message, - /* require_extension = */ has_extension, - /* require_map = */ has_map); -} - -void Generator::GenerateRequiresForLibrary( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& files, - std::set* provided) const { - GOOGLE_CHECK_EQ(options.import_style, GeneratorOptions::kImportClosure); - // For Closure imports we need to import every message type individually. - std::set required; - std::set forwards; - bool have_extensions = false; - bool have_map = false; - bool have_message = false; - - for (int i = 0; i < files.size(); i++) { - for (int j = 0; j < files[i]->message_type_count(); j++) { - const Descriptor* desc = files[i]->message_type(j); - if (!IgnoreMessage(desc)) { - FindRequiresForMessage(options, desc, &required, &forwards, - &have_message); - } - } - - if (!have_extensions && HasExtensions(files[i])) { - have_extensions = true; - } - - if (!have_map && FileHasMap(options, files[i])) { - have_map = true; - } - - for (int j = 0; j < files[i]->extension_count(); j++) { - const FieldDescriptor* extension = files[i]->extension(j); - if (IgnoreField(extension)) { - continue; - } - if (extension->containing_type()->full_name() != - "google.protobuf.bridge.MessageSet") { - required.insert(GetMessagePath(options, extension->containing_type())); - } - FindRequiresForField(options, extension, &required, &forwards); - have_extensions = true; - } - } - - GenerateRequiresImpl(options, printer, &required, &forwards, provided, - /* require_jspb = */ have_message, - /* require_extension = */ have_extensions, - /* require_map = */ have_map); -} - -void Generator::GenerateRequiresForExtensions( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& fields, - std::set* provided) const { - std::set required; - std::set forwards; - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - if (IgnoreField(field)) { - continue; - } - FindRequiresForExtension(options, field, &required, &forwards); - } - - GenerateRequiresImpl(options, printer, &required, &forwards, provided, - /* require_jspb = */ false, - /* require_extension = */ fields.size() > 0, - /* require_map = */ false); -} - -void Generator::GenerateRequiresImpl(const GeneratorOptions& options, - io::Printer* printer, - std::set* required, - std::set* forwards, - std::set* provided, - bool require_jspb, bool require_extension, - bool require_map) const { - if (require_jspb) { - required->insert("jspb.Message"); - required->insert("jspb.BinaryReader"); - required->insert("jspb.BinaryWriter"); - } - if (require_extension) { - required->insert("jspb.ExtensionFieldBinaryInfo"); - required->insert("jspb.ExtensionFieldInfo"); - } - if (require_map) { - required->insert("jspb.Map"); - } - - std::set::iterator it; - for (it = required->begin(); it != required->end(); ++it) { - if (provided->find(*it) != provided->end()) { - continue; - } - printer->Print("goog.require('$name$');\n", "name", *it); - } - - printer->Print("\n"); - - for (it = forwards->begin(); it != forwards->end(); ++it) { - if (provided->find(*it) != provided->end()) { - continue; - } - printer->Print("goog.forwardDeclare('$name$');\n", "name", *it); - } -} - -bool NamespaceOnly(const Descriptor* desc) { return false; } - -void Generator::FindRequiresForMessage(const GeneratorOptions& options, - const Descriptor* desc, - std::set* required, - std::set* forwards, - bool* have_message) const { - if (!NamespaceOnly(desc)) { - *have_message = true; - for (int i = 0; i < desc->field_count(); i++) { - const FieldDescriptor* field = desc->field(i); - if (IgnoreField(field)) { - continue; - } - FindRequiresForField(options, field, required, forwards); - } - } - - for (int i = 0; i < desc->extension_count(); i++) { - const FieldDescriptor* field = desc->extension(i); - if (IgnoreField(field)) { - continue; - } - FindRequiresForExtension(options, field, required, forwards); - } - - for (int i = 0; i < desc->nested_type_count(); i++) { - FindRequiresForMessage(options, desc->nested_type(i), required, forwards, - have_message); - } -} - -void Generator::FindRequiresForField(const GeneratorOptions& options, - const FieldDescriptor* field, - std::set* required, - std::set* forwards) const { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM && - // N.B.: file-level extensions with enum type do *not* create - // dependencies, as per original codegen. - !(field->is_extension() && field->extension_scope() == nullptr)) { - if (options.add_require_for_enums) { - required->insert(GetEnumPath(options, field->enum_type())); - } else { - forwards->insert(GetEnumPath(options, field->enum_type())); - } - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (!IgnoreMessage(field->message_type())) { - required->insert(GetMessagePath(options, field->message_type())); - } - } -} - -void Generator::FindRequiresForExtension( - const GeneratorOptions& options, const FieldDescriptor* field, - std::set* required, std::set* forwards) const { - if (field->containing_type()->full_name() != - "google.protobuf.bridge.MessageSet") { - required->insert(GetMessagePath(options, field->containing_type())); - } - FindRequiresForField(options, field, required, forwards); -} - -void Generator::GenerateTestOnly(const GeneratorOptions& options, - io::Printer* printer) const { - if (options.testonly) { - printer->Print("goog.setTestOnly();\n\n"); - } - printer->Print("\n"); -} - -void Generator::GenerateClassesAndEnums(const GeneratorOptions& options, - io::Printer* printer, - const FileDescriptor* file) const { - for (int i = 0; i < file->message_type_count(); i++) { - GenerateClassConstructorAndDeclareExtensionFieldInfo(options, printer, - file->message_type(i)); - } - for (int i = 0; i < file->message_type_count(); i++) { - GenerateClass(options, printer, file->message_type(i)); - } - for (int i = 0; i < file->enum_type_count(); i++) { - GenerateEnum(options, printer, file->enum_type(i)); - } -} - -void Generator::GenerateClass(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - if (IgnoreMessage(desc)) { - return; - } - - if (!NamespaceOnly(desc)) { - printer->Print("\n"); - GenerateClassFieldInfo(options, printer, desc); - - GenerateClassToObject(options, printer, desc); - // These must come *before* the extension-field info generation in - // GenerateClassRegistration so that references to the binary - // serialization/deserialization functions may be placed in the extension - // objects. - GenerateClassDeserializeBinary(options, printer, desc); - GenerateClassSerializeBinary(options, printer, desc); - } - - // Recurse on nested types. These must come *before* the extension-field - // info generation in GenerateClassRegistration so that extensions that - // reference nested types proceed the definitions of the nested types. - for (int i = 0; i < desc->enum_type_count(); i++) { - GenerateEnum(options, printer, desc->enum_type(i)); - } - for (int i = 0; i < desc->nested_type_count(); i++) { - GenerateClass(options, printer, desc->nested_type(i)); - } - - if (!NamespaceOnly(desc)) { - GenerateClassRegistration(options, printer, desc); - GenerateClassFields(options, printer, desc); - - if (options.import_style != GeneratorOptions::kImportClosure) { - for (int i = 0; i < desc->extension_count(); i++) { - GenerateExtension(options, printer, desc->extension(i)); - } - } - } -} - -void Generator::GenerateClassConstructor(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print( - "/**\n" - " * Generated by JsPbCodeGenerator.\n" - " * @param {Array=} opt_data Optional initial data array, typically " - "from a\n" - " * server response, or constructed directly in Javascript. The array " - "is used\n" - " * in place and becomes part of the constructed object. It is not " - "cloned.\n" - " * If no data is provided, the constructed object will be empty, but " - "still\n" - " * valid.\n" - " * @extends {jspb.Message}\n" - " * @constructor\n" - " */\n" - "$classprefix$$classname$ = function(opt_data) {\n", - "classprefix", GetMessagePathPrefix(options, desc), "classname", - desc->name()); - printer->Annotate("classname", desc); - std::string message_id = GetMessageId(desc); - printer->Print( - " jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, " - "$rptfields$, $oneoffields$);\n", - "messageId", - !message_id.empty() ? ("'" + message_id + "'") - : (IsResponse(desc) ? "''" : "0"), - "pivot", GetPivot(desc), "rptfields", - RepeatedFieldsArrayName(options, desc), "oneoffields", - OneofFieldsArrayName(options, desc)); - printer->Print( - "};\n" - "goog.inherits($classname$, jspb.Message);\n" - "if (goog.DEBUG && !COMPILED) {\n" - // displayName overrides Function.prototype.displayName - // http://google3/javascript/externs/es3.js?l=511 - " /**\n" - " * @public\n" - " * @override\n" - " */\n" - " $classname$.displayName = '$classname$';\n" - "}\n", - "classname", GetMessagePath(options, desc)); -} - -void Generator::GenerateClassConstructorAndDeclareExtensionFieldInfo( - const GeneratorOptions& options, io::Printer* printer, - const Descriptor* desc) const { - if (!NamespaceOnly(desc)) { - GenerateClassConstructor(options, printer, desc); - if (IsExtendable(desc) && - desc->full_name() != "google.protobuf.bridge.MessageSet") { - GenerateClassExtensionFieldInfo(options, printer, desc); - } - } - for (int i = 0; i < desc->nested_type_count(); i++) { - if (!IgnoreMessage(desc->nested_type(i))) { - GenerateClassConstructorAndDeclareExtensionFieldInfo( - options, printer, desc->nested_type(i)); - } - } -} - -void Generator::GenerateClassFieldInfo(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - if (HasRepeatedFields(options, desc)) { - printer->Print( - "/**\n" - " * List of repeated fields within this message type.\n" - " * @private {!Array}\n" - " * @const\n" - " */\n" - "$classname$$rptfieldarray$ = $rptfields$;\n" - "\n", - "classname", GetMessagePath(options, desc), "rptfieldarray", - kRepeatedFieldArrayName, "rptfields", - RepeatedFieldNumberList(options, desc)); - } - - if (HasOneofFields(desc)) { - printer->Print( - "/**\n" - " * Oneof group definitions for this message. Each group defines the " - "field\n" - " * numbers belonging to that group. When of these fields' value is " - "set, all\n" - " * other fields in the group are cleared. During deserialization, if " - "multiple\n" - " * fields are encountered for a group, only the last value seen will " - "be kept.\n" - " * @private {!Array>}\n" - " * @const\n" - " */\n" - "$classname$$oneofgrouparray$ = $oneofgroups$;\n" - "\n", - "classname", GetMessagePath(options, desc), "oneofgrouparray", - kOneofGroupArrayName, "oneofgroups", OneofGroupList(desc)); - - for (int i = 0; i < desc->oneof_decl_count(); i++) { - if (IgnoreOneof(desc->oneof_decl(i))) { - continue; - } - GenerateOneofCaseDefinition(options, printer, desc->oneof_decl(i)); - } - } -} - -void Generator::GenerateClassXid(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print( - "\n" - "\n" - "$class$.prototype.messageXid = xid('$class$');\n", - "class", GetMessagePath(options, desc)); -} - -void Generator::GenerateOneofCaseDefinition( - const GeneratorOptions& options, io::Printer* printer, - const OneofDescriptor* oneof) const { - printer->Print( - "/**\n" - " * @enum {number}\n" - " */\n" - "$classname$.$oneof$Case = {\n" - " $upcase$_NOT_SET: 0", - "classname", GetMessagePath(options, oneof->containing_type()), "oneof", - JSOneofName(oneof), "upcase", ToEnumCase(oneof->name())); - - for (int i = 0; i < oneof->field_count(); i++) { - if (IgnoreField(oneof->field(i))) { - continue; - } - - printer->Print( - ",\n" - " $upcase$: $number$", - "upcase", ToEnumCase(oneof->field(i)->name()), "number", - JSFieldIndex(oneof->field(i))); - printer->Annotate("upcase", oneof->field(i)); - } - - printer->Print( - "\n" - "};\n" - "\n" - "/**\n" - " * @return {$class$.$oneof$Case}\n" - " */\n" - "$class$.prototype.get$oneof$Case = function() {\n" - " return /** @type {$class$.$oneof$Case} */(jspb.Message." - "computeOneofCase(this, $class$.oneofGroups_[$oneofindex$]));\n" - "};\n" - "\n", - "class", GetMessagePath(options, oneof->containing_type()), "oneof", - JSOneofName(oneof), "oneofindex", JSOneofIndex(oneof)); -} - -void Generator::GenerateClassToObject(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print( - "\n" - "\n" - "if (jspb.Message.GENERATE_TO_OBJECT) {\n" - "/**\n" - " * Creates an object representation of this proto.\n" - " * Field names that are reserved in JavaScript and will be renamed to " - "pb_name.\n" - " * Optional fields that are not set will be set to undefined.\n" - " * To access a reserved field use, foo.pb_, eg, foo.pb_default.\n" - " * For the list of reserved names please see:\n" - " * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n" - " * @param {boolean=} opt_includeInstance Deprecated. whether to include " - "the\n" - " * JSPB instance for transitional soy proto support:\n" - " * http://goto/soy-param-migration\n" - " * @return {!Object}\n" - " */\n" - "$classname$.prototype.toObject = function(opt_includeInstance) {\n" - " return $classname$.toObject(opt_includeInstance, this);\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Static version of the {@see toObject} method.\n" - " * @param {boolean|undefined} includeInstance Deprecated. Whether to " - "include\n" - " * the JSPB instance for transitional soy proto support:\n" - " * http://goto/soy-param-migration\n" - " * @param {!$classname$} msg The msg instance to transform.\n" - " * @return {!Object}\n" - " * @suppress {unusedLocalVariables} f is only used for nested messages\n" - " */\n" - "$classname$.toObject = function(includeInstance, msg) {\n" - " var f, obj = {", - "classname", GetMessagePath(options, desc)); - - bool first = true; - for (int i = 0; i < desc->field_count(); i++) { - const FieldDescriptor* field = desc->field(i); - if (IgnoreField(field)) { - continue; - } - - if (!first) { - printer->Print(",\n "); - } else { - printer->Print("\n "); - first = false; - } - - GenerateClassFieldToObject(options, printer, field); - } - - if (!first) { - printer->Print("\n };\n\n"); - } else { - printer->Print("\n\n };\n\n"); - } - - if (IsExtendable(desc)) { - printer->Print( - " jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), " - "obj,\n" - " $extObject$, $class$.prototype.getExtension,\n" - " includeInstance);\n", - "extObject", JSExtensionsObjectName(options, desc->file(), desc), - "class", GetMessagePath(options, desc)); - } - - printer->Print( - " if (includeInstance) {\n" - " obj.$$jspbMessageInstance = msg;\n" - " }\n" - " return obj;\n" - "};\n" - "}\n" - "\n" - "\n", - "classname", GetMessagePath(options, desc)); -} - -void Generator::GenerateFieldValueExpression(io::Printer* printer, - const char* obj_reference, - const FieldDescriptor* field, - bool use_default) const { - const bool is_float_or_double = - field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT || - field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE; - const bool is_boolean = field->cpp_type() == FieldDescriptor::CPPTYPE_BOOL; - - const std::string with_default = use_default ? "WithDefault" : ""; - const std::string default_arg = - use_default ? StrCat(", ", JSFieldDefault(field)) : ""; - const std::string cardinality = field->is_repeated() ? "Repeated" : ""; - std::string type = ""; - if (is_float_or_double) { - type = "FloatingPoint"; - } - if (is_boolean) { - type = "Boolean"; - } - - // Prints the appropriate function, among: - // - getField - // - getBooleanField - // - getFloatingPointField => Replaced by getOptionalFloatingPointField to - // preserve backward compatibility. - // - getFieldWithDefault - // - getBooleanFieldWithDefault - // - getFloatingPointFieldWithDefault - // - getRepeatedField - // - getRepeatedBooleanField - // - getRepeatedFloatingPointField - if (is_float_or_double && !field->is_repeated() && !use_default) { - printer->Print( - "jspb.Message.getOptionalFloatingPointField($obj$, " - "$index$$default$)", - "obj", obj_reference, "index", JSFieldIndex(field), "default", - default_arg); - } else { - printer->Print( - "jspb.Message.get$cardinality$$type$Field$with_default$($obj$, " - "$index$$default$)", - "cardinality", cardinality, "type", type, "with_default", with_default, - "obj", obj_reference, "index", JSFieldIndex(field), "default", - default_arg); - } -} - -void Generator::GenerateClassFieldToObject(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const { - printer->Print("$fieldname$: ", "fieldname", - JSObjectFieldName(options, field)); - - if (field->is_map()) { - const FieldDescriptor* value_field = MapFieldValue(field); - // If the map values are of a message type, we must provide their static - // toObject() method; otherwise we pass undefined for that argument. - std::string value_to_object; - if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - value_to_object = - GetMessagePath(options, value_field->message_type()) + ".toObject"; - } else { - value_to_object = "undefined"; - } - printer->Print( - "(f = msg.get$name$()) ? f.toObject(includeInstance, $valuetoobject$) " - ": []", - "name", JSGetterName(options, field), "valuetoobject", value_to_object); - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - // Message field. - if (field->is_repeated()) { - { - printer->Print( - "jspb.Message.toObjectList(msg.get$getter$(),\n" - " $type$.toObject, includeInstance)", - "getter", JSGetterName(options, field), "type", - SubmessageTypeRef(options, field)); - } - } else { - printer->Print( - "(f = msg.get$getter$()) && " - "$type$.toObject(includeInstance, f)", - "getter", JSGetterName(options, field), "type", - SubmessageTypeRef(options, field)); - } - } else if (field->type() == FieldDescriptor::TYPE_BYTES) { - // For bytes fields we want to always return the B64 data. - printer->Print("msg.get$getter$()", "getter", - JSGetterName(options, field, BYTES_B64)); - } else { - bool use_default = field->has_default_value(); - - if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 && - // Repeated fields get initialized to their default in the constructor - // (why?), so we emit a plain getField() call for them. - !field->is_repeated()) { - // Proto3 puts all defaults (including implicit defaults) in toObject(). - // But for proto2 we leave the existing semantics unchanged: unset fields - // without default are unset. - use_default = true; - } - - // We don't implement this by calling the accessors, because the semantics - // of the accessors are changing independently of the toObject() semantics. - // We are migrating the accessors to return defaults instead of null, but - // it may take longer to migrate toObject (or we might not want to do it at - // all). So we want to generate independent code. - // The accessor for unset optional values without default should return - // null. Those are converted to undefined in the generated object. - if (!use_default) { - printer->Print("(f = "); - } - GenerateFieldValueExpression(printer, "msg", field, use_default); - if (!use_default) { - printer->Print(") == null ? undefined : f"); - } - } -} - -void Generator::GenerateObjectTypedef(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - // TODO(b/122687752): Consider renaming nested messages called ObjectFormat - // to prevent collisions. - const std::string type_name = GetMessagePath(options, desc) + ".ObjectFormat"; - - printer->Print( - "/**\n" - " * The raw object form of $messageName$ as accepted by the `fromObject` " - "method.\n" - " * @record\n" - " */\n" - "$typeName$ = function() {\n", - "messageName", desc->name(), "typeName", type_name); - - for (int i = 0; i < desc->field_count(); i++) { - if (i > 0) { - printer->Print("\n"); - } - printer->Print( - " /** @type {$fieldType$|undefined} */\n" - " this.$fieldName$;\n", - "fieldName", JSObjectFieldName(options, desc->field(i)), - // TODO(b/121097361): Add type checking for field values. - "fieldType", "?"); - } - - printer->Print("};\n\n"); -} - -void Generator::GenerateClassFromObject(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print("if (jspb.Message.GENERATE_FROM_OBJECT) {\n\n"); - - GenerateObjectTypedef(options, printer, desc); - - printer->Print( - "/**\n" - " * Loads data from an object into a new instance of this proto.\n" - " * @param {!$classname$.ObjectFormat} obj\n" - " * The object representation of this proto to load the data from.\n" - " * @return {!$classname$}\n" - " */\n" - "$classname$.fromObject = function(obj) {\n" - " var msg = new $classname$();\n", - "classname", GetMessagePath(options, desc)); - - for (int i = 0; i < desc->field_count(); i++) { - const FieldDescriptor* field = desc->field(i); - if (!IgnoreField(field)) { - GenerateClassFieldFromObject(options, printer, field); - } - } - - printer->Print( - " return msg;\n" - "};\n" - "}\n\n"); -} - -void Generator::GenerateClassFieldFromObject( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const { - if (field->is_map()) { - const FieldDescriptor* value_field = MapFieldValue(field); - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - // Since the map values are of message type, we have to do some extra work - // to recursively call fromObject() on them before setting the map field. - printer->Print( - " obj.$name$ && jspb.Message.setWrapperField(\n" - " msg, $index$, jspb.Map.fromObject(obj.$name$, $fieldclass$, " - "$fieldclass$.fromObject));\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field), "fieldclass", - GetMessagePath(options, value_field->message_type())); - } else { - // `msg` is a newly-constructed message object that has not yet built any - // map containers wrapping underlying arrays, so we can simply directly - // set the array here without fear of a stale wrapper. - printer->Print( - " obj.$name$ && " - "jspb.Message.setField(msg, $index$, obj.$name$);\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field)); - } - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - // Message field (singular or repeated) - if (field->is_repeated()) { - { - printer->Print( - " obj.$name$ && " - "jspb.Message.setRepeatedWrapperField(\n" - " msg, $index$, obj.$name$.map(\n" - " $fieldclass$.fromObject));\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field), "fieldclass", - SubmessageTypeRef(options, field)); - } - } else { - printer->Print( - " obj.$name$ && jspb.Message.setWrapperField(\n" - " msg, $index$, $fieldclass$.fromObject(obj.$name$));\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field), "fieldclass", SubmessageTypeRef(options, field)); - } - } else { - // Simple (primitive) field. - printer->Print( - " obj.$name$ != null && jspb.Message.setField(msg, $index$, " - "obj.$name$);\n", - "name", JSObjectFieldName(options, field), "index", - JSFieldIndex(field)); - } -} - -void Generator::GenerateClassRegistration(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - // Register any extensions defined inside this message type. - for (int i = 0; i < desc->extension_count(); i++) { - const FieldDescriptor* extension = desc->extension(i); - if (ShouldGenerateExtension(extension)) { - GenerateExtension(options, printer, extension); - } - } -} - -void Generator::GenerateClassFields(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i))) { - GenerateClassField(options, printer, desc->field(i)); - } - } -} - -void GenerateBytesWrapper(const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field, BytesMode bytes_mode) { - std::string type = - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false, bytes_mode); - printer->Print( - "/**\n" - " * $fielddef$\n" - "$comment$" - " * This is a type-conversion wrapper around `get$defname$()`\n" - " * @return {$type$}\n" - " */\n" - "$class$.prototype.get$name$ = function() {\n" - " return /** @type {$type$} */ (jspb.Message.bytes$list$As$suffix$(\n" - " this.get$defname$()));\n" - "};\n" - "\n" - "\n", - "fielddef", FieldDefinition(options, field), "comment", - FieldComments(field, bytes_mode), "type", type, "class", - GetMessagePath(options, field->containing_type()), "name", - JSGetterName(options, field, bytes_mode), "list", - field->is_repeated() ? "List" : "", "suffix", - JSByteGetterSuffix(bytes_mode), "defname", - JSGetterName(options, field, BYTES_DEFAULT)); -} - -void Generator::GenerateClassField(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const { - if (field->is_map()) { - const FieldDescriptor* key_field = MapFieldKey(field); - const FieldDescriptor* value_field = MapFieldValue(field); - // Map field: special handling to instantiate the map object on demand. - std::string key_type = - JSFieldTypeAnnotation(options, key_field, - /* is_setter_argument = */ false, - /* force_present = */ true, - /* singular_if_not_packed = */ false); - std::string value_type = - JSFieldTypeAnnotation(options, value_field, - /* is_setter_argument = */ false, - /* force_present = */ true, - /* singular_if_not_packed = */ false); - - printer->Print( - "/**\n" - " * $fielddef$\n" - " * @param {boolean=} opt_noLazyCreate Do not create the map if\n" - " * empty, instead returning `undefined`\n" - " * @return {!jspb.Map<$keytype$,$valuetype$>}\n" - " */\n", - "fielddef", FieldDefinition(options, field), "keytype", key_type, - "valuetype", value_type); - printer->Print( - "$class$.prototype.$gettername$ = function(opt_noLazyCreate) {\n" - " return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n", - "class", GetMessagePath(options, field->containing_type()), - "gettername", "get" + JSGetterName(options, field), "keytype", key_type, - "valuetype", value_type); - printer->Annotate("gettername", field); - printer->Print( - " jspb.Message.getMapField(this, $index$, opt_noLazyCreate", - "index", JSFieldIndex(field)); - - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print( - ",\n" - " $messageType$", - "messageType", GetMessagePath(options, value_field->message_type())); - } else { - printer->Print( - ",\n" - " null"); - } - - printer->Print("));\n"); - - printer->Print( - "};\n" - "\n" - "\n"); - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - // Message field: special handling in order to wrap the underlying data - // array with a message object. - - printer->Print( - "/**\n" - " * $fielddef$\n" - "$comment$" - " * @return {$type$}\n" - " */\n", - "fielddef", FieldDefinition(options, field), "comment", - FieldComments(field, BYTES_DEFAULT), "type", - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false)); - printer->Print( - "$class$.prototype.$gettername$ = function() {\n" - " return /** @type{$type$} */ (\n" - " jspb.Message.get$rpt$WrapperField(this, $wrapperclass$, " - "$index$$required$));\n" - "};\n" - "\n" - "\n", - "class", GetMessagePath(options, field->containing_type()), - "gettername", "get" + JSGetterName(options, field), "type", - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false), - "rpt", (field->is_repeated() ? "Repeated" : ""), "index", - JSFieldIndex(field), "wrapperclass", SubmessageTypeRef(options, field), - "required", - (field->label() == FieldDescriptor::LABEL_REQUIRED ? ", 1" : "")); - printer->Annotate("gettername", field); - printer->Print( - "/**\n" - " * @param {$optionaltype$} value\n" - " * @return {!$class$} returns this\n" - "*/\n" - "$class$.prototype.$settername$ = function(value) {\n" - " return jspb.Message.set$oneoftag$$repeatedtag$WrapperField(", - "optionaltype", - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ true, - /* force_present = */ false, - /* singular_if_not_packed = */ false), - "class", GetMessagePath(options, field->containing_type()), - "settername", "set" + JSGetterName(options, field), "oneoftag", - (InRealOneof(field) ? "Oneof" : ""), "repeatedtag", - (field->is_repeated() ? "Repeated" : "")); - printer->Annotate("settername", field); - - printer->Print( - "this, $index$$oneofgroup$, value);\n" - "};\n" - "\n" - "\n", - "index", JSFieldIndex(field), "oneofgroup", - (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : "")); - - if (field->is_repeated()) { - GenerateRepeatedMessageHelperMethods(options, printer, field); - } - - } else { - bool untyped = false; - - // Simple (primitive) field, either singular or repeated. - - // TODO(b/26173701): Always use BYTES_DEFAULT for the getter return type; - // at this point we "lie" to non-binary users and tell the return - // type is always base64 string, pending a LSC to migrate to typed getters. - BytesMode bytes_mode = - field->type() == FieldDescriptor::TYPE_BYTES && !options.binary - ? BYTES_B64 - : BYTES_DEFAULT; - std::string typed_annotation = - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false, - /* bytes_mode = */ bytes_mode); - if (untyped) { - printer->Print( - "/**\n" - " * @return {?} Raw field, untyped.\n" - " */\n"); - } else { - printer->Print( - "/**\n" - " * $fielddef$\n" - "$comment$" - " * @return {$type$}\n" - " */\n", - "fielddef", FieldDefinition(options, field), "comment", - FieldComments(field, bytes_mode), "type", typed_annotation); - } - - printer->Print("$class$.prototype.$gettername$ = function() {\n", "class", - GetMessagePath(options, field->containing_type()), - "gettername", "get" + JSGetterName(options, field)); - printer->Annotate("gettername", field); - - if (untyped) { - printer->Print(" return "); - } else { - printer->Print(" return /** @type {$type$} */ (", "type", - typed_annotation); - } - - bool use_default = !ReturnsNullWhenUnset(options, field); - - // Raw fields with no default set should just return undefined. - if (untyped && !field->has_default_value()) { - use_default = false; - } - - // Repeated fields get initialized to their default in the constructor - // (why?), so we emit a plain getField() call for them. - if (field->is_repeated()) { - use_default = false; - } - - GenerateFieldValueExpression(printer, "this", field, use_default); - - if (untyped) { - printer->Print( - ";\n" - "};\n" - "\n" - "\n"); - } else { - printer->Print( - ");\n" - "};\n" - "\n" - "\n"); - } - - if (field->type() == FieldDescriptor::TYPE_BYTES && !untyped) { - GenerateBytesWrapper(options, printer, field, BYTES_B64); - GenerateBytesWrapper(options, printer, field, BYTES_U8); - } - - printer->Print( - "/**\n" - " * @param {$optionaltype$} value\n" - " * @return {!$class$} returns this\n" - " */\n", - "class", GetMessagePath(options, field->containing_type()), - "optionaltype", - untyped ? "*" - : JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ true, - /* force_present = */ false, - /* singular_if_not_packed = */ false)); - - if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 && - !field->is_repeated() && !field->is_map() && - !HasFieldPresence(options, field)) { - // Proto3 non-repeated and non-map fields without presence use the - // setProto3*Field function. - printer->Print( - "$class$.prototype.$settername$ = function(value) {\n" - " return jspb.Message.setProto3$typetag$Field(this, $index$, " - "value);" - "\n" - "};\n" - "\n" - "\n", - "class", GetMessagePath(options, field->containing_type()), - "settername", "set" + JSGetterName(options, field), "typetag", - JSTypeTag(field), "index", JSFieldIndex(field)); - printer->Annotate("settername", field); - } else { - // Otherwise, use the regular setField function. - printer->Print( - "$class$.prototype.$settername$ = function(value) {\n" - " return jspb.Message.set$oneoftag$Field(this, $index$", - "class", GetMessagePath(options, field->containing_type()), - "settername", "set" + JSGetterName(options, field), "oneoftag", - (InRealOneof(field) ? "Oneof" : ""), "index", JSFieldIndex(field)); - printer->Annotate("settername", field); - printer->Print( - "$oneofgroup$, $type$value$rptvalueinit$$typeclose$);\n" - "};\n" - "\n" - "\n", - "type", - untyped ? "/** @type{string|number|boolean|Array|undefined} */(" : "", - "typeclose", untyped ? ")" : "", "oneofgroup", - (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), - "rptvalueinit", (field->is_repeated() ? " || []" : "")); - } - - if (untyped) { - printer->Print( - "/**\n" - " * Clears the value.\n" - " * @return {!$class$} returns this\n" - " */\n", - "class", GetMessagePath(options, field->containing_type())); - } - - if (field->is_repeated()) { - GenerateRepeatedPrimitiveHelperMethods(options, printer, field, untyped); - } - } - - // Generate clearFoo() method for map fields, repeated fields, and other - // fields with presence. - if (field->is_map()) { - // clang-format off - printer->Print( - "/**\n" - " * Clears values from the map. The map will be non-null.\n" - " * @return {!$class$} returns this\n" - " */\n" - "$class$.prototype.$clearername$ = function() {\n" - " this.$gettername$().clear();\n" - " return this;" - "};\n" - "\n" - "\n", - "class", GetMessagePath(options, field->containing_type()), - "clearername", "clear" + JSGetterName(options, field), - "gettername", "get" + JSGetterName(options, field)); - // clang-format on - printer->Annotate("clearername", field); - } else if (field->is_repeated() || - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_required())) { - // Fields where we can delegate to the regular setter. - // clang-format off - printer->Print( - "/**\n" - " * $jsdoc$\n" - " * @return {!$class$} returns this\n" - " */\n" - "$class$.prototype.$clearername$ = function() {\n" - " return this.$settername$($clearedvalue$);\n" - "};\n" - "\n" - "\n", - "jsdoc", field->is_repeated() - ? "Clears the list making it empty but non-null." - : "Clears the message field making it undefined.", - "class", GetMessagePath(options, field->containing_type()), - "clearername", "clear" + JSGetterName(options, field), - "settername", "set" + JSGetterName(options, field), - "clearedvalue", (field->is_repeated() ? "[]" : "undefined")); - // clang-format on - printer->Annotate("clearername", field); - } else if (HasFieldPresence(options, field)) { - // Fields where we can't delegate to the regular setter because it doesn't - // accept "undefined" as an argument. - // clang-format off - printer->Print( - "/**\n" - " * Clears the field making it undefined.\n" - " * @return {!$class$} returns this\n" - " */\n" - "$class$.prototype.$clearername$ = function() {\n" - " return jspb.Message.set$maybeoneof$Field(this, " - "$index$$maybeoneofgroup$, ", - "class", GetMessagePath(options, field->containing_type()), - "clearername", "clear" + JSGetterName(options, field), - "maybeoneof", (InRealOneof(field) ? "Oneof" : ""), - "maybeoneofgroup", (InRealOneof(field) - ? (", " + JSOneofArray(options, field)) - : ""), - "index", JSFieldIndex(field)); - // clang-format on - printer->Annotate("clearername", field); - printer->Print( - "$clearedvalue$);\n" - "};\n" - "\n" - "\n", - "clearedvalue", (field->is_repeated() ? "[]" : "undefined")); - } - - if (HasFieldPresence(options, field)) { - printer->Print( - "/**\n" - " * Returns whether this field is set.\n" - " * @return {boolean}\n" - " */\n" - "$class$.prototype.$hasername$ = function() {\n" - " return jspb.Message.getField(this, $index$) != null;\n" - "};\n" - "\n" - "\n", - "class", GetMessagePath(options, field->containing_type()), "hasername", - "has" + JSGetterName(options, field), "index", JSFieldIndex(field)); - printer->Annotate("hasername", field); - } -} - -void Generator::GenerateRepeatedPrimitiveHelperMethods( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field, bool untyped) const { - // clang-format off - printer->Print( - "/**\n" - " * @param {$optionaltype$} value\n" - " * @param {number=} opt_index\n" - " * @return {!$class$} returns this\n" - " */\n" - "$class$.prototype.$addername$ = function(value, opt_index) {\n" - " return jspb.Message.addToRepeatedField(this, " - "$index$", - "class", GetMessagePath(options, field->containing_type()), "addername", - "add" + JSGetterName(options, field, BYTES_DEFAULT, - /* drop_list = */ true), - "optionaltype", - JSFieldTypeAnnotation( - options, field, - /* is_setter_argument = */ false, - /* force_present = */ true, - /* singular_if_not_packed = */ false, - BYTES_DEFAULT, - /* force_singular = */ true), - "index", JSFieldIndex(field)); - printer->Annotate("addername", field); - printer->Print( - "$oneofgroup$, $type$value$rptvalueinit$$typeclose$, " - "opt_index);\n" - "};\n" - "\n" - "\n", - "type", untyped ? "/** @type{string|number|boolean|!Uint8Array} */(" : "", - "typeclose", untyped ? ")" : "", "oneofgroup", - (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), - "rptvalueinit", ""); - // clang-format on -} - -void Generator::GenerateRepeatedMessageHelperMethods( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const { - printer->Print( - "/**\n" - " * @param {!$optionaltype$=} opt_value\n" - " * @param {number=} opt_index\n" - " * @return {!$optionaltype$}\n" - " */\n" - "$class$.prototype.$addername$ = function(opt_value, opt_index) {\n" - " return jspb.Message.addTo$repeatedtag$WrapperField(", - "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "class", - GetMessagePath(options, field->containing_type()), "addername", - "add" + JSGetterName(options, field, BYTES_DEFAULT, - /* drop_list = */ true), - "repeatedtag", (field->is_repeated() ? "Repeated" : "")); - - printer->Annotate("addername", field); - printer->Print( - "this, $index$$oneofgroup$, opt_value, $ctor$, opt_index);\n" - "};\n" - "\n" - "\n", - "index", JSFieldIndex(field), "oneofgroup", - (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), "ctor", - GetMessagePath(options, field->message_type())); -} - -void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - if (IsExtendable(desc)) { - printer->Print( - "\n" - "/**\n" - " * The extensions registered with this message class. This is a " - "map of\n" - " * extension field number to fieldInfo object.\n" - " *\n" - " * For example:\n" - " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, " - "ctor: proto.example.MyMessage} }\n" - " *\n" - " * fieldName contains the JsCompiler renamed field name property " - "so that it\n" - " * works in OPTIMIZED mode.\n" - " *\n" - " * @type {!Object}\n" - " */\n" - "$class$.extensions = {};\n" - "\n", - "class", GetMessagePath(options, desc)); - - printer->Print( - "\n" - "/**\n" - " * The extensions registered with this message class. This is a " - "map of\n" - " * extension field number to fieldInfo object.\n" - " *\n" - " * For example:\n" - " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, " - "ctor: proto.example.MyMessage} }\n" - " *\n" - " * fieldName contains the JsCompiler renamed field name property " - "so that it\n" - " * works in OPTIMIZED mode.\n" - " *\n" - " * @type {!Object}\n" - " */\n" - "$class$.extensionsBinary = {};\n" - "\n", - "class", GetMessagePath(options, desc)); - } -} - -void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - // TODO(cfallin): Handle lazy decoding when requested by field option and/or - // by default for 'bytes' fields and packed repeated fields. - - printer->Print( - "/**\n" - " * Deserializes binary data (in protobuf wire format).\n" - " * @param {jspb.ByteSource} bytes The bytes to deserialize.\n" - " * @return {!$class$}\n" - " */\n" - "$class$.deserializeBinary = function(bytes) {\n" - " var reader = new jspb.BinaryReader(bytes);\n" - " var msg = new $class$;\n" - " return $class$.deserializeBinaryFromReader(msg, reader);\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Deserializes binary data (in protobuf wire format) from the\n" - " * given reader into the given message object.\n" - " * @param {!$class$} msg The message object to deserialize into.\n" - " * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n" - " * @return {!$class$}\n" - " */\n" - "$class$.deserializeBinaryFromReader = function(msg, reader) {\n" - " while (reader.nextField()) {\n", - "class", GetMessagePath(options, desc)); - printer->Print( - " if (reader.isEndGroup()) {\n" - " break;\n" - " }\n" - " var field = reader.getFieldNumber();\n" - " switch (field) {\n"); - - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i))) { - GenerateClassDeserializeBinaryField(options, printer, desc->field(i)); - } - } - - printer->Print(" default:\n"); - if (IsExtendable(desc)) { - printer->Print( - " jspb.Message.readBinaryExtension(msg, reader,\n" - " $extobj$Binary,\n" - " $class$.prototype.getExtension,\n" - " $class$.prototype.setExtension);\n" - " break;\n" - " }\n", - "extobj", JSExtensionsObjectName(options, desc->file(), desc), "class", - GetMessagePath(options, desc)); - } else { - printer->Print( - " reader.skipField();\n" - " break;\n" - " }\n"); - } - - printer->Print( - " }\n" - " return msg;\n" - "};\n" - "\n" - "\n"); -} - -void Generator::GenerateClassDeserializeBinaryField( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const { - printer->Print(" case $num$:\n", "num", StrCat(field->number())); - - if (field->is_map()) { - const FieldDescriptor* key_field = MapFieldKey(field); - const FieldDescriptor* value_field = MapFieldValue(field); - printer->Print( - " var value = msg.get$name$();\n" - " reader.readMessage(value, function(message, reader) {\n", - "name", JSGetterName(options, field)); - - printer->Print( - " jspb.Map.deserializeBinary(message, reader, " - "$keyReaderFn$, $valueReaderFn$", - "keyReaderFn", JSBinaryReaderMethodName(options, key_field), - "valueReaderFn", JSBinaryReaderMethodName(options, value_field)); - - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(", $messageType$.deserializeBinaryFromReader", - "messageType", - GetMessagePath(options, value_field->message_type())); - } else { - printer->Print(", null"); - } - printer->Print(", $defaultKey$", "defaultKey", JSFieldDefault(key_field)); - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(", new $messageType$()", "messageType", - GetMessagePath(options, value_field->message_type())); - } else { - printer->Print(", $defaultValue$", "defaultValue", - JSFieldDefault(value_field)); - } - printer->Print(");\n"); - printer->Print(" });\n"); - } else { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print( - " var value = new $fieldclass$;\n" - " reader.read$msgOrGroup$($grpfield$value," - "$fieldclass$.deserializeBinaryFromReader);\n", - "fieldclass", SubmessageTypeRef(options, field), "msgOrGroup", - (field->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message", - "grpfield", - (field->type() == FieldDescriptor::TYPE_GROUP) - ? (StrCat(field->number()) + ", ") - : ""); - } else if (field->is_packable()) { - printer->Print( - " var values = /** @type {$fieldtype$} */ " - "(reader.isDelimited() " - "? reader.readPacked$reader$() : [reader.read$reader$()]);\n", - "fieldtype", - JSFieldTypeAnnotation(options, field, false, true, - /* singular_if_not_packed */ false, BYTES_U8), - "reader", JSBinaryReaderMethodType(field)); - } else { - printer->Print( - " var value = /** @type {$fieldtype$} */ " - "(reader.read$reader$());\n", - "fieldtype", - JSFieldTypeAnnotation(options, field, false, true, - /* singular_if_not_packed */ true, BYTES_U8), - "reader", - JSBinaryReadWriteMethodName(field, /* is_writer = */ false)); - } - - if (field->is_packable()) { - printer->Print( - " for (var i = 0; i < values.length; i++) {\n" - " msg.add$name$(values[i]);\n" - " }\n", - "name", - JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true)); - } else if (field->is_repeated()) { - printer->Print( - " msg.add$name$(value);\n", "name", - JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true)); - } else { - // Singular fields, and packed repeated fields, receive a |value| either - // as the field's value or as the array of all the field's values; set - // this as the field's value directly. - printer->Print(" msg.set$name$(value);\n", "name", - JSGetterName(options, field)); - } - } - - printer->Print(" break;\n"); -} - -void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const { - printer->Print( - "/**\n" - " * Serializes the message to binary data (in protobuf wire format).\n" - " * @return {!Uint8Array}\n" - " */\n" - "$class$.prototype.serializeBinary = function() {\n" - " var writer = new jspb.BinaryWriter();\n" - " $class$.serializeBinaryToWriter(this, writer);\n" - " return writer.getResultBuffer();\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Serializes the given message to binary data (in protobuf wire\n" - " * format), writing to the given BinaryWriter.\n" - " * @param {!$class$} message\n" - " * @param {!jspb.BinaryWriter} writer\n" - " * @suppress {unusedLocalVariables} f is only used for nested messages\n" - " */\n" - "$class$.serializeBinaryToWriter = function(message, " - "writer) {\n" - " var f = undefined;\n", - "class", GetMessagePath(options, desc)); - - for (int i = 0; i < desc->field_count(); i++) { - if (!IgnoreField(desc->field(i))) { - GenerateClassSerializeBinaryField(options, printer, desc->field(i)); - } - } - - if (IsExtendable(desc)) { - printer->Print( - " jspb.Message.serializeBinaryExtensions(message, writer,\n" - " $extobj$Binary, $class$.prototype.getExtension);\n", - "extobj", JSExtensionsObjectName(options, desc->file(), desc), "class", - GetMessagePath(options, desc)); - } - - printer->Print( - "};\n" - "\n" - "\n"); -} - -void Generator::GenerateClassSerializeBinaryField( - const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const { - if (HasFieldPresence(options, field) && - field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - std::string typed_annotation = - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ false, - /* singular_if_not_packed = */ false, - /* bytes_mode = */ BYTES_DEFAULT); - printer->Print( - " f = /** @type {$type$} */ " - "(jspb.Message.getField(message, $index$));\n", - "index", JSFieldIndex(field), "type", typed_annotation); - } else { - printer->Print( - " f = message.get$name$($nolazy$);\n", "name", - JSGetterName(options, field, BYTES_U8), - // No lazy creation for maps containers -- fastpath the empty case. - "nolazy", field->is_map() ? "true" : ""); - } - - // Print an `if (condition)` statement that evaluates to true if the field - // goes on the wire. - if (field->is_map()) { - printer->Print(" if (f && f.getLength() > 0) {\n"); - } else if (field->is_repeated()) { - printer->Print(" if (f.length > 0) {\n"); - } else { - if (HasFieldPresence(options, field)) { - printer->Print(" if (f != null) {\n"); - } else { - // No field presence: serialize onto the wire only if value is - // non-default. Defaults are documented here: - // https://goto.google.com/lhdfm - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - case FieldDescriptor::CPPTYPE_INT64: - case FieldDescriptor::CPPTYPE_UINT32: - case FieldDescriptor::CPPTYPE_UINT64: { - if (IsIntegralFieldWithStringJSType(field)) { - // We can use `parseInt` here even though it will not be precise for - // 64-bit quantities because we are only testing for zero/nonzero, - // and JS numbers (64-bit floating point values, i.e., doubles) are - // integer-precise in the range that includes zero. - printer->Print(" if (parseInt(f, 10) !== 0) {\n"); - } else { - printer->Print(" if (f !== 0) {\n"); - } - break; - } - - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_FLOAT: - case FieldDescriptor::CPPTYPE_DOUBLE: - printer->Print(" if (f !== 0.0) {\n"); - break; - case FieldDescriptor::CPPTYPE_BOOL: - printer->Print(" if (f) {\n"); - break; - case FieldDescriptor::CPPTYPE_STRING: - printer->Print(" if (f.length > 0) {\n"); - break; - default: - assert(false); - break; - } - } - } - - // Write the field on the wire. - if (field->is_map()) { - const FieldDescriptor* key_field = MapFieldKey(field); - const FieldDescriptor* value_field = MapFieldValue(field); - printer->Print( - " f.serializeBinary($index$, writer, " - "$keyWriterFn$, $valueWriterFn$", - "index", StrCat(field->number()), "keyWriterFn", - JSBinaryWriterMethodName(options, key_field), "valueWriterFn", - JSBinaryWriterMethodName(options, value_field)); - - if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(", $messageType$.serializeBinaryToWriter", "messageType", - GetMessagePath(options, value_field->message_type())); - } - - printer->Print(");\n"); - } else { - printer->Print( - " writer.write$method$(\n" - " $index$,\n" - " f", - "method", JSBinaryReadWriteMethodName(field, /* is_writer = */ true), - "index", StrCat(field->number())); - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_map()) { - printer->Print( - ",\n" - " $submsg$.serializeBinaryToWriter\n", - "submsg", SubmessageTypeRef(options, field)); - } else { - printer->Print("\n"); - } - - printer->Print(" );\n"); - } - - // Close the `if`. - printer->Print(" }\n"); -} - -void Generator::GenerateEnum(const GeneratorOptions& options, - io::Printer* printer, - const EnumDescriptor* enumdesc) const { - printer->Print( - "/**\n" - " * @enum {number}\n" - " */\n" - "$enumprefix$$name$ = {\n", - "enumprefix", GetEnumPathPrefix(options, enumdesc), "name", - enumdesc->name()); - printer->Annotate("name", enumdesc); - - std::set used_name; - std::vector valid_index; - for (int i = 0; i < enumdesc->value_count(); i++) { - if (enumdesc->options().allow_alias() && - !used_name.insert(ToEnumCase(enumdesc->value(i)->name())).second) { - continue; - } - valid_index.push_back(i); - } - for (auto i : valid_index) { - const EnumValueDescriptor* value = enumdesc->value(i); - printer->Print(" $name$: $value$$comma$\n", "name", - ToEnumCase(value->name()), "value", StrCat(value->number()), - "comma", (i == valid_index.back()) ? "" : ","); - printer->Annotate("name", value); - } - - printer->Print( - "};\n" - "\n"); -} - -void Generator::GenerateExtension(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const { - std::string extension_scope = - (field->extension_scope() - ? GetMessagePath(options, field->extension_scope()) - : GetNamespace(options, field->file())); - - const std::string extension_object_name = JSObjectFieldName(options, field); - printer->Print( - "\n" - "/**\n" - " * A tuple of {field number, class constructor} for the extension\n" - " * field named `$nameInComment$`.\n" - " * @type {!jspb.ExtensionFieldInfo<$extensionType$>}\n" - " */\n" - "$class$.$name$ = new jspb.ExtensionFieldInfo(\n", - "nameInComment", extension_object_name, "name", extension_object_name, - "class", extension_scope, "extensionType", - JSFieldTypeAnnotation(options, field, - /* is_setter_argument = */ false, - /* force_present = */ true, - /* singular_if_not_packed = */ false)); - printer->Annotate("name", field); - printer->Print( - " $index$,\n" - " {$name$: 0},\n" - " $ctor$,\n" - " /** @type {?function((boolean|undefined),!jspb.Message=): " - "!Object} */ (\n" - " $toObject$),\n" - " $repeated$);\n", - "index", StrCat(field->number()), "name", extension_object_name, "ctor", - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE - ? SubmessageTypeRef(options, field) - : std::string("null")), - "toObject", - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE - ? (SubmessageTypeRef(options, field) + ".toObject") - : std::string("null")), - "repeated", (field->is_repeated() ? "1" : "0")); - - printer->Print( - "\n" - "$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n" - " $class$.$name$,\n" - " $binaryReaderFn$,\n" - " $binaryWriterFn$,\n" - " $binaryMessageSerializeFn$,\n" - " $binaryMessageDeserializeFn$,\n", - "extendName", - JSExtensionsObjectName(options, field->file(), field->containing_type()), - "index", StrCat(field->number()), "class", extension_scope, "name", - extension_object_name, "binaryReaderFn", - JSBinaryReaderMethodName(options, field), "binaryWriterFn", - JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn", - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) - ? (SubmessageTypeRef(options, field) + ".serializeBinaryToWriter") - : "undefined", - "binaryMessageDeserializeFn", - (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) - ? (SubmessageTypeRef(options, field) + ".deserializeBinaryFromReader") - : "undefined"); - - printer->Print(" $isPacked$);\n", "isPacked", - (field->is_packed() ? "true" : "false")); - - printer->Print( - "// This registers the extension field with the extended class, so that\n" - "// toObject() will function correctly.\n" - "$extendName$[$index$] = $class$.$name$;\n" - "\n", - "extendName", - JSExtensionsObjectName(options, field->file(), field->containing_type()), - "index", StrCat(field->number()), "class", extension_scope, "name", - extension_object_name); -} - -bool GeneratorOptions::ParseFromOptions( - const std::vector >& options, - std::string* error) { - for (int i = 0; i < options.size(); i++) { - if (options[i].first == "add_require_for_enums") { - if (options[i].second != "") { - *error = "Unexpected option value for add_require_for_enums"; - return false; - } - add_require_for_enums = true; - } else if (options[i].first == "binary") { - if (options[i].second != "") { - *error = "Unexpected option value for binary"; - return false; - } - binary = true; - } else if (options[i].first == "testonly") { - if (options[i].second != "") { - *error = "Unexpected option value for testonly"; - return false; - } - testonly = true; - - } else if (options[i].first == "error_on_name_conflict") { - GOOGLE_LOG(WARNING) << "Ignoring error_on_name_conflict option, this " - "will be removed in a future release"; - } else if (options[i].first == "output_dir") { - output_dir = options[i].second; - } else if (options[i].first == "namespace_prefix") { - namespace_prefix = options[i].second; - } else if (options[i].first == "library") { - library = options[i].second; - } else if (options[i].first == "import_style") { - if (options[i].second == "closure") { - import_style = kImportClosure; - } else if (options[i].second == "commonjs") { - import_style = kImportCommonJs; - } else if (options[i].second == "commonjs_strict") { - import_style = kImportCommonJsStrict; - } else if (options[i].second == "browser") { - import_style = kImportBrowser; - } else if (options[i].second == "es6") { - import_style = kImportEs6; - } else { - *error = "Unknown import style " + options[i].second + ", expected " + - "one of: closure, commonjs, browser, es6."; - } - } else if (options[i].first == "extension") { - extension = options[i].second; - } else if (options[i].first == "one_output_file_per_input_file") { - if (!options[i].second.empty()) { - *error = "Unexpected option value for one_output_file_per_input_file"; - return false; - } - one_output_file_per_input_file = true; - } else if (options[i].first == "annotate_code") { - if (!options[i].second.empty()) { - *error = "Unexpected option value for annotate_code"; - return false; - } - annotate_code = true; - } else { - // Assume any other option is an output directory, as long as it is a bare - // `key` rather than a `key=value` option. - if (options[i].second != "") { - *error = "Unknown option: " + options[i].first; - return false; - } - output_dir = options[i].first; - } - } - - if (import_style != kImportClosure && - (add_require_for_enums || testonly || !library.empty() || - extension != ".js" || one_output_file_per_input_file)) { - *error = - "The add_require_for_enums, testonly, library, extension, and " - "one_output_file_per_input_file options should only be " - "used for import_style=closure"; - return false; - } - - return true; -} - -GeneratorOptions::OutputMode GeneratorOptions::output_mode() const { - // We use one output file per input file if we are not using Closure or if - // this is explicitly requested. - if (import_style != kImportClosure || one_output_file_per_input_file) { - return kOneOutputFilePerInputFile; - } - - // If a library name is provided, we put everything in that one file. - if (!library.empty()) { - return kEverythingInOneFile; - } - - // Otherwise, we create one output file per SCC. - return kOneOutputFilePerSCC; -} - -void Generator::GenerateFilesInDepOrder( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& files) const { - // Build a std::set over all files so that the DFS can detect when it recurses - // into a dep not specified in the user's command line. - std::set all_files(files.begin(), files.end()); - // Track the in-progress set of files that have been generated already. - std::set generated; - for (int i = 0; i < files.size(); i++) { - GenerateFileAndDeps(options, printer, files[i], &all_files, &generated); - } -} - -void Generator::GenerateFileAndDeps( - const GeneratorOptions& options, io::Printer* printer, - const FileDescriptor* root, std::set* all_files, - std::set* generated) const { - // Skip if already generated. - if (generated->find(root) != generated->end()) { - return; - } - generated->insert(root); - - // Generate all dependencies before this file's content. - for (int i = 0; i < root->dependency_count(); i++) { - const FileDescriptor* dep = root->dependency(i); - GenerateFileAndDeps(options, printer, dep, all_files, generated); - } - - // Generate this file's content. Only generate if the file is part of the - // original set requested to be generated; i.e., don't take all transitive - // deps down to the roots. - if (all_files->find(root) != all_files->end()) { - GenerateClassesAndEnums(options, printer, root); - } -} - -bool Generator::GenerateFile(const FileDescriptor* file, - const GeneratorOptions& options, - GeneratorContext* context, - bool use_short_name) const { - std::string filename = - options.output_dir + "/" + - GetJSFilename(options, use_short_name - ? file->name().substr(file->name().rfind('/')) - : file->name()); - std::unique_ptr output(context->Open(filename)); - GOOGLE_CHECK(output); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer(output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - GenerateFile(options, &printer, file); - - if (printer.failed()) { - return false; - } - - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - - return true; -} - -void Generator::GenerateFile(const GeneratorOptions& options, - io::Printer* printer, - const FileDescriptor* file) const { - GenerateHeader(options, file, printer); - - // Generate "require" statements. - if ((options.import_style == GeneratorOptions::kImportCommonJs || - options.import_style == GeneratorOptions::kImportCommonJsStrict)) { - printer->Print("var jspb = require('google-protobuf');\n"); - printer->Print("var goog = jspb;\n"); - - // Do not use global scope in strict mode - if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { - printer->Print("var proto = {};\n\n"); - } else { - // To get the global object we call a function with .call(null), this will - // set "this" inside the function to the global object. This does not work - // if we are running in strict mode ("use strict"), so we fallback to the - // following things (in order from first to last): - // - window: defined in browsers - // - global: defined in most server side environments like NodeJS - // - self: defined inside Web Workers (WorkerGlobalScope) - // - Function('return this')(): this will work on most platforms, but it - // may be blocked by things like CSP. - // Function('') is almost the same as eval('') - printer->Print( - "var global = (function() { return this || window || global || self " - "|| Function('return this')(); }).call(null);\n\n"); - } - - for (int i = 0; i < file->dependency_count(); i++) { - const std::string& name = file->dependency(i)->name(); - printer->Print( - "var $alias$ = require('$file$');\n" - "goog.object.extend(proto, $alias$);\n", - "alias", ModuleAlias(name), "file", - GetRootPath(file->name(), name) + GetJSFilename(options, name)); - } - } - - std::set provided; - std::set extensions; - for (int i = 0; i < file->extension_count(); i++) { - // We honor the jspb::ignore option here only when working with - // Closure-style imports. Use of this option is discouraged and so we want - // to avoid adding new support for it. - if (options.import_style == GeneratorOptions::kImportClosure && - IgnoreField(file->extension(i))) { - continue; - } - provided.insert(GetNamespace(options, file) + "." + - JSObjectFieldName(options, file->extension(i))); - extensions.insert(file->extension(i)); - } - - FindProvidesForFile(options, printer, file, &provided); - GenerateProvides(options, printer, &provided); - std::vector files; - files.push_back(file); - if (options.import_style == GeneratorOptions::kImportClosure) { - GenerateRequiresForLibrary(options, printer, files, &provided); - } - - GenerateClassesAndEnums(options, printer, file); - - // Generate code for top-level extensions. Extensions nested inside messages - // are emitted inside GenerateClassesAndEnums(). - for (std::set::const_iterator it = extensions.begin(); - it != extensions.end(); ++it) { - GenerateExtension(options, printer, *it); - } - - // if provided is empty, do not export anything - if (options.import_style == GeneratorOptions::kImportCommonJs && - !provided.empty()) { - printer->Print("goog.object.extend(exports, $package$);\n", "package", - GetNamespace(options, file)); - } else if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { - printer->Print("goog.object.extend(exports, proto);\n", "package", - GetNamespace(options, file)); - } - - // Emit well-known type methods. - for (FileToc* toc = well_known_types_js; toc->name != NULL; toc++) { - std::string name = std::string("google/protobuf/") + toc->name; - if (name == StripProto(file->name()) + ".js") { - printer->Print(toc->data); - } - } -} - -bool Generator::GenerateAll(const std::vector& files, - const std::string& parameter, - GeneratorContext* context, - std::string* error) const { - std::vector > option_pairs; - ParseGeneratorParameter(parameter, &option_pairs); - GeneratorOptions options; - if (!options.ParseFromOptions(option_pairs, error)) { - return false; - } - - if (options.output_mode() == GeneratorOptions::kEverythingInOneFile) { - // All output should go in a single file. - std::string filename = options.output_dir + "/" + options.library + - options.GetFileNameExtension(); - std::unique_ptr output(context->Open(filename)); - GOOGLE_CHECK(output.get()); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer( - output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - // Pull out all extensions -- we need these to generate all - // provides/requires. - std::vector extensions; - for (int i = 0; i < files.size(); i++) { - for (int j = 0; j < files[i]->extension_count(); j++) { - const FieldDescriptor* extension = files[i]->extension(j); - extensions.push_back(extension); - } - } - - if (files.size() == 1) { - GenerateHeader(options, files[0], &printer); - } else { - GenerateHeader(options, nullptr, &printer); - } - - std::set provided; - FindProvides(options, &printer, files, &provided); - FindProvidesForFields(options, &printer, extensions, &provided); - GenerateProvides(options, &printer, &provided); - GenerateTestOnly(options, &printer); - GenerateRequiresForLibrary(options, &printer, files, &provided); - - GenerateFilesInDepOrder(options, &printer, files); - - for (int i = 0; i < extensions.size(); i++) { - if (ShouldGenerateExtension(extensions[i])) { - GenerateExtension(options, &printer, extensions[i]); - } - } - - if (printer.failed()) { - return false; - } - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - } else if (options.output_mode() == GeneratorOptions::kOneOutputFilePerSCC) { - std::set have_printed; - SCCAnalyzer analyzer; - std::map allowed_map; - if (!GenerateJspbAllowedMap(options, files, &allowed_map, &analyzer)) { - return false; - } - - bool generated = false; - for (int i = 0; i < files.size(); i++) { - const FileDescriptor* file = files[i]; - // Force well known type to generate in a whole file. - if (IsWellKnownTypeFile(file)) { - if (!GenerateFile(file, options, context, true)) { - return false; - } - generated = true; - continue; - } - for (int j = 0; j < file->message_type_count(); j++) { - const Descriptor* desc = file->message_type(j); - if (have_printed.count(desc) || - allowed_map.count(analyzer.GetSCC(desc)) == 0) { - continue; - } - - generated = true; - const SCC* scc = analyzer.GetSCC(desc); - const std::string& filename = allowed_map[scc]; - std::unique_ptr output( - context->Open(filename)); - GOOGLE_CHECK(output.get()); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer( - output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - GenerateHeader(options, file, &printer); - - std::set provided; - for (auto one_desc : scc->descriptors) { - if (one_desc->containing_type() == nullptr) { - FindProvidesForMessage(options, &printer, one_desc, &provided); - } - } - GenerateProvides(options, &printer, &provided); - GenerateTestOnly(options, &printer); - GenerateRequiresForSCC(options, &printer, scc, &provided); - - for (auto one_desc : scc->descriptors) { - if (one_desc->containing_type() == nullptr) { - GenerateClassConstructorAndDeclareExtensionFieldInfo( - options, &printer, one_desc); - } - } - for (auto one_desc : scc->descriptors) { - if (one_desc->containing_type() == nullptr) { - GenerateClass(options, &printer, one_desc); - } - } - - for (auto one_desc : scc->descriptors) { - have_printed.insert(one_desc); - } - - if (printer.failed()) { - return false; - } - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - } - for (int j = 0; j < file->enum_type_count(); j++) { - const EnumDescriptor* enumdesc = file->enum_type(j); - if (allowed_map.count(enumdesc) == 0) { - continue; - } - - generated = true; - const std::string& filename = allowed_map[enumdesc]; - std::unique_ptr output( - context->Open(filename)); - GOOGLE_CHECK(output.get()); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer( - output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - GenerateHeader(options, file, &printer); - - std::set provided; - FindProvidesForEnum(options, &printer, enumdesc, &provided); - GenerateProvides(options, &printer, &provided); - GenerateTestOnly(options, &printer); - - GenerateEnum(options, &printer, enumdesc); - - if (printer.failed()) { - return false; - } - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - } - // File-level extensions (message-level extensions are generated under - // the enclosing message). - if (allowed_map.count(file) == 1) { - generated = true; - const std::string& filename = allowed_map[file]; - - std::unique_ptr output( - context->Open(filename)); - GOOGLE_CHECK(output.get()); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - io::Printer printer( - output.get(), '$', - options.annotate_code ? &annotation_collector : nullptr); - - GenerateHeader(options, file, &printer); - - std::set provided; - std::vector fields; - - for (int j = 0; j < files[i]->extension_count(); j++) { - if (ShouldGenerateExtension(files[i]->extension(j))) { - fields.push_back(files[i]->extension(j)); - } - } - - FindProvidesForFields(options, &printer, fields, &provided); - GenerateProvides(options, &printer, &provided); - GenerateTestOnly(options, &printer); - GenerateRequiresForExtensions(options, &printer, fields, &provided); - - for (int j = 0; j < files[i]->extension_count(); j++) { - if (ShouldGenerateExtension(files[i]->extension(j))) { - GenerateExtension(options, &printer, files[i]->extension(j)); - } - } - if (options.annotate_code) { - EmbedCodeAnnotations(annotations, &printer); - } - } - } - if (!generated) { - std::string filename = options.output_dir + "/" + - "empty_no_content_void_file" + - options.GetFileNameExtension(); - std::unique_ptr output(context->Open(filename)); - } - } else /* options.output_mode() == kOneOutputFilePerInputFile */ { - // Generate one output file per input (.proto) file. - - for (int i = 0; i < files.size(); i++) { - const FileDescriptor* file = files[i]; - if (!GenerateFile(file, options, context, false)) { - return false; - } - } - } - return true; -} - -} // namespace js -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/js/js_generator.h b/src/google/protobuf/compiler/js/js_generator.h deleted file mode 100644 index c7a942a8c..000000000 --- a/src/google/protobuf/compiler/js/js_generator.h +++ /dev/null @@ -1,336 +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. - -// Generates JavaScript code for a given .proto file. -// -#ifndef GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__ - -#include -#include - -#include -#include -#include -#include - -#include - -namespace google { -namespace protobuf { - -class Descriptor; -class EnumDescriptor; -class FieldDescriptor; -class OneofDescriptor; -class FileDescriptor; - -namespace io { -class Printer; -} - -namespace compiler { -namespace js { - -struct GeneratorOptions { - // Output path. - std::string output_dir; - // Namespace prefix. - std::string namespace_prefix; - // Enable binary-format support? - bool binary; - // What style of imports should be used. - enum ImportStyle { - kImportClosure, // goog.require() - kImportCommonJs, // require() - kImportCommonJsStrict, // require() with no global export - kImportBrowser, // no import statements - kImportEs6, // import { member } from '' - } import_style; - - GeneratorOptions() - : output_dir("."), - namespace_prefix(""), - binary(false), - import_style(kImportClosure), - add_require_for_enums(false), - testonly(false), - library(""), - extension(".js"), - one_output_file_per_input_file(false), - annotate_code(false) {} - - bool ParseFromOptions( - const std::vector >& options, - std::string* error); - - // Returns the file name extension to use for generated code. - std::string GetFileNameExtension() const { - return import_style == kImportClosure ? extension : "_pb.js"; - } - - enum OutputMode { - // Create an output file for each input .proto file. - kOneOutputFilePerInputFile, - // Create an output file for each type. - kOneOutputFilePerSCC, - // Put everything in a single file named by the library option. - kEverythingInOneFile, - }; - - // Indicates how to output the generated code based on the provided options. - OutputMode output_mode() const; - - // The remaining options are only relevant when we are using kImportClosure. - - // Add a `goog.requires()` call for each enum type used. If not set, a - // forward declaration with `goog.forwardDeclare` is produced instead. - bool add_require_for_enums; - // Set this as a test-only module via `goog.setTestOnly();`. - bool testonly; - // Create a library with name _lib.js rather than a separate .js file - // per type? - std::string library; - // The extension to use for output file names. - std::string extension; - // Create a separate output file for each input file? - bool one_output_file_per_input_file; - // If true, we should append annotations as comments on the last line for - // generated .js file. Annotations used by tools like https://kythe.io - // to provide cross-references between .js and .proto files. Annotations - // are encoded as base64 proto of GeneratedCodeInfo message (see - // descriptor.proto). - bool annotate_code; -}; - -// CodeGenerator implementation which generates a JavaScript source file and -// header. If you create your own protocol compiler binary and you want it to -// support JavaScript output, you can do so by registering an instance of this -// CodeGenerator with the CommandLineInterface in your main() function. -class PROTOC_EXPORT Generator : public CodeGenerator { - public: - Generator() {} - virtual ~Generator() {} - - bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* context, std::string* error) const override { - *error = "Unimplemented Generate() method. Call GenerateAll() instead."; - return false; - } - - bool HasGenerateAll() const override { return true; } - - bool GenerateAll(const std::vector& files, - const std::string& parameter, GeneratorContext* context, - std::string* error) const override; - - uint64_t GetSupportedFeatures() const override { - return FEATURE_PROTO3_OPTIONAL; - } - - private: - void GenerateHeader(const GeneratorOptions& options, - const FileDescriptor* file, io::Printer* printer) const; - - // Generate goog.provides() calls. - void FindProvides(const GeneratorOptions& options, io::Printer* printer, - const std::vector& file, - std::set* provided) const; - void FindProvidesForFile(const GeneratorOptions& options, - io::Printer* printer, const FileDescriptor* file, - std::set* provided) const; - void FindProvidesForMessage(const GeneratorOptions& options, - io::Printer* printer, const Descriptor* desc, - std::set* provided) const; - void FindProvidesForEnum(const GeneratorOptions& options, - io::Printer* printer, const EnumDescriptor* enumdesc, - std::set* provided) const; - // For extension fields at file scope. - void FindProvidesForFields(const GeneratorOptions& options, - io::Printer* printer, - const std::vector& fields, - std::set* provided) const; - // Print the goog.provides() found by the methods above. - void GenerateProvides(const GeneratorOptions& options, io::Printer* printer, - std::set* provided) const; - - // Generate goog.setTestOnly() if indicated. - void GenerateTestOnly(const GeneratorOptions& options, - io::Printer* printer) const; - - // Generate goog.requires() calls. - void GenerateRequiresForLibrary( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& files, - std::set* provided) const; - void GenerateRequiresForSCC(const GeneratorOptions& options, - io::Printer* printer, const SCC* scc, - std::set* provided) const; - // For extension fields at file scope. - void GenerateRequiresForExtensions( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& fields, - std::set* provided) const; - void GenerateRequiresImpl(const GeneratorOptions& options, - io::Printer* printer, - std::set* required, - std::set* forwards, - std::set* provided, bool require_jspb, - bool require_extension, bool require_map) const; - void FindRequiresForMessage(const GeneratorOptions& options, - const Descriptor* desc, - std::set* required, - std::set* forwards, - bool* have_message) const; - void FindRequiresForField(const GeneratorOptions& options, - const FieldDescriptor* field, - std::set* required, - std::set* forwards) const; - void FindRequiresForExtension(const GeneratorOptions& options, - const FieldDescriptor* field, - std::set* required, - std::set* forwards) const; - // Generate all things in a proto file into one file. - // If use_short_name is true, the generated file's name will only be short - // name that without directory, otherwise filename equals file->name() - bool GenerateFile(const FileDescriptor* file, const GeneratorOptions& options, - GeneratorContext* context, bool use_short_name) const; - void GenerateFile(const GeneratorOptions& options, io::Printer* printer, - const FileDescriptor* file) const; - - // Generate definitions for all message classes and enums in all files, - // processing the files in dependence order. - void GenerateFilesInDepOrder( - const GeneratorOptions& options, io::Printer* printer, - const std::vector& file) const; - // Helper for above. - void GenerateFileAndDeps(const GeneratorOptions& options, - io::Printer* printer, const FileDescriptor* root, - std::set* all_files, - std::set* generated) const; - - // Generate definitions for all message classes and enums. - void GenerateClassesAndEnums(const GeneratorOptions& options, - io::Printer* printer, - const FileDescriptor* file) const; - - void GenerateFieldValueExpression(io::Printer* printer, - const char* obj_reference, - const FieldDescriptor* field, - bool use_default) const; - - // Generate definition for one class. - void GenerateClass(const GeneratorOptions& options, io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassConstructor(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassFieldInfo(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassConstructorAndDeclareExtensionFieldInfo( - const GeneratorOptions& options, io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassXid(const GeneratorOptions& options, io::Printer* printer, - const Descriptor* desc) const; - void GenerateOneofCaseDefinition(const GeneratorOptions& options, - io::Printer* printer, - const OneofDescriptor* oneof) const; - void GenerateObjectTypedef(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassToObject(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassFieldToObject(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - void GenerateClassFromObject(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassFieldFromObject(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - void GenerateClassRegistration(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassFields(const GeneratorOptions& options, - io::Printer* printer, const Descriptor* desc) const; - void GenerateClassField(const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* desc) const; - void GenerateClassExtensionFieldInfo(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassDeserialize(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassDeserializeBinary(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassDeserializeBinaryField(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - void GenerateClassSerializeBinary(const GeneratorOptions& options, - io::Printer* printer, - const Descriptor* desc) const; - void GenerateClassSerializeBinaryField(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - - // Generate definition for one enum. - void GenerateEnum(const GeneratorOptions& options, io::Printer* printer, - const EnumDescriptor* enumdesc) const; - - // Generate an extension definition. - void GenerateExtension(const GeneratorOptions& options, io::Printer* printer, - const FieldDescriptor* field) const; - - // Generate addFoo() method for repeated primitive fields. - void GenerateRepeatedPrimitiveHelperMethods(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field, - bool untyped) const; - - // Generate addFoo() method for repeated message fields. - void GenerateRepeatedMessageHelperMethods(const GeneratorOptions& options, - io::Printer* printer, - const FieldDescriptor* field) const; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); -}; - -} // namespace js -} // namespace compiler -} // namespace protobuf -} // namespace google - -#include - -#endif // GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/js/well_known_types_embed.cc b/src/google/protobuf/compiler/js/well_known_types_embed.cc deleted file mode 100644 index 5cb73657e..000000000 --- a/src/google/protobuf/compiler/js/well_known_types_embed.cc +++ /dev/null @@ -1,270 +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. - -#include - -struct FileToc well_known_types_js[] = { - {"any.js", - "/* This code will be inserted into generated code for\n" - " * google/protobuf/any.proto. */\n" - "\n" - "/**\n" - " * Returns the type name contained in this instance, if any.\n" - " * @return {string|undefined}\n" - " */\n" - "proto.google.protobuf.Any.prototype.getTypeName = function() {\n" - " return this.getTypeUrl().split('/').pop();\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Packs the given message instance into this Any.\n" - " * For binary format usage only.\n" - " * @param {!Uint8Array} serialized The serialized data to pack.\n" - " * @param {string} name The type name of this message object.\n" - " * @param {string=} opt_typeUrlPrefix the type URL prefix.\n" - " */\n" - "proto.google.protobuf.Any.prototype.pack = function(serialized, name,\n" - " opt_typeUrlPrefix) " - "{\n" - " if (!opt_typeUrlPrefix) {\n" - " opt_typeUrlPrefix = 'type.googleapis.com/';\n" - " }\n" - "\n" - " if (opt_typeUrlPrefix.substr(-1) != '/') {\n" - " this.setTypeUrl(opt_typeUrlPrefix + '/' + name);\n" - " } else {\n" - " this.setTypeUrl(opt_typeUrlPrefix + name);\n" - " }\n" - "\n" - " this.setValue(serialized);\n" - "};\n" - "\n" - "\n" - "/**\n" - " * @template T\n" - " * Unpacks this Any into the given message object.\n" - " * @param {function(Uint8Array):T} deserialize Function that will " - "deserialize\n" - " * the binary data properly.\n" - " * @param {string} name The expected type name of this message object.\n" - " * @return {?T} If the name matched the expected name, returns the " - "deserialized\n" - " * object, otherwise returns null.\n" - " */\n" - "proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) " - "{\n" - " if (this.getTypeName() == name) {\n" - " return deserialize(this.getValue_asU8());\n" - " } else {\n" - " return null;\n" - " }\n" - "};\n" - }, - {"timestamp.js", - "/* This code will be inserted into generated code for\n" - " * google/protobuf/timestamp.proto. */\n" - "\n" - "/**\n" - " * Returns a JavaScript 'Date' object corresponding to this Timestamp.\n" - " * @return {!Date}\n" - " */\n" - "proto.google.protobuf.Timestamp.prototype.toDate = function() {\n" - " var seconds = this.getSeconds();\n" - " var nanos = this.getNanos();\n" - "\n" - " return new Date((seconds * 1000) + (nanos / 1000000));\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Sets the value of this Timestamp object to be the given Date.\n" - " * @param {!Date} value The value to set.\n" - " */\n" - "proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {\n" - " this.setSeconds(Math.floor(value.getTime() / 1000));\n" - " this.setNanos(value.getMilliseconds() * 1000000);\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Factory method that returns a Timestamp object with value equal to\n" - " * the given Date.\n" - " * @param {!Date} value The value to set.\n" - " * @return {!proto.google.protobuf.Timestamp}\n" - " */\n" - "proto.google.protobuf.Timestamp.fromDate = function(value) {\n" - " var timestamp = new proto.google.protobuf.Timestamp();\n" - " timestamp.fromDate(value);\n" - " return timestamp;\n" - "};\n"}, - {"struct.js", - "/* This code will be inserted into generated code for\n" - " * google/protobuf/struct.proto. */\n" - "\n" - "/**\n" - " * Typedef representing plain JavaScript values that can go into a\n" - " * Struct.\n" - " * @typedef {null|number|string|boolean|Array|Object}\n" - " */\n" - "proto.google.protobuf.JavaScriptValue;\n" - "\n" - "\n" - "/**\n" - " * Converts this Value object to a plain JavaScript value.\n" - " * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript\n" - " * value representing this Struct.\n" - " */\n" - "proto.google.protobuf.Value.prototype.toJavaScript = function() {\n" - " var kindCase = proto.google.protobuf.Value.KindCase;\n" - " switch (this.getKindCase()) {\n" - " case kindCase.NULL_VALUE:\n" - " return null;\n" - " case kindCase.NUMBER_VALUE:\n" - " return this.getNumberValue();\n" - " case kindCase.STRING_VALUE:\n" - " return this.getStringValue();\n" - " case kindCase.BOOL_VALUE:\n" - " return this.getBoolValue();\n" - " case kindCase.STRUCT_VALUE:\n" - " return this.getStructValue().toJavaScript();\n" - " case kindCase.LIST_VALUE:\n" - " return this.getListValue().toJavaScript();\n" - " default:\n" - " throw new Error('Unexpected struct type');\n" - " }\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Converts this JavaScript value to a new Value proto.\n" - " * @param {!proto.google.protobuf.JavaScriptValue} value The value to\n" - " * convert.\n" - " * @return {!proto.google.protobuf.Value} The newly constructed value.\n" - " */\n" - "proto.google.protobuf.Value.fromJavaScript = function(value) {\n" - " var ret = new proto.google.protobuf.Value();\n" - " switch (goog.typeOf(value)) {\n" - " case 'string':\n" - " ret.setStringValue(/** @type {string} */ (value));\n" - " break;\n" - " case 'number':\n" - " ret.setNumberValue(/** @type {number} */ (value));\n" - " break;\n" - " case 'boolean':\n" - " ret.setBoolValue(/** @type {boolean} */ (value));\n" - " break;\n" - " case 'null':\n" - " ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE);\n" - " break;\n" - " case 'array':\n" - " ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript(\n" - " /** @type{!Array} */ (value)));\n" - " break;\n" - " case 'object':\n" - " ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript(\n" - " /** @type{!Object} */ (value)));\n" - " break;\n" - " default:\n" - " throw new Error('Unexpected struct type.');\n" - " }\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Converts this ListValue object to a plain JavaScript array.\n" - " * @return {!Array} a plain JavaScript array representing this List.\n" - " */\n" - "proto.google.protobuf.ListValue.prototype.toJavaScript = function() {\n" - " var ret = [];\n" - " var values = this.getValuesList();\n" - "\n" - " for (var i = 0; i < values.length; i++) {\n" - " ret[i] = values[i].toJavaScript();\n" - " }\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Constructs a ListValue protobuf from this plain JavaScript array.\n" - " * @param {!Array} array a plain JavaScript array\n" - " * @return {proto.google.protobuf.ListValue} a new ListValue object\n" - " */\n" - "proto.google.protobuf.ListValue.fromJavaScript = function(array) {\n" - " var ret = new proto.google.protobuf.ListValue();\n" - "\n" - " for (var i = 0; i < array.length; i++) {\n" - " " - "ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i]));\n" - " }\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Converts this Struct object to a plain JavaScript object.\n" - " * @return {!Object} a " - "plain\n" - " * JavaScript object representing this Struct.\n" - " */\n" - "proto.google.protobuf.Struct.prototype.toJavaScript = function() {\n" - " var ret = {};\n" - "\n" - " this.getFieldsMap().forEach(function(value, key) {\n" - " ret[key] = value.toJavaScript();\n" - " });\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Constructs a Struct protobuf from this plain JavaScript object.\n" - " * @param {!Object} obj a plain JavaScript object\n" - " * @return {proto.google.protobuf.Struct} a new Struct object\n" - " */\n" - "proto.google.protobuf.Struct.fromJavaScript = function(obj) {\n" - " var ret = new proto.google.protobuf.Struct();\n" - " var map = ret.getFieldsMap();\n" - "\n" - " for (var property in obj) {\n" - " var val = obj[property];\n" - " map.set(property, proto.google.protobuf.Value.fromJavaScript(val));\n" - " }\n" - "\n" - " return ret;\n" - "};\n"}, - {NULL, NULL} // Terminate the list. -}; diff --git a/src/google/protobuf/compiler/js/well_known_types_embed.h b/src/google/protobuf/compiler/js/well_known_types_embed.h deleted file mode 100644 index 174c665e4..000000000 --- a/src/google/protobuf/compiler/js/well_known_types_embed.h +++ /dev/null @@ -1,43 +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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__ -#define GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__ - -#include - -struct FileToc { - const char* name; - const char* data; -}; - -extern struct FileToc well_known_types_js[]; - -#endif // GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__ diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index dacab7cde..39609468a 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -102,11 +101,6 @@ int ProtobufMain(int argc, char* argv[]) { cli.RegisterGenerator("--objc_out", "--objc_opt", &objc_generator, "Generate Objective-C header and source."); - // JavaScript - js::Generator js_generator; - cli.RegisterGenerator("--js_out", "--js_opt", &js_generator, - "Generate JavaScript source."); - return cli.Run(argc, argv); } diff --git a/tests.sh b/tests.sh index 132d0bea9..7bc11254b 100755 --- a/tests.sh +++ b/tests.sh @@ -57,7 +57,7 @@ build_cpp_distcheck() { make dist # List all files that should be included in the distribution package. - git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|php\|cmake\|examples\|src/google/protobuf/.*\.proto\)" |\ + git ls-files | grep "^\(java\|python\|objectivec\|csharp\|ruby\|php\|cmake\|examples\|src/google/protobuf/.*\.proto\)" |\ grep -v ".gitignore" | grep -v "java/lite/proguard.pgcfg" |\ grep -v "python/compatibility_tests" | grep -v "python/docs" | grep -v "python/.repo-metadata.json" |\ grep -v "python/protobuf_distutils" | grep -v "csharp/compatibility_tests" > dist.lst @@ -460,19 +460,6 @@ build_jruby93() { cd ruby && bash travis-test.sh jruby-9.3.4.0 && cd .. } -build_javascript() { - internal_build_cpp - NODE_VERSION=node-v12.16.3-darwin-x64 - NODE_TGZ="$NODE_VERSION.tar.gz" - pushd /tmp - curl -OL https://nodejs.org/dist/v12.16.3/$NODE_TGZ - tar zxvf $NODE_TGZ - export PATH=$PATH:`pwd`/$NODE_VERSION/bin - popd - cd js && npm install && npm test && cd .. - cd conformance && make test_nodejs && cd .. -} - use_php() { VERSION=$1 export PATH=/usr/local/php-${VERSION}/bin:$PATH diff --git a/update_version.py b/update_version.py index e1f259eb8..0ab9cc098 100755 --- a/update_version.py +++ b/update_version.py @@ -288,14 +288,6 @@ def UpdateJava(): line)) -def UpdateJavaScript(): - RewriteTextFile('js/package.json', - lambda line : re.sub( - r'^ "version": ".*",$', - ' "version": "%s",' % GetFullVersion(rc_suffix = '-rc.'), - line)) - - def UpdateMakefile(): RewriteTextFile('src/Makefile.am', lambda line : re.sub( @@ -405,7 +397,6 @@ UpdateConfigure() UpdateCsharp() UpdateCpp() UpdateJava() -UpdateJavaScript() UpdateMakefile() UpdateObjectiveC() UpdatePhp()