diff options
169 files changed, 8408 insertions, 1133 deletions
@@ -84,6 +84,8 @@ src/**/*.trs java/core/target java/util/target javanano/target +java/.idea +java/**/*.iml # Windows native output. cmake/build @@ -113,9 +115,11 @@ conformance/conformance.pb.cc conformance/conformance.pb.h conformance/Conformance.pbobjc.h conformance/Conformance.pbobjc.m +conformance/conformance_pb.js conformance/conformance_pb.rb conformance/failing_tests.txt conformance/google/ +conformance/google-protobuf/ conformance/javac_middleman conformance/lite/ conformance/nonexistent_tests.txt @@ -146,8 +150,15 @@ 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_libs.js +js/testproto_libs1.js +js/testproto_libs2.js @@ -145,6 +145,7 @@ cc_library( "src/google/protobuf/timestamp.pb.cc", "src/google/protobuf/type.pb.cc", "src/google/protobuf/unknown_field_set.cc", + "src/google/protobuf/util/delimited_message_util.cc", "src/google/protobuf/util/field_comparator.cc", "src/google/protobuf/util/field_mask_util.cc", "src/google/protobuf/util/internal/datapiece.cc", @@ -521,6 +522,7 @@ cc_test( "src/google/protobuf/stubs/type_traits_unittest.cc", "src/google/protobuf/text_format_unittest.cc", "src/google/protobuf/unknown_field_set_unittest.cc", + "src/google/protobuf/util/delimited_message_util_test.cc", "src/google/protobuf/util/field_comparator_test.cc", "src/google/protobuf/util/field_mask_util_test.cc", "src/google/protobuf/util/internal/default_value_objectwriter_test.cc", @@ -568,6 +570,7 @@ java_library( ]) + [ ":gen_well_known_protos_java", ], + javacopts = ["-source 6"], visibility = ["//visibility:public"], ) diff --git a/Makefile.am b/Makefile.am index 3222417f..a9927e9e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -584,6 +584,21 @@ objectivec_EXTRA_DIST= \ Protobuf.podspec php_EXTRA_DIST= \ + php/ext/google/protobuf/utf8.h \ + php/ext/google/protobuf/message.c \ + php/ext/google/protobuf/utf8.c \ + php/ext/google/protobuf/package.xml \ + php/ext/google/protobuf/upb.h \ + php/ext/google/protobuf/array.c \ + php/ext/google/protobuf/encode_decode.c \ + php/ext/google/protobuf/protobuf.h \ + php/ext/google/protobuf/type_check.c \ + php/ext/google/protobuf/def.c \ + php/ext/google/protobuf/storage.c \ + php/ext/google/protobuf/map.c \ + php/ext/google/protobuf/config.m4 \ + php/ext/google/protobuf/upb.c \ + php/ext/google/protobuf/protobuf.c \ php/src/phpdoc.dist.xml \ php/src/Google/Protobuf/Internal/DescriptorPool.php \ php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php \ @@ -632,39 +647,26 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/Internal/FieldOptions_CType.php \ php/src/Google/Protobuf/descriptor.php \ php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php \ + php/tests/array_test.php \ php/tests/autoload.php \ php/tests/encode_decode_test.php \ - php/tests/test.sh \ php/tests/gdb_test.sh \ php/tests/generated_class_test.php \ - php/tests/array_test.php \ + php/tests/map_field_test.php \ + php/tests/memory_leak_test.php \ php/tests/php_implementation_test.php \ php/tests/proto/test_include.proto \ - php/tests/map_field_test.php \ - php/tests/test_base.php \ + php/tests/proto/test.proto \ + php/tests/proto/test_prefix.proto \ php/tests/proto/test_no_namespace.proto \ + php/tests/test.sh \ + php/tests/test_base.php \ php/tests/test_util.php \ - php/tests/proto/test.proto \ - php/tests/memory_leak_test.php \ php/tests/well_known_test.php \ php/README.md \ - php/ext/google/protobuf/utf8.h \ - php/ext/google/protobuf/message.c \ - php/ext/google/protobuf/utf8.c \ - php/ext/google/protobuf/package.xml \ - php/ext/google/protobuf/upb.h \ - php/ext/google/protobuf/array.c \ - php/ext/google/protobuf/encode_decode.c \ - php/ext/google/protobuf/protobuf.h \ - php/ext/google/protobuf/type_check.c \ - php/ext/google/protobuf/def.c \ - php/ext/google/protobuf/storage.c \ - php/ext/google/protobuf/map.c \ - php/ext/google/protobuf/config.m4 \ - php/ext/google/protobuf/upb.c \ - php/ext/google/protobuf/protobuf.c \ php/phpunit.xml \ php/composer.json \ + php/generate_descriptor_protos.sh \ composer.json python_EXTRA_DIST= \ @@ -829,51 +831,80 @@ ruby_EXTRA_DIST= \ ruby/tests/well_known_types_test.rb \ ruby/travis-test.sh -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/test6/test6.proto \ - js/commonjs/test7/test7.proto \ - js/data.proto \ - js/debug.js \ - js/debug_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/test_bootstrap.js \ - js/testbinary.proto \ +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/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/data.proto \ + js/debug.js \ + js/debug_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/test_bootstrap.js \ + js/testbinary.proto \ js/testempty.proto all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(javanano_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) $(js_EXTRA_DIST) diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index 87cbc951..a4fd7622 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -14,114 +14,114 @@ mkdir include\google\protobuf\compiler\ruby mkdir include\google\protobuf\io mkdir include\google\protobuf\stubs mkdir include\google\protobuf\util -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.h include\google\protobuf\any.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.pb.h include\google\protobuf\any.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.pb.h include\google\protobuf\api.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena.h include\google\protobuf\arena.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenastring.h include\google\protobuf\arenastring.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h include\google\protobuf\compiler\code_generator.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h include\google\protobuf\compiler\command_line_interface.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h include\google\protobuf\compiler\csharp\csharp_generator.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_names.h include\google\protobuf\compiler\csharp\csharp_names.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h include\google\protobuf\compiler\java\java_names.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\javanano\javanano_generator.h include\google\protobuf\compiler\javanano\javanano_generator.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\js\well_known_types_embed.h include\google\protobuf\compiler\js\well_known_types_embed.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 -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\php\php_generator.h include\google\protobuf\compiler\php\php_generator.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h include\google\protobuf\compiler\plugin.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h include\google\protobuf\compiler\plugin.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_generator.h include\google\protobuf\compiler\python\python_generator.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h include\google\protobuf\compiler\ruby\ruby_generator.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h include\google\protobuf\descriptor.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.pb.h include\google\protobuf\descriptor.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor_database.h include\google\protobuf\descriptor_database.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\duration.pb.h include\google\protobuf\duration.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\dynamic_message.h include\google\protobuf\dynamic_message.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.pb.h include\google\protobuf\empty.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set.h include\google\protobuf\extension_set.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_mask.pb.h include\google\protobuf\field_mask.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflection.h include\google\protobuf\generated_enum_reflection.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h include\google\protobuf\generated_enum_util.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h include\google\protobuf\generated_message_reflection.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h include\google\protobuf\generated_message_util.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h include\google\protobuf\has_bits.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h include\google\protobuf\io\coded_stream.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h include\google\protobuf\io\gzip_stream.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\printer.h include\google\protobuf\io\printer.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\strtod.h include\google\protobuf\io\strtod.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\tokenizer.h include\google\protobuf\io\tokenizer.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream.h include\google\protobuf\io\zero_copy_stream.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl.h include\google\protobuf\io\zero_copy_stream_impl.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl_lite.h include\google\protobuf\io\zero_copy_stream_impl_lite.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map.h include\google\protobuf\map.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry.h include\google\protobuf\map_entry.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry_lite.h include\google\protobuf\map_entry_lite.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field.h include\google\protobuf\map_field.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_inl.h include\google\protobuf\map_field_inl.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_lite.h include\google\protobuf\map_field_lite.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_type_handler.h include\google\protobuf\map_type_handler.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message.h include\google\protobuf\message.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message_lite.h include\google\protobuf\message_lite.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata.h include\google\protobuf\metadata.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection.h include\google\protobuf\reflection.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection_ops.h include\google\protobuf\reflection_ops.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h include\google\protobuf\repeated_field.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\service.h include\google\protobuf\service.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.pb.h include\google\protobuf\source_context.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.pb.h include\google\protobuf\struct.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomic_sequence_num.h include\google\protobuf\stubs\atomic_sequence_num.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops.h include\google\protobuf\stubs\atomicops.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm64_gcc.h include\google\protobuf\stubs\atomicops_internals_arm64_gcc.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_gcc.h include\google\protobuf\stubs\atomicops_internals_arm_gcc.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_qnx.h include\google\protobuf\stubs\atomicops_internals_arm_qnx.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_atomicword_compat.h include\google\protobuf\stubs\atomicops_internals_atomicword_compat.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h include\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_gcc.h include\google\protobuf\stubs\atomicops_internals_generic_gcc.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_mips_gcc.h include\google\protobuf\stubs\atomicops_internals_mips_gcc.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_power.h include\google\protobuf\stubs\atomicops_internals_power.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_ppc_gcc.h include\google\protobuf\stubs\atomicops_internals_ppc_gcc.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_solaris.h include\google\protobuf\stubs\atomicops_internals_solaris.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_tsan.h include\google\protobuf\stubs\atomicops_internals_tsan.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_gcc.h include\google\protobuf\stubs\atomicops_internals_x86_gcc.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h include\google\protobuf\stubs\atomicops_internals_x86_msvc.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h include\google\protobuf\stubs\bytestream.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h include\google\protobuf\stubs\callback.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h include\google\protobuf\stubs\casts.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h include\google\protobuf\stubs\common.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h include\google\protobuf\stubs\fastmem.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h include\google\protobuf\stubs\hash.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h include\google\protobuf\stubs\logging.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h include\google\protobuf\stubs\macros.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h include\google\protobuf\stubs\mutex.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\once.h include\google\protobuf\stubs\once.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\platform_macros.h include\google\protobuf\stubs\platform_macros.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\port.h include\google\protobuf\stubs\port.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\scoped_ptr.h include\google\protobuf\stubs\scoped_ptr.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\shared_ptr.h include\google\protobuf\stubs\shared_ptr.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\singleton.h include\google\protobuf\stubs\singleton.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\status.h include\google\protobuf\stubs\status.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stl_util.h include\google\protobuf\stubs\stl_util.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stringpiece.h include\google\protobuf\stubs\stringpiece.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\template_util.h include\google\protobuf\stubs\template_util.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\type_traits.h include\google\protobuf\stubs\type_traits.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\text_format.h include\google\protobuf\text_format.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\timestamp.pb.h include\google\protobuf\timestamp.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.pb.h include\google\protobuf\type.pb.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\unknown_field_set.h include\google\protobuf\unknown_field_set.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_comparator.h include\google\protobuf\util\field_comparator.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_mask_util.h include\google\protobuf\util\field_mask_util.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\json_util.h include\google\protobuf\util\json_util.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\message_differencer.h include\google\protobuf\util\message_differencer.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\time_util.h include\google\protobuf\util\time_util.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver.h include\google\protobuf\util\type_resolver.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver_util.h include\google\protobuf\util\type_resolver_util.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format.h include\google\protobuf\wire_format.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite.h include\google\protobuf\wire_format_lite.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite_inl.h include\google\protobuf\wire_format_lite_inl.h -copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wrappers.pb.h include\google\protobuf\wrappers.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.h" include\google\protobuf\any.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.pb.h" include\google\protobuf\any.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.pb.h" include\google\protobuf\api.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arena.h" include\google\protobuf\arena.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\arenastring.h" include\google\protobuf\arenastring.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\code_generator.h" include\google\protobuf\compiler\code_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_interface.h" include\google\protobuf\compiler\command_line_interface.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h" include\google\protobuf\compiler\cpp\cpp_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h" include\google\protobuf\compiler\csharp\csharp_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_names.h" include\google\protobuf\compiler\csharp\csharp_names.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h" include\google\protobuf\compiler\importer.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h" include\google\protobuf\compiler\java\java_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h" include\google\protobuf\compiler\java\java_names.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\javanano\javanano_generator.h" include\google\protobuf\compiler\javanano\javanano_generator.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\js\well_known_types_embed.h" include\google\protobuf\compiler\js\well_known_types_embed.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 +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\php\php_generator.h" include\google\protobuf\compiler\php\php_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h" include\google\protobuf\compiler\plugin.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_generator.h" include\google\protobuf\compiler\python\python_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.pb.h" include\google\protobuf\descriptor.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor_database.h" include\google\protobuf\descriptor_database.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\duration.pb.h" include\google\protobuf\duration.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\dynamic_message.h" include\google\protobuf\dynamic_message.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.pb.h" include\google\protobuf\empty.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set.h" include\google\protobuf\extension_set.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_mask.pb.h" include\google\protobuf\field_mask.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflection.h" include\google\protobuf\generated_enum_reflection.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h" include\google\protobuf\generated_enum_util.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h" include\google\protobuf\io\gzip_stream.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\printer.h" include\google\protobuf\io\printer.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\strtod.h" include\google\protobuf\io\strtod.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\tokenizer.h" include\google\protobuf\io\tokenizer.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream.h" include\google\protobuf\io\zero_copy_stream.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl.h" include\google\protobuf\io\zero_copy_stream_impl.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\zero_copy_stream_impl_lite.h" include\google\protobuf\io\zero_copy_stream_impl_lite.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map.h" include\google\protobuf\map.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry.h" include\google\protobuf\map_entry.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_entry_lite.h" include\google\protobuf\map_entry_lite.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field.h" include\google\protobuf\map_field.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_inl.h" include\google\protobuf\map_field_inl.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_field_lite.h" include\google\protobuf\map_field_lite.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_type_handler.h" include\google\protobuf\map_type_handler.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message.h" include\google\protobuf\message.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message_lite.h" include\google\protobuf\message_lite.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata.h" include\google\protobuf\metadata.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection.h" include\google\protobuf\reflection.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection_ops.h" include\google\protobuf\reflection_ops.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h" include\google\protobuf\repeated_field.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\service.h" include\google\protobuf\service.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.pb.h" include\google\protobuf\source_context.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.pb.h" include\google\protobuf\struct.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomic_sequence_num.h" include\google\protobuf\stubs\atomic_sequence_num.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops.h" include\google\protobuf\stubs\atomicops.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm64_gcc.h" include\google\protobuf\stubs\atomicops_internals_arm64_gcc.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_gcc.h" include\google\protobuf\stubs\atomicops_internals_arm_gcc.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_qnx.h" include\google\protobuf\stubs\atomicops_internals_arm_qnx.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_atomicword_compat.h" include\google\protobuf\stubs\atomicops_internals_atomicword_compat.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h" include\google\protobuf\stubs\atomicops_internals_generic_c11_atomic.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_generic_gcc.h" include\google\protobuf\stubs\atomicops_internals_generic_gcc.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_mips_gcc.h" include\google\protobuf\stubs\atomicops_internals_mips_gcc.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_power.h" include\google\protobuf\stubs\atomicops_internals_power.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_ppc_gcc.h" include\google\protobuf\stubs\atomicops_internals_ppc_gcc.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_solaris.h" include\google\protobuf\stubs\atomicops_internals_solaris.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_tsan.h" include\google\protobuf\stubs\atomicops_internals_tsan.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_gcc.h" include\google\protobuf\stubs\atomicops_internals_x86_gcc.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h" include\google\protobuf\stubs\atomicops_internals_x86_msvc.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h" include\google\protobuf\stubs\bytestream.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h" include\google\protobuf\stubs\callback.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" include\google\protobuf\stubs\casts.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h" include\google\protobuf\stubs\fastmem.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\mutex.h" include\google\protobuf\stubs\mutex.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\once.h" include\google\protobuf\stubs\once.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\platform_macros.h" include\google\protobuf\stubs\platform_macros.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\port.h" include\google\protobuf\stubs\port.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\scoped_ptr.h" include\google\protobuf\stubs\scoped_ptr.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\shared_ptr.h" include\google\protobuf\stubs\shared_ptr.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\singleton.h" include\google\protobuf\stubs\singleton.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\status.h" include\google\protobuf\stubs\status.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stl_util.h" include\google\protobuf\stubs\stl_util.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\stringpiece.h" include\google\protobuf\stubs\stringpiece.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\template_util.h" include\google\protobuf\stubs\template_util.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\type_traits.h" include\google\protobuf\stubs\type_traits.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\text_format.h" include\google\protobuf\text_format.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\timestamp.pb.h" include\google\protobuf\timestamp.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.pb.h" include\google\protobuf\type.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\unknown_field_set.h" include\google\protobuf\unknown_field_set.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_comparator.h" include\google\protobuf\util\field_comparator.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_mask_util.h" include\google\protobuf\util\field_mask_util.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\json_util.h" include\google\protobuf\util\json_util.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\message_differencer.h" include\google\protobuf\util\message_differencer.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\time_util.h" include\google\protobuf\util\time_util.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver.h" include\google\protobuf\util\type_resolver.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver_util.h" include\google\protobuf\util\type_resolver_util.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format.h" include\google\protobuf\wire_format.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite.h" include\google\protobuf\wire_format_lite.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite_inl.h" include\google\protobuf\wire_format_lite_inl.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wrappers.pb.h" include\google\protobuf\wrappers.pb.h diff --git a/cmake/install.cmake b/cmake/install.cmake index 73e31984..28dc90dc 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -20,18 +20,12 @@ install(TARGETS protoc EXPORT protobuf-targets file(STRINGS extract_includes.bat.in _extract_strings REGEX "^copy") foreach(_extract_string ${_extract_strings}) - string(REPLACE "copy \${PROTOBUF_SOURCE_WIN32_PATH}\\" "" - _extract_string ${_extract_string}) - string(REPLACE "\\" "/" _extract_string ${_extract_string}) - string(REGEX MATCH "^[^ ]+" - _extract_from ${_extract_string}) - string(REGEX REPLACE "^${_extract_from} ([^$]+)" "\\1" - _extract_to ${_extract_string}) - get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/${_extract_from}" ABSOLUTE) - get_filename_component(_extract_name ${_extract_to} NAME) - get_filename_component(_extract_to ${_extract_to} PATH) - string(REPLACE "include/" "${CMAKE_INSTALL_INCLUDEDIR}/" - _extract_to "${_extract_to}") + string(REGEX REPLACE "^.* .+ include\\\\(.+)$" "\\1" + _header ${_extract_string}) + string(REPLACE "\\" "/" _header ${_header}) + get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/../src/${_header}" ABSOLUTE) + get_filename_component(_extract_name ${_header} NAME) + get_filename_component(_extract_to "${CMAKE_INSTALL_INCLUDEDIR}/${_header}" PATH) if(EXISTS "${_extract_from}") install(FILES "${_extract_from}" DESTINATION "${_extract_to}" diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index 26e1f356..5313d39e 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -30,6 +30,7 @@ set(libprotobuf_files ${protobuf_source_dir}/src/google/protobuf/timestamp.pb.cc ${protobuf_source_dir}/src/google/protobuf/type.pb.cc ${protobuf_source_dir}/src/google/protobuf/unknown_field_set.cc + ${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util.cc ${protobuf_source_dir}/src/google/protobuf/util/field_comparator.cc ${protobuf_source_dir}/src/google/protobuf/util/field_mask_util.cc ${protobuf_source_dir}/src/google/protobuf/util/internal/datapiece.cc diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index 215abcd8..29b32538 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -94,7 +94,7 @@ set(libprotoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.cc ) -set(js_well_known_types_sources, +set(js_well_known_types_sources ${protobuf_source_dir}/src/google/protobuf/compiler/js/well_known_types/any.js ${protobuf_source_dir}/src/google/protobuf/compiler/js/well_known_types/struct.js ${protobuf_source_dir}/src/google/protobuf/compiler/js/well_known_types/timestamp.js diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 1d3be71f..1470e4b0 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -17,6 +17,7 @@ add_library(gmock STATIC ${protobuf_source_dir}/gmock/src/gmock-all.cc ${protobuf_source_dir}/gmock/gtest/src/gtest-all.cc ) +target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT}) add_library(gmock_main STATIC ${protobuf_source_dir}/gmock/src/gmock_main.cc) target_link_libraries(gmock_main gmock) @@ -168,6 +169,7 @@ set(tests_files ${protobuf_source_dir}/src/google/protobuf/stubs/type_traits_unittest.cc ${protobuf_source_dir}/src/google/protobuf/text_format_unittest.cc ${protobuf_source_dir}/src/google/protobuf/unknown_field_set_unittest.cc + ${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util_test.cc ${protobuf_source_dir}/src/google/protobuf/util/field_comparator_test.cc ${protobuf_source_dir}/src/google/protobuf/util/field_mask_util_test.cc ${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter_test.cc diff --git a/configure.ac b/configure.ac index 6d9c2a01..531e25fb 100644 --- a/configure.ac +++ b/configure.ac @@ -93,6 +93,25 @@ ACX_CHECK_SUNCC # to the link AC_PROG_LIBTOOL +# Check whether the linker supports version scripts +AC_MSG_CHECKING([whether the linker supports version scripts]) +save_LDFLAGS=$LDFLAGS +LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" +cat > conftest.map <<EOF +{ + global: + main; + local: + *; +}; +EOF +AC_LINK_IFELSE( + [AC_LANG_SOURCE([int main() { return 0; }])], + [have_ld_version_script=yes; AC_MSG_RESULT(yes)], + [have_ld_version_script=no; AC_MSG_RESULT(no)]) +LDFLAGS=$save_LDFLAGS +AM_CONDITIONAL([HAVE_LD_VERSION_SCRIPT], [test "$have_ld_version_script" == "yes"]) + # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h stdlib.h unistd.h]) diff --git a/conformance/Makefile.am b/conformance/Makefile.am index cf7eee3a..1a8b5748 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -21,6 +21,7 @@ other_language_protoc_outputs = \ conformance_pb2.py \ Conformance.pbobjc.h \ Conformance.pbobjc.m \ + conformance_pb.js \ conformance_pb.rb \ com/google/protobuf/Any.java \ com/google/protobuf/AnyOrBuilder.java \ @@ -183,6 +184,7 @@ EXTRA_DIST = \ failure_list_cpp.txt \ failure_list_csharp.txt \ failure_list_java.txt \ + failure_list_js.txt \ failure_list_objc.txt \ failure_list_python.txt \ failure_list_python_cpp.txt \ @@ -230,12 +232,19 @@ conformance_objc-conformance_objc.$(OBJEXT): Conformance.pbobjc.h google/protobu endif +# JavaScript well-known types are expected to be in a directory called +# google-protobuf, because they are usually in the google-protobuf npm +# package. But we want to use the sources from our tree, so we recreate +# that directory structure here. +google-protobuf: + mkdir google-protobuf + if USE_EXTERNAL_PROTOC # Some implementations include pre-generated versions of well-known types. -protoc_middleman: $(conformance_protoc_inputs) $(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=. --python_out=. --php_out=. $(well_known_type_protoc_inputs) +protoc_middleman: $(conformance_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=. --python_out=. --php_out=. --js_out=import_style=commonjs,binary:google-protobuf $(well_known_type_protoc_inputs) ## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) touch protoc_middleman @@ -244,9 +253,9 @@ else # We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is # 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) $(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 --python_out=$$oldpwd --php_out=$$oldpwd $(well_known_type_protoc_inputs) ) +protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_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 --python_out=$$oldpwd --php_out=$$oldpwd --js_out=import_style=commonjs,binary:$$oldpwd/google-protobuf $(well_known_type_protoc_inputs) ) ## @mkdir -p lite ## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) ) touch protoc_middleman @@ -335,6 +344,9 @@ 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 ./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/conformance/README.md b/conformance/README.md index 9388055f..971fe8f6 100644 --- a/conformance/README.md +++ b/conformance/README.md @@ -19,11 +19,39 @@ directory to build `protoc`, since all the tests depend on it. $ make -Then to run the tests against the C++ implementation, run: +Running the tests for C++ +------------------------- + +To run the tests against the C++ implementation, run: $ cd conformance && make test_cpp -More tests and languages will be added soon! +Running the tests for JavaScript (Node.js) +------------------------------------------ + +To run the JavaScript tests against Node.js, make sure you have "node" +on your path and then run: + + $ cd conformance && make test_nodejs + +Running the tests for Ruby (MRI) +-------------------------------- + +To run the Ruby tests against MRI, first build the C extension: + + $ cd ruby && rake + +Then run the tests like so: + + $ cd conformance && make test_ruby + +Running the tests for other languages +------------------------------------- + +Most of the languages in the Protobuf source tree are set up to run +conformance tests. However some of them are more tricky to set up +properly. See `tests.sh` in the base of the repository to see how +Travis runs the tests. Testing other Protocol Buffer implementations --------------------------------------------- diff --git a/conformance/conformance_nodejs.js b/conformance/conformance_nodejs.js new file mode 100755 index 00000000..5ee37269 --- /dev/null +++ b/conformance/conformance_nodejs.js @@ -0,0 +1,168 @@ +#!/usr/bin/env node + +/* + * 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. + */ + +var conformance = require('conformance_pb'); +var test_messages_proto3 = require('google/protobuf/test_messages_proto3_pb'); +var fs = require('fs'); + +var testCount = 0; + +function doTest(request) { + var testMessage; + var response = new conformance.ConformanceResponse(); + + try { + if (request.getRequestedOutputFormat() === conformance.WireFormat.JSON) { + response.setSkipped("JSON not supported."); + return response; + } + + switch (request.getPayloadCase()) { + case conformance.ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD: + try { + testMessage = test_messages_proto3.TestAllTypes.deserializeBinary( + request.getProtobufPayload()); + } catch (err) { + response.setParseError(err.toString()); + return response; + } + + case conformance.ConformanceRequest.PayloadCase.JSON_PAYLOAD: + response.setSkipped("JSON not supported."); + return response; + + case conformance.ConformanceRequest.PayloadCase.PAYLOAD_NOT_SET: + response.setRuntimeError("Request didn't have payload"); + return response; + } + + switch (request.getRequestedOutputFormat()) { + case conformance.WireFormat.UNSPECIFIED: + response.setRuntimeError("Unspecified output format"); + return response; + + case conformance.WireFormat.PROTOBUF: + response.setProtobufPayload(testMessage.serializeBinary()); + + case conformance.WireFormat.JSON: + response.setSkipped("JSON not supported."); + return response; + + default: + throw "Request didn't have requested output format"; + } + } catch (err) { + response.setRuntimeError(err.toString()); + } + + return response; +} + +function onEof(totalRead) { + if (totalRead == 0) { + return undefined; + } else { + throw "conformance_nodejs: premature EOF on stdin."; + } +} + +// Utility function to read a buffer of N bytes. +function readBuffer(bytes) { + var buf = new Buffer(bytes); + var totalRead = 0; + while (totalRead < bytes) { + var read = 0; + try { + read = fs.readSync(process.stdin.fd, buf, totalRead, bytes - totalRead); + } catch (e) { + if (e.code == 'EOF') { + return onEof(totalRead) + } else if (e.code == 'EAGAIN') { + } else { + throw "conformance_nodejs: Error reading from stdin." + e; + } + } + + totalRead += read; + } + + return buf; +} + +function writeBuffer(buffer) { + var totalWritten = 0; + while (totalWritten < buffer.length) { + totalWritten += fs.writeSync( + process.stdout.fd, buffer, totalWritten, buffer.length - totalWritten); + } +} + +// Returns true if the test ran successfully, false on legitimate EOF. +// If EOF is encountered in an unexpected place, raises IOError. +function doTestIo() { + var lengthBuf = readBuffer(4); + if (!lengthBuf) { + return false; + } + + var length = lengthBuf.readInt32LE(0); + var serializedRequest = readBuffer(length); + if (!serializedRequest) { + throw "conformance_nodejs: Failed to read request."; + } + + serializedRequest = new Uint8Array(serializedRequest); + var request = + conformance.ConformanceRequest.deserializeBinary(serializedRequest); + var response = doTest(request); + + var serializedResponse = response.serializeBinary(); + + lengthBuf = new Buffer(4); + lengthBuf.writeInt32LE(serializedResponse.length, 0); + writeBuffer(lengthBuf); + writeBuffer(new Buffer(serializedResponse)); + + testCount += 1 + + return true; +} + +while (true) { + if (!doTestIo()) { + console.error('conformance_nodejs: received EOF from test runner ' + + "after " + testCount + " tests, exiting") + break; + } +} diff --git a/conformance/failure_list_js.txt b/conformance/failure_list_js.txt new file mode 100644 index 00000000..5414a2f9 --- /dev/null +++ b/conformance/failure_list_js.txt @@ -0,0 +1,15 @@ +Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs index c6819899..d4b78dae 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs @@ -80,7 +80,7 @@ namespace Google.Protobuf.Reflection { "ASgJEhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5n", "b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFt", "aW5nGAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVm", - "YWxzZSKaBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK", + "YWxzZSK0BQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK", "FGphdmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVf", "ZmlsZXMYCiABKAg6BWZhbHNlEikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2Fu", "ZF9oYXNoGBQgASgIQgIYARIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg", @@ -91,61 +91,61 @@ namespace Google.Protobuf.Reflection { "cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl", "ZBgXIAEoCDoFZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFs", "c2USGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVz", - "cGFjZRglIAEoCRIUCgxzd2lmdF9wcmVmaXgYJyABKAkSQwoUdW5pbnRlcnBy", - "ZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJw", - "cmV0ZWRPcHRpb24iOgoMT3B0aW1pemVNb2RlEgkKBVNQRUVEEAESDQoJQ09E", - "RV9TSVpFEAISEAoMTElURV9SVU5USU1FEAMqCQjoBxCAgICAAkoECCYQJyLs", - "AQoOTWVzc2FnZU9wdGlvbnMSJgoXbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQY", - "ASABKAg6BWZhbHNlEi4KH25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNz", - "b3IYAiABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEhEK", - "CW1hcF9lbnRyeRgHIAEoCBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByAD", - "KAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgH", - "EICAgIACSgQICBAJIp4DCgxGaWVsZE9wdGlvbnMSOgoFY3R5cGUYASABKA4y", - "Iy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkcS", - "DgoGcGFja2VkGAIgASgIEj8KBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90", - "b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUwSEwoEbGF6eRgF", - "IAEoCDoFZmFsc2USGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEwoEd2Vh", - "axgKIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygL", - "MiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24iLwoFQ1R5", - "cGUSCgoGU1RSSU5HEAASCAoEQ09SRBABEhAKDFNUUklOR19QSUVDRRACIjUK", - "BkpTVHlwZRINCglKU19OT1JNQUwQABINCglKU19TVFJJTkcQARINCglKU19O", - "VU1CRVIQAioJCOgHEICAgIACSgQIBBAFIl4KDE9uZW9mT3B0aW9ucxJDChR1", + "cGFjZRglIAEoCRIUCgxzd2lmdF9wcmVmaXgYJyABKAkSGAoQcGhwX2NsYXNz", + "X3ByZWZpeBgoIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsy", + "JC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRp", + "bWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JV", + "TlRJTUUQAyoJCOgHEICAgIACSgQIJhAnIuwBCg5NZXNzYWdlT3B0aW9ucxIm", + "ChdtZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9f", + "c3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoK", + "ZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMK", + "FHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1", + "Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgIEAkingMKDEZp", + "ZWxkT3B0aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5G", + "aWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoG", + "anN0eXBlGAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5K", + "U1R5cGU6CUpTX05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpkZXBy", + "ZWNhdGVkGAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1", "bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYu", - "VW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIo0BCgtFbnVtT3B0aW9u", - "cxITCgthbGxvd19hbGlhcxgCIAEoCBIZCgpkZXByZWNhdGVkGAMgASgIOgVm", - "YWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUu", - "cHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIn0KEEVu", - "dW1WYWx1ZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2USQwoU", - "dW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVm", - "LlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiJ7Cg5TZXJ2aWNlT3B0", - "aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJl", - "dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy", - "ZXRlZE9wdGlvbioJCOgHEICAgIACIq0CCg1NZXRob2RPcHRpb25zEhkKCmRl", - "cHJlY2F0ZWQYISABKAg6BWZhbHNlEl8KEWlkZW1wb3RlbmN5X2xldmVsGCIg", - "ASgOMi8uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVu", - "Y3lMZXZlbDoTSURFTVBPVEVOQ1lfVU5LTk9XThJDChR1bmludGVycHJldGVk", - "X29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRl", - "ZE9wdGlvbiJQChBJZGVtcG90ZW5jeUxldmVsEhcKE0lERU1QT1RFTkNZX1VO", - "S05PV04QABITCg9OT19TSURFX0VGRkVDVFMQARIOCgpJREVNUE9URU5UEAIq", - "CQjoBxCAgICAAiKeAgoTVW5pbnRlcnByZXRlZE9wdGlvbhI7CgRuYW1lGAIg", - "AygLMi0uZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFt", - "ZVBhcnQSGAoQaWRlbnRpZmllcl92YWx1ZRgDIAEoCRIaChJwb3NpdGl2ZV9p", - "bnRfdmFsdWUYBCABKAQSGgoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDEhQK", - "DGRvdWJsZV92YWx1ZRgGIAEoARIUCgxzdHJpbmdfdmFsdWUYByABKAwSFwoP", - "YWdncmVnYXRlX3ZhbHVlGAggASgJGjMKCE5hbWVQYXJ0EhEKCW5hbWVfcGFy", - "dBgBIAIoCRIUCgxpc19leHRlbnNpb24YAiACKAgi1QEKDlNvdXJjZUNvZGVJ", - "bmZvEjoKCGxvY2F0aW9uGAEgAygLMiguZ29vZ2xlLnByb3RvYnVmLlNvdXJj", - "ZUNvZGVJbmZvLkxvY2F0aW9uGoYBCghMb2NhdGlvbhIQCgRwYXRoGAEgAygF", - "QgIQARIQCgRzcGFuGAIgAygFQgIQARIYChBsZWFkaW5nX2NvbW1lbnRzGAMg", - "ASgJEhkKEXRyYWlsaW5nX2NvbW1lbnRzGAQgASgJEiEKGWxlYWRpbmdfZGV0", - "YWNoZWRfY29tbWVudHMYBiADKAkipwEKEUdlbmVyYXRlZENvZGVJbmZvEkEK", - "CmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVk", - "Q29kZUluZm8uQW5ub3RhdGlvbhpPCgpBbm5vdGF0aW9uEhAKBHBhdGgYASAD", - "KAVCAhABEhMKC3NvdXJjZV9maWxlGAIgASgJEg0KBWJlZ2luGAMgASgFEgsK", - "A2VuZBgEIAEoBUKMAQoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRv", - "clByb3Rvc0gBWj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90b2Mt", - "Z2VuLWdvL2Rlc2NyaXB0b3I7ZGVzY3JpcHRvcqICA0dQQqoCGkdvb2dsZS5Q", - "cm90b2J1Zi5SZWZsZWN0aW9u")); + "VW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRD", + "T1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1B", + "TBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAJK", + "BAgEEAUiXgoMT25lb2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u", + "GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u", + "KgkI6AcQgICAgAIijQEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFzGAIg", + "ASgIEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0", + "ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJl", + "dGVkT3B0aW9uKgkI6AcQgICAgAIifQoQRW51bVZhbHVlT3B0aW9ucxIZCgpk", + "ZXByZWNhdGVkGAEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlv", + "bhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlv", + "bioJCOgHEICAgIACInsKDlNlcnZpY2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQY", + "ISABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIk", + "Lmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICA", + "gAIirQIKDU1ldGhvZE9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFs", + "c2USXwoRaWRlbXBvdGVuY3lfbGV2ZWwYIiABKA4yLy5nb29nbGUucHJvdG9i", + "dWYuTWV0aG9kT3B0aW9ucy5JZGVtcG90ZW5jeUxldmVsOhNJREVNUE9URU5D", + "WV9VTktOT1dOEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv", + "b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIlAKEElkZW1wb3Rl", + "bmN5TGV2ZWwSFwoTSURFTVBPVEVOQ1lfVU5LTk9XThAAEhMKD05PX1NJREVf", + "RUZGRUNUUxABEg4KCklERU1QT1RFTlQQAioJCOgHEICAgIACIp4CChNVbmlu", + "dGVycHJldGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5nb29nbGUucHJvdG9i", + "dWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIYChBpZGVudGlmaWVy", + "X3ZhbHVlGAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBBIaChJu", + "ZWdhdGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91YmxlX3ZhbHVlGAYgASgB", + "EhQKDHN0cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCAB", + "KAkaMwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVu", + "c2lvbhgCIAIoCCLVAQoOU291cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASAD", + "KAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24a", + "hgEKCExvY2F0aW9uEhAKBHBhdGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVC", + "AhABEhgKEGxlYWRpbmdfY29tbWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29t", + "bWVudHMYBCABKAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMo", + "CSKnAQoRR2VuZXJhdGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzIt", + "Lmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9u", + "Gk8KCkFubm90YXRpb24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2Zp", + "bGUYAiABKAkSDQoFYmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQowBChNjb20u", + "Z29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFaPmdpdGh1Yi5j", + "b20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvYy1nZW4tZ28vZGVzY3JpcHRvcjtk", + "ZXNjcmlwdG9yogIDR1BCqgIaR29vZ2xlLlByb3RvYnVmLlJlZmxlY3Rpb24=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { @@ -159,7 +159,7 @@ namespace Google.Protobuf.Reflection { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null), @@ -2808,6 +2808,7 @@ namespace Google.Protobuf.Reflection { objcClassPrefix_ = other.objcClassPrefix_; csharpNamespace_ = other.csharpNamespace_; swiftPrefix_ = other.swiftPrefix_; + phpClassPrefix_ = other.phpClassPrefix_; uninterpretedOption_ = other.uninterpretedOption_.Clone(); } @@ -3056,6 +3057,21 @@ namespace Google.Protobuf.Reflection { } } + /// <summary>Field number for the "php_class_prefix" field.</summary> + public const int PhpClassPrefixFieldNumber = 40; + private string phpClassPrefix_ = ""; + /// <summary> + /// Sets the php class prefix which is prepended to all php generated classes + /// from this .proto. Default is empty. + /// </summary> + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string PhpClassPrefix { + get { return phpClassPrefix_; } + set { + phpClassPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// <summary>Field number for the "uninterpreted_option" field.</summary> public const int UninterpretedOptionFieldNumber = 999; private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec @@ -3097,6 +3113,7 @@ namespace Google.Protobuf.Reflection { if (ObjcClassPrefix != other.ObjcClassPrefix) return false; if (CsharpNamespace != other.CsharpNamespace) return false; if (SwiftPrefix != other.SwiftPrefix) return false; + if (PhpClassPrefix != other.PhpClassPrefix) return false; if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false; return true; } @@ -3119,6 +3136,7 @@ namespace Google.Protobuf.Reflection { if (ObjcClassPrefix.Length != 0) hash ^= ObjcClassPrefix.GetHashCode(); if (CsharpNamespace.Length != 0) hash ^= CsharpNamespace.GetHashCode(); if (SwiftPrefix.Length != 0) hash ^= SwiftPrefix.GetHashCode(); + if (PhpClassPrefix.Length != 0) hash ^= PhpClassPrefix.GetHashCode(); hash ^= uninterpretedOption_.GetHashCode(); return hash; } @@ -3190,6 +3208,10 @@ namespace Google.Protobuf.Reflection { output.WriteRawTag(186, 2); output.WriteString(SwiftPrefix); } + if (PhpClassPrefix.Length != 0) { + output.WriteRawTag(194, 2); + output.WriteString(PhpClassPrefix); + } uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); } @@ -3241,6 +3263,9 @@ namespace Google.Protobuf.Reflection { if (SwiftPrefix.Length != 0) { size += 2 + pb::CodedOutputStream.ComputeStringSize(SwiftPrefix); } + if (PhpClassPrefix.Length != 0) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpClassPrefix); + } size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); return size; } @@ -3295,6 +3320,9 @@ namespace Google.Protobuf.Reflection { if (other.SwiftPrefix.Length != 0) { SwiftPrefix = other.SwiftPrefix; } + if (other.PhpClassPrefix.Length != 0) { + PhpClassPrefix = other.PhpClassPrefix; + } uninterpretedOption_.Add(other.uninterpretedOption_); } @@ -3366,6 +3394,10 @@ namespace Google.Protobuf.Reflection { SwiftPrefix = input.ReadString(); break; } + case 322: { + PhpClassPrefix = input.ReadString(); + break; + } case 7994: { uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); break; diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh index 668e6d13..809214ce 100755 --- a/generate_descriptor_proto.sh +++ b/generate_descriptor_proto.sh @@ -104,3 +104,8 @@ if test -x csharp/generate_protos.sh; then echo "Generating messages for C#." csharp/generate_protos.sh $@ fi + +if test -x php/generate_descriptor_protos.sh; then + echo "Generating messages for PHP." + php/generate_descriptor_protos.sh $@ +fi diff --git a/java/core/pom.xml b/java/core/pom.xml index 14a4bf6c..be0da5ea 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -22,14 +22,17 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> + <scope>test</scope> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> + <scope>test</scope> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymockclassextension</artifactId> + <scope>test</scope> </dependency> </dependencies> diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java index 14169dc4..239798e4 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -354,9 +354,9 @@ public abstract class CodedInputStream { * * <p>Set the maximum message size. In order to prevent malicious messages from exhausting memory * or causing integer overflows, {@code CodedInputStream} limits how large a message may be. The - * default limit is 64MB. You should set this limit as small as you can without harming your app's - * functionality. Note that size limits only apply when reading from an {@code InputStream}, not - * when constructed around a raw byte array (nor with {@link ByteString#newCodedInput}). + * default limit is {@code Integer.MAX_INT}. You should set this limit as small as you can without + * harming your app's functionality. Note that size limits only apply when reading from an + * {@code InputStream}, not when constructed around a raw byte array. * * <p>If you want to read several messages from a single CodedInputStream, you could call {@link * #resetSizeCounter()} after each one to avoid hitting the size limit. diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java index cea05794..60179e37 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java @@ -854,6 +854,7 @@ public abstract class GeneratedMessage extends AbstractMessage /** Check if a singular extension is present. */ @Override + @SuppressWarnings("unchecked") public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) { Extension<MessageType, Type> extension = checkNotLite(extensionLite); @@ -863,6 +864,7 @@ public abstract class GeneratedMessage extends AbstractMessage /** Get the number of elements in a repeated extension. */ @Override + @SuppressWarnings("unchecked") public final <Type> int getExtensionCount( final ExtensionLite<MessageType, List<Type>> extensionLite) { Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); @@ -2555,6 +2557,7 @@ public abstract class GeneratedMessage extends AbstractMessage } @Override + @SuppressWarnings("unchecked") public Object get(GeneratedMessage message) { List result = new ArrayList(); for (int i = 0; i < getRepeatedCount(message); i++) { @@ -2564,6 +2567,7 @@ public abstract class GeneratedMessage extends AbstractMessage } @Override + @SuppressWarnings("unchecked") public Object get(Builder builder) { List result = new ArrayList(); for (int i = 0; i < getRepeatedCount(builder); i++) { diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java index f885b01e..2d7fd334 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -220,6 +220,7 @@ public abstract class GeneratedMessageLite< } @Override + @SuppressWarnings("unchecked") public final BuilderType toBuilder() { BuilderType builder = (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER); builder.mergeFrom((MessageType) this); @@ -453,6 +454,7 @@ public abstract class GeneratedMessageLite< */ protected FieldSet<ExtensionDescriptor> extensions = FieldSet.newFieldSet(); + @SuppressWarnings("unchecked") protected final void mergeExtensionFields(final MessageType other) { if (extensions.isImmutable()) { extensions = extensions.clone(); diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java index 2a5d8b50..fd051e75 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java @@ -866,6 +866,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage /** Check if a singular extension is present. */ @Override + @SuppressWarnings("unchecked") public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) { Extension<MessageType, Type> extension = checkNotLite(extensionLite); @@ -875,6 +876,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage /** Get the number of elements in a repeated extension. */ @Override + @SuppressWarnings("unchecked") public final <Type> int getExtensionCount( final ExtensionLite<MessageType, List<Type>> extensionLite) { Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); @@ -2219,6 +2221,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage } @Override + @SuppressWarnings("unchecked") public Object get(GeneratedMessageV3 message) { List result = new ArrayList(); for (int i = 0; i < getRepeatedCount(message); i++) { @@ -2228,6 +2231,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage } @Override + @SuppressWarnings("unchecked") public Object get(Builder builder) { List result = new ArrayList(); for (int i = 0; i < getRepeatedCount(builder); i++) { diff --git a/java/core/src/main/java/com/google/protobuf/MapEntry.java b/java/core/src/main/java/com/google/protobuf/MapEntry.java index 179c3348..7e8e9aad 100644 --- a/java/core/src/main/java/com/google/protobuf/MapEntry.java +++ b/java/core/src/main/java/com/google/protobuf/MapEntry.java @@ -89,6 +89,7 @@ public final class MapEntry<K, V> extends AbstractMessage { } /** Create a MapEntry with the provided key and value. */ + @SuppressWarnings("unchecked") private MapEntry(Metadata metadata, K key, V value) { this.key = key; this.value = value; @@ -435,6 +436,7 @@ public final class MapEntry<K, V> extends AbstractMessage { } @Override + @SuppressWarnings("unchecked") public Builder<K, V> clone() { return new Builder(metadata, key, value); } diff --git a/java/core/src/main/java/com/google/protobuf/MapField.java b/java/core/src/main/java/com/google/protobuf/MapField.java index a6109f98..805defe2 100644 --- a/java/core/src/main/java/com/google/protobuf/MapField.java +++ b/java/core/src/main/java/com/google/protobuf/MapField.java @@ -100,6 +100,7 @@ public class MapField<K, V> implements MutabilityOracle { } @Override + @SuppressWarnings("unchecked") public void convertMessageToKeyAndValue(Message message, Map<K, V> map) { MapEntry<K, V> entry = (MapEntry<K, V>) message; map.put(entry.getKey(), entry.getValue()); diff --git a/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java index d2bee2a4..2fc3124d 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java @@ -281,6 +281,7 @@ public class LazyStringArrayListTest extends TestCase { assertGenericListImmutable(byteArrayList, byteArrayList.get(0)); } + @SuppressWarnings("unchecked") private static <T> void assertGenericListImmutable(List<T> list, T value) { try { list.add(value); diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java index d4a18a22..c1bd21db 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java @@ -2602,6 +2602,9 @@ public final class TestUtil { case FOO_CORD: Assert.assertTrue(message.hasFooCord()); break; + case FOO_STRING_PIECE: + Assert.assertTrue(message.hasFooStringPiece()); + break; case FOO_BYTES: Assert.assertTrue(message.hasFooBytes()); break; diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index ac712c94..7d6718b8 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -35,6 +35,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import com.google.gson.JsonIOException; import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonParser; @@ -1067,9 +1068,23 @@ public class JsonFormat { } void merge(Reader json, Message.Builder builder) throws IOException { - JsonReader reader = new JsonReader(json); - reader.setLenient(false); - merge(jsonParser.parse(reader), builder); + try { + JsonReader reader = new JsonReader(json); + reader.setLenient(false); + merge(jsonParser.parse(reader), builder); + } catch (InvalidProtocolBufferException e) { + throw e; + } catch (JsonIOException e) { + // Unwrap IOException. + if (e.getCause() instanceof IOException) { + throw (IOException) e.getCause(); + } else { + throw new InvalidProtocolBufferException(e.getMessage()); + } + } catch (Exception e) { + // We convert all exceptions from JSON parsing to our own exceptions. + throw new InvalidProtocolBufferException(e.getMessage()); + } } void merge(String json, Message.Builder builder) throws InvalidProtocolBufferException { @@ -1521,7 +1536,7 @@ public class JsonFormat { BigDecimal value = new BigDecimal(json.getAsString()); return value.longValueExact(); } catch (Exception e) { - throw new InvalidProtocolBufferException("Not an int32 value: " + json); + throw new InvalidProtocolBufferException("Not an int64 value: " + json); } } diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java index 2160e4d5..1d631a2c 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java +++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java @@ -44,6 +44,7 @@ import java.text.SimpleDateFormat; import java.util.Comparator; import java.util.Date; import java.util.GregorianCalendar; +import java.util.Locale; import java.util.TimeZone; /** @@ -83,7 +84,7 @@ public final class Timestamps { }; private static SimpleDateFormat createTimestampFormat() { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); // We use Proleptic Gregorian Calendar (i.e., Gregorian calendar extends // backwards to year one) for timestamp formating. @@ -386,11 +387,11 @@ public final class Timestamps { static String formatNanos(int nanos) { // Determine whether to use 3, 6, or 9 digits for the nano part. if (nanos % NANOS_PER_MILLISECOND == 0) { - return String.format("%1$03d", nanos / NANOS_PER_MILLISECOND); + return String.format(Locale.ENGLISH, "%1$03d", nanos / NANOS_PER_MILLISECOND); } else if (nanos % NANOS_PER_MICROSECOND == 0) { - return String.format("%1$06d", nanos / NANOS_PER_MICROSECOND); + return String.format(Locale.ENGLISH, "%1$06d", nanos / NANOS_PER_MICROSECOND); } else { - return String.format("%1$09d", nanos); + return String.format(Locale.ENGLISH, "%1$09d", nanos); } } } diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index dafd9bb5..de02c117 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -62,13 +62,23 @@ import com.google.protobuf.util.JsonTestProto.TestStruct; import com.google.protobuf.util.JsonTestProto.TestTimestamp; import com.google.protobuf.util.JsonTestProto.TestWrappers; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; import java.math.BigDecimal; import java.math.BigInteger; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import junit.framework.TestCase; public class JsonFormatTest extends TestCase { + public JsonFormatTest() { + // Test that locale does not affect JsonFormat. + Locale.setDefault(Locale.forLanguageTag("hi-IN")); + } + private void setAllFields(TestAllTypes.Builder builder) { builder.setOptionalInt32(1234); builder.setOptionalInt64(1234567890123456789L); @@ -1411,4 +1421,34 @@ public class JsonFormatTest extends TestCase { // Expected. } } + + // Test that we are not leaking out JSON exceptions. + public void testJsonException() throws Exception { + InputStream throwingInputStream = new InputStream() { + public int read() throws IOException { + throw new IOException("12345"); + } + }; + InputStreamReader throwingReader = new InputStreamReader(throwingInputStream); + // When the underlying reader throws IOException, JsonFormat should forward + // through this IOException. + try { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + JsonFormat.parser().merge(throwingReader, builder); + fail("Exception is expected."); + } catch (IOException e) { + assertEquals("12345", e.getMessage()); + } + + Reader invalidJsonReader = new StringReader("{ xxx - yyy }"); + // When the JSON parser throws parser exceptions, JsonFormat should turn + // that into InvalidProtocolBufferException. + try { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + JsonFormat.parser().merge(invalidJsonReader, builder); + fail("Exception is expected."); + } catch (InvalidProtocolBufferException e) { + // Expected. + } + } } diff --git a/java/util/src/test/proto/com/google/protobuf/util/json_test.proto b/java/util/src/test/proto/com/google/protobuf/util/json_test.proto index a75338ef..d1248cfb 100644 --- a/java/util/src/test/proto/com/google/protobuf/util/json_test.proto +++ b/java/util/src/test/proto/com/google/protobuf/util/json_test.proto @@ -28,36 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// 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 json_test; diff --git a/javanano/README.md b/javanano/README.md index e19b90b1..6b13ecea 100644 --- a/javanano/README.md +++ b/javanano/README.md @@ -7,6 +7,9 @@ Copyright 2008 Google Inc. This directory contains the Java Protocol Buffers Nano runtime library. +**Nano is no longer supported by protobuf team. We recommend Android users to +use protobuf lite runtime instead.** + Installation - With Maven ------------------------- diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile index b7583fc7..659336d8 100644 --- a/jenkins/docker/Dockerfile +++ b/jenkins/docker/Dockerfile @@ -129,7 +129,7 @@ ENV MVN mvn --batch-mode RUN cd /tmp && \ git clone https://github.com/google/protobuf.git && \ cd protobuf && \ - git reset bf379715c93b581eeb078cec1f0dd8a7d79df431 && \ + git reset 6b27c1f981a9a93918e4039f236ead27165a8e91 && \ ./autogen.sh && \ ./configure && \ make -j4 && \ diff --git a/jenkins/docker32/Dockerfile b/jenkins/docker32/Dockerfile index 94d9a4c3..02e9df17 100644 --- a/jenkins/docker32/Dockerfile +++ b/jenkins/docker32/Dockerfile @@ -64,7 +64,7 @@ RUN php -r "unlink('composer-setup.php');" RUN cd /tmp && \ git clone https://github.com/google/protobuf.git && \ cd protobuf/php && \ - git reset 46ae90dc5e145b12fffa7e053a908a9f3e066286 && \ + git reset 6b27c1f981a9a93918e4039f236ead27165a8e91 && \ ln -sfn /usr/bin/php5.5 /usr/bin/php && \ ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config && \ ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize && \ diff --git a/js/binary/proto_test.js b/js/binary/proto_test.js index f86dc645..f5e1b6bb 100644 --- a/js/binary/proto_test.js +++ b/js/binary/proto_test.js @@ -283,8 +283,7 @@ function checkAllFields(original, copy) { * @param {!proto.jspb.test.TestExtendable} msg */ function checkExtensions(msg) { - assertEquals(-42, - msg.getExtension(proto.jspb.test.extendOptionalInt32)); + assertEquals(0, msg.getExtension(proto.jspb.test.extendOptionalInt32)); assertEquals(-0x7fffffff00000000, msg.getExtension(proto.jspb.test.extendOptionalInt64)); assertEquals(0x80000000, @@ -512,8 +511,7 @@ describe('protoBinaryTest', function() { * @param {proto.jspb.test.TestExtendable} msg */ function fillExtensions(msg) { - msg.setExtension( - proto.jspb.test.extendOptionalInt32, -42); + msg.setExtension(proto.jspb.test.extendOptionalInt32, 0); msg.setExtension( proto.jspb.test.extendOptionalInt64, -0x7fffffff00000000); msg.setExtension( diff --git a/js/binary/utils.js b/js/binary/utils.js index bbf99cdf..3ecd08e9 100644 --- a/js/binary/utils.js +++ b/js/binary/utils.js @@ -970,6 +970,10 @@ jspb.utils.byteSourceToUint8Array = function(data) { return /** @type {!Uint8Array} */(new Uint8Array(data)); } + if (data.constructor === Buffer) { + return /** @type {!Uint8Array} */(new Uint8Array(data)); + } + if (data.constructor === Array) { data = /** @type {!Array.<number>} */(data); return /** @type {!Uint8Array} */(new Uint8Array(data)); diff --git a/js/compatibility_tests/v3.0.0/binary/arith_test.js b/js/compatibility_tests/v3.0.0/binary/arith_test.js new file mode 100644 index 00000000..89796bf7 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/binary/arith_test.js @@ -0,0 +1,355 @@ +// 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 new file mode 100644 index 00000000..ac312648 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/binary/decoder_test.js @@ -0,0 +1,334 @@ +// 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()}); + + // Positive 32-bit varints encoded with 1 bits in positions 33 through 35 + // should trigger assertions. + decoder.setBlock([255, 255, 255, 255, 0x1F]); + assertThrows(function() {decoder.readUnsignedVarint32()}); + + decoder.setBlock([255, 255, 255, 255, 0x2F]); + assertThrows(function() {decoder.readUnsignedVarint32()}); + + decoder.setBlock([255, 255, 255, 255, 0x4F]); + assertThrows(function() {decoder.readUnsignedVarint32()}); + + // Negative 32-bit varints encoded with non-1 bits in the high dword should + // trigger assertions. + decoder.setBlock([255, 255, 255, 255, 255, 255, 0, 255, 255, 1]); + assertThrows(function() {decoder.readUnsignedVarint32()}); + + decoder.setBlock([255, 255, 255, 255, 255, 255, 255, 255, 255, 0]); + 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 new file mode 100644 index 00000000..14d0f42e --- /dev/null +++ b/js/compatibility_tests/v3.0.0/binary/proto_test.js @@ -0,0 +1,628 @@ +// 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 (goog.isString(arr)) { + 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(goog.isString(msg.getRepeatedBytesList_asB64()[0])); + assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[1])); + 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 new file mode 100644 index 00000000..95711385 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/binary/reader_test.js @@ -0,0 +1,922 @@ +// 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, goog.nullFunction); + writer.writeMessage(2, dummyMessage, goog.nullFunction); + + 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, goog.nullFunction); + }); + + // 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, goog.nullFunction); + + 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 new file mode 100644 index 00000000..d27e5ea2 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/binary/utils_test.js @@ -0,0 +1,668 @@ +// 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 (goog.isDef(opt_bits)) { + 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 (goog.isDef(opt_highBits)) { + if (opt_highBits != jspb.utils.split64High) throw 'fail!'; + } + if (goog.isDef(opt_lowBits)) { + 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.<numbers> 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 new file mode 100644 index 00000000..d5dadb41 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/binary/writer_test.js @@ -0,0 +1,122 @@ +// 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, goog.nullFunction); + }); + + // 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 new file mode 100644 index 00000000..5219d120 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/commonjs/export_asserts.js @@ -0,0 +1,37 @@ +/** + * @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 new file mode 100644 index 00000000..59c77ca2 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/commonjs/export_testdeps.js @@ -0,0 +1,18 @@ +/** + * @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 new file mode 100644 index 00000000..ffa34fea --- /dev/null +++ b/js/compatibility_tests/v3.0.0/commonjs/import_test.js @@ -0,0 +1,52 @@ +// 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 new file mode 100644 index 00000000..666b8edb --- /dev/null +++ b/js/compatibility_tests/v3.0.0/commonjs/jasmine.json @@ -0,0 +1,9 @@ +{ + "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 new file mode 100644 index 00000000..b6d90d28 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/commonjs/rewrite_tests_for_commonjs.js @@ -0,0 +1,97 @@ +/** + * @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 new file mode 100644 index 00000000..a060925f --- /dev/null +++ b/js/compatibility_tests/v3.0.0/commonjs/test6/test6.proto @@ -0,0 +1,40 @@ +// 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 new file mode 100644 index 00000000..f5574a3d --- /dev/null +++ b/js/compatibility_tests/v3.0.0/commonjs/test7/test7.proto @@ -0,0 +1,42 @@ +// 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 new file mode 100644 index 00000000..74a8a994 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/data.proto @@ -0,0 +1,51 @@ +// 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 new file mode 100644 index 00000000..01cbf891 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/debug_test.js @@ -0,0 +1,105 @@ +// 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 new file mode 100644 index 00000000..6653c01c --- /dev/null +++ b/js/compatibility_tests/v3.0.0/jasmine1.json @@ -0,0 +1,17 @@ +{ + "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 new file mode 100644 index 00000000..3208078f --- /dev/null +++ b/js/compatibility_tests/v3.0.0/jasmine2.json @@ -0,0 +1,17 @@ +{ + "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 new file mode 100644 index 00000000..3fb9a1b0 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/jasmine3.json @@ -0,0 +1,17 @@ +{ + "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 new file mode 100644 index 00000000..b7791431 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/message_test.js @@ -0,0 +1,1080 @@ +// 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_<reserved_name>. + 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.', + goog.isNumber(x) && 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 new file mode 100644 index 00000000..fab0fd44 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/proto3_test.js @@ -0,0 +1,329 @@ +// 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 (goog.isString(arr)) { + 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 new file mode 100644 index 00000000..acb67164 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/proto3_test.proto @@ -0,0 +1,89 @@ +// 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 new file mode 100644 index 00000000..937ffb89 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/test.proto @@ -0,0 +1,236 @@ +// 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_<name>. + 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 new file mode 100755 index 00000000..9d58f30a --- /dev/null +++ b/js/compatibility_tests/v3.0.0/test.sh @@ -0,0 +1,92 @@ +#!/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/google-closure-library/closure/bin/calcdeps.py -i commonjs/export_asserts.js -p . -p ../../node_modules/google-closure-library/closure -o compiled --compiler_jar ../../node_modules/google-closure-compiler/compiler.jar > commonjs_out/test_node_modules/closure_asserts_commonjs.js +../../node_modules/google-closure-library/closure/bin/calcdeps.py -i commonjs/export_testdeps.js -p ../.. -p ../../node_modules/google-closure-library/closure -o compiled --compiler_jar ../../node_modules/google-closure-compiler/compiler.jar > 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 new file mode 100644 index 00000000..44e55eff --- /dev/null +++ b/js/compatibility_tests/v3.0.0/test2.proto @@ -0,0 +1,54 @@ +// 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 new file mode 100644 index 00000000..940a552e --- /dev/null +++ b/js/compatibility_tests/v3.0.0/test3.proto @@ -0,0 +1,53 @@ +// 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 new file mode 100644 index 00000000..cf2451e9 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/test4.proto @@ -0,0 +1,42 @@ +// 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 new file mode 100644 index 00000000..34979517 --- /dev/null +++ b/js/compatibility_tests/v3.0.0/test5.proto @@ -0,0 +1,44 @@ +// 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 new file mode 100644 index 00000000..116f17fb --- /dev/null +++ b/js/compatibility_tests/v3.0.0/testbinary.proto @@ -0,0 +1,212 @@ +// 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<string, string> map_string_string = 1; + map<string, int32> map_string_int32 = 2; + map<string, int64> map_string_int64 = 3; + map<string, bool> map_string_bool = 4; + map<string, double> map_string_double = 5; + map<string, MapValueEnum> map_string_enum = 6; + map<string, MapValueMessage> map_string_msg = 7; + + map<int32, string> map_int32_string = 8; + map<int64, string> map_int64_string = 9; + map<bool, string> map_bool_string = 10; + + optional TestMapFields test_map_fields = 11; + map<string, TestMapFields> 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 new file mode 100644 index 00000000..960bce4e --- /dev/null +++ b/js/compatibility_tests/v3.0.0/testempty.proto @@ -0,0 +1,34 @@ +// 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/gulpfile.js b/js/gulpfile.js index 16c302ed..fc9559f9 100644 --- a/js/gulpfile.js +++ b/js/gulpfile.js @@ -23,8 +23,62 @@ var wellKnownTypes = [ '../src/google/protobuf/wrappers.proto', ]; -gulp.task('genproto_closure', function (cb) { - exec(protoc + ' --js_out=library=testproto_libs,binary:. -I ../src -I . *.proto && ' + protoc + ' --js_out=one_output_file_per_input_file,binary:. -I ../src -I . ' + wellKnownTypes.join(' '), +var group1Protos = [ + 'data.proto', + 'test3.proto', + 'test5.proto', + 'commonjs/test6/test6.proto', + 'test8.proto', + 'testbinary.proto', + 'testempty.proto', + 'test.proto', +]; + +var group2Protos = [ + 'proto3_test.proto', + 'test2.proto', + 'test4.proto', + 'commonjs/test7/test7.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 + ' --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); @@ -32,8 +86,8 @@ gulp.task('genproto_closure', function (cb) { }); }); -gulp.task('genproto_commonjs', function (cb) { - exec('mkdir -p commonjs_out && ' + protoc + ' --js_out=import_style=commonjs,binary:commonjs_out -I ../src -I commonjs -I . *.proto commonjs/test*/*.proto ' + wellKnownTypes.join(' '), +gulp.task('genproto_group2_commonjs', function (cb) { + exec('mkdir -p commonjs_out && ' + protoc + ' --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); @@ -105,7 +159,7 @@ gulp.task('commonjs_testdeps', function (cb) { }); }); -gulp.task('make_commonjs_out', ['dist', 'genproto_commonjs', 'genproto_commonjs_wellknowntypes', 'commonjs_asserts', 'commonjs_testdeps'], function (cb) { +gulp.task('make_commonjs_out', ['dist', 'genproto_well_known_types_commonjs', 'genproto_group1_commonjs', 'genproto_group2_commonjs', 'genproto_commonjs_wellknowntypes', 'commonjs_asserts', 'commonjs_testdeps'], 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 && "; @@ -128,8 +182,8 @@ gulp.task('make_commonjs_out', ['dist', 'genproto_commonjs', 'genproto_commonjs_ }); }); -gulp.task('deps', ['genproto_closure'], function (cb) { - exec('./node_modules/google-closure-library/closure/bin/build/depswriter.py *.js binary/*.js > deps.js', +gulp.task('deps', ['genproto_well_known_types_closure', 'genproto_group1_closure', 'genproto_group2_closure'], function (cb) { + exec('./node_modules/google-closure-library/closure/bin/build/depswriter.py 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); @@ -137,7 +191,7 @@ gulp.task('deps', ['genproto_closure'], function (cb) { }); }); -gulp.task('test_closure', ['genproto_closure', 'deps'], function (cb) { +gulp.task('test_closure', ['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); diff --git a/js/jasmine.json b/js/jasmine.json index 093f1579..aeea72f8 100644 --- a/js/jasmine.json +++ b/js/jasmine.json @@ -10,6 +10,8 @@ "deps.js", "google/protobuf/any.js", "google/protobuf/struct.js", - "google/protobuf/timestamp.js" + "google/protobuf/timestamp.js", + "testproto_libs1.js", + "testproto_libs2.js" ] } diff --git a/js/message.js b/js/message.js index 05d34e9d..220a5bdb 100644 --- a/js/message.js +++ b/js/message.js @@ -202,7 +202,7 @@ goog.define('jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS', COMPILED); /** - * Does this browser support Uint8Aray typed arrays? + * Does this JavaScript environment support Uint8Aray typed arrays? * @type {boolean} * @private */ @@ -497,7 +497,7 @@ jspb.Message.toObjectExtension = function(proto, obj, extensions, for (var fieldNumber in extensions) { var fieldInfo = extensions[fieldNumber]; var value = getExtensionFn.call(proto, fieldInfo); - if (value) { + if (goog.isDefAndNotNull(value)) { for (var name in fieldInfo.fieldName) { if (fieldInfo.fieldName.hasOwnProperty(name)) { break; // the compiled field name @@ -541,7 +541,7 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, 'without binary serialization support'); } var value = getExtensionFn.call(proto, fieldInfo); - if (value) { + if (goog.isDefAndNotNull(value)) { 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 diff --git a/js/message_test.js b/js/message_test.js index a2c5763d..2298742d 100644 --- a/js/message_test.js +++ b/js/message_test.js @@ -693,10 +693,11 @@ describe('Message test suite', function() { }); it('testToObject_hasExtensionField', function() { - var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]); + 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() { diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh index ea9fd273..c3cc8e68 100755 --- a/objectivec/DevTools/full_mac_build.sh +++ b/objectivec/DevTools/full_mac_build.sh @@ -273,6 +273,14 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then -destination "platform=iOS Simulator,name=iPad Pro (9.7 inch),OS=10.2" # 64bit ) ;; + 8.3* ) + XCODEBUILD_TEST_BASE_IOS+=( + -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit + -destination "platform=iOS Simulator,name=iPhone 7,OS=10.3" # 64bit + -destination "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit + -destination "platform=iOS Simulator,name=iPad Pro (9.7 inch),OS=10.3" # 64bit + ) + ;; * ) echo "Time to update the simulator targets for Xcode ${XCODE_VERSION}" exit 2 diff --git a/objectivec/GPBCodedInputStream.m b/objectivec/GPBCodedInputStream.m index e8c8989c..eef05353 100644 --- a/objectivec/GPBCodedInputStream.m +++ b/objectivec/GPBCodedInputStream.m @@ -45,7 +45,12 @@ NSString *const GPBCodedInputStreamUnderlyingErrorKey = NSString *const GPBCodedInputStreamErrorDomain = GPBNSStringifySymbol(GPBCodedInputStreamErrorDomain); -static const NSUInteger kDefaultRecursionLimit = 64; +// Matching: +// https://github.com/google/protobuf/blob/master/java/core/src/main/java/com/google/protobuf/CodedInputStream.java#L62 +// private static final int DEFAULT_RECURSION_LIMIT = 100; +// https://github.com/google/protobuf/blob/master/src/google/protobuf/io/coded_stream.cc#L86 +// int CodedInputStream::default_recursion_limit_ = 100; +static const NSUInteger kDefaultRecursionLimit = 100; static void RaiseException(NSInteger code, NSString *reason) { NSDictionary *errorInfo = nil; diff --git a/objectivec/GPBMessage.h b/objectivec/GPBMessage.h index c07ec888..2c325ba8 100644 --- a/objectivec/GPBMessage.h +++ b/objectivec/GPBMessage.h @@ -66,6 +66,11 @@ CF_EXTERN_C_END /** * Base class that each generated message subclasses from. * + * @note @c NSCopying support is a "deep copy", in that all sub objects are + * copied. Just like you wouldn't want a UIView/NSView trying to + * exist in two places, you don't want a sub message to be a property + * property of two other messages. + * * @note While the class support NSSecureCoding, if the message has any * extensions, they will end up reloaded in @c unknownFields as there is * no way for the @c NSCoding plumbing to pass through a diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m index 58a10fdb..78935b19 100644 --- a/objectivec/GPBMessage.m +++ b/objectivec/GPBMessage.m @@ -738,6 +738,25 @@ void GPBClearMessageAutocreator(GPBMessage *self) { self->autocreatorExtension_ = nil; } +// Call this before using the readOnlySemaphore_. This ensures it is created only once. +void GPBPrepareReadOnlySemaphore(GPBMessage *self) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdirect-ivar-access" +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + + // Create the semaphore on demand (rather than init) as developers might not cause them + // to be needed, and the heap usage can add up. The atomic swap is used to avoid needing + // another lock around creating it. + if (self->readOnlySemaphore_ == nil) { + dispatch_semaphore_t worker = dispatch_semaphore_create(1); + if (!OSAtomicCompareAndSwapPtrBarrier(NULL, worker, (void * volatile *)&(self->readOnlySemaphore_))) { + dispatch_release(worker); + } + } + +#pragma clang diagnostic pop +} + static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { if (!self->unknownFields_) { self->unknownFields_ = [[GPBUnknownFieldSet alloc] init]; diff --git a/objectivec/GPBMessage_PackagePrivate.h b/objectivec/GPBMessage_PackagePrivate.h index 9324cf8d..90834d40 100644 --- a/objectivec/GPBMessage_PackagePrivate.h +++ b/objectivec/GPBMessage_PackagePrivate.h @@ -70,7 +70,6 @@ typedef struct GPBMessage_Storage *GPBMessage_StoragePtr; // Use of readOnlySemaphore_ must be prefaced by a call to // GPBPrepareReadOnlySemaphore to ensure it has been created. This allows // readOnlySemaphore_ to be only created when actually needed. - dispatch_once_t readOnlySemaphoreCreationOnce_; dispatch_semaphore_t readOnlySemaphore_; } @@ -105,22 +104,7 @@ CF_EXTERN_C_BEGIN // Call this before using the readOnlySemaphore_. This ensures it is created only once. -NS_INLINE void GPBPrepareReadOnlySemaphore(GPBMessage *self) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdirect-ivar-access" - -// Starting on Xcode 8.3, the static analyzer complains that the dispatch_once_t -// variable passed to dispatch_once should not be allocated on the heap or -// stack. Given that the semaphore is also an instance variable of the message, -// both variables are cleared at the same time, so this is safe. -#if !defined(__clang_analyzer__) - dispatch_once(&self->readOnlySemaphoreCreationOnce_, ^{ - self->readOnlySemaphore_ = dispatch_semaphore_create(1); - }); -#endif // !defined(__clang_analyzer__) - -#pragma clang diagnostic pop -} +void GPBPrepareReadOnlySemaphore(GPBMessage *self); // Returns a new instance that was automatically created by |autocreator| for // its field |field|. diff --git a/objectivec/Tests/GPBMessageTests+Serialization.m b/objectivec/Tests/GPBMessageTests+Serialization.m index 763af2b0..3c861fef 100644 --- a/objectivec/Tests/GPBMessageTests+Serialization.m +++ b/objectivec/Tests/GPBMessageTests+Serialization.m @@ -948,15 +948,23 @@ static NSData *DataFromCStr(const char *str) { - (void)testErrorRecursionDepthReached { NSData *data = DataFromCStr( - "\x0A\x86\x01\x0A\x83\x01\x0A\x80\x01\x0A\x7E\x0A\x7C\x0A\x7A\x0A\x78" - "\x0A\x76\x0A\x74\x0A\x72\x0A\x70\x0A\x6E\x0A\x6C\x0A\x6A\x0A\x68" - "\x0A\x66\x0A\x64\x0A\x62\x0A\x60\x0A\x5E\x0A\x5C\x0A\x5A\x0A\x58" - "\x0A\x56\x0A\x54\x0A\x52\x0A\x50\x0A\x4E\x0A\x4C\x0A\x4A\x0A\x48" - "\x0A\x46\x0A\x44\x0A\x42\x0A\x40\x0A\x3E\x0A\x3C\x0A\x3A\x0A\x38" - "\x0A\x36\x0A\x34\x0A\x32\x0A\x30\x0A\x2E\x0A\x2C\x0A\x2A\x0A\x28" - "\x0A\x26\x0A\x24\x0A\x22\x0A\x20\x0A\x1E\x0A\x1C\x0A\x1A\x0A\x18" - "\x0A\x16\x0A\x14\x0A\x12\x0A\x10\x0A\x0E\x0A\x0C\x0A\x0A\x0A\x08" - "\x0A\x06\x12\x04\x72\x02\x4B\x50"); + "\x0A\xF2\x01\x0A\xEF\x01\x0A\xEC\x01\x0A\xE9\x01\x0A\xE6\x01" + "\x0A\xE3\x01\x0A\xE0\x01\x0A\xDD\x01\x0A\xDA\x01\x0A\xD7\x01" + "\x0A\xD4\x01\x0A\xD1\x01\x0A\xCE\x01\x0A\xCB\x01\x0A\xC8\x01" + "\x0A\xC5\x01\x0A\xC2\x01\x0A\xBF\x01\x0A\xBC\x01\x0A\xB9\x01" + "\x0A\xB6\x01\x0A\xB3\x01\x0A\xB0\x01\x0A\xAD\x01\x0A\xAA\x01" + "\x0A\xA7\x01\x0A\xA4\x01\x0A\xA1\x01\x0A\x9E\x01\x0A\x9B\x01" + "\x0A\x98\x01\x0A\x95\x01\x0A\x92\x01\x0A\x8F\x01\x0A\x8C\x01" + "\x0A\x89\x01\x0A\x86\x01\x0A\x83\x01\x0A\x80\x01\x0A\x7E" + "\x0A\x7C\x0A\x7A\x0A\x78\x0A\x76\x0A\x74\x0A\x72\x0A\x70" + "\x0A\x6E\x0A\x6C\x0A\x6A\x0A\x68\x0A\x66\x0A\x64\x0A\x62" + "\x0A\x60\x0A\x5E\x0A\x5C\x0A\x5A\x0A\x58\x0A\x56\x0A\x54" + "\x0A\x52\x0A\x50\x0A\x4E\x0A\x4C\x0A\x4A\x0A\x48\x0A\x46" + "\x0A\x44\x0A\x42\x0A\x40\x0A\x3E\x0A\x3C\x0A\x3A\x0A\x38" + "\x0A\x36\x0A\x34\x0A\x32\x0A\x30\x0A\x2E\x0A\x2C\x0A\x2A" + "\x0A\x28\x0A\x26\x0A\x24\x0A\x22\x0A\x20\x0A\x1E\x0A\x1C" + "\x0A\x1A\x0A\x18\x0A\x16\x0A\x14\x0A\x12\x0A\x10\x0A\x0E" + "\x0A\x0C\x0A\x0A\x0A\x08\x0A\x06\x12\x04\x72\x02\x4B\x50"); NSError *error = nil; NestedTestAllTypes *msg = [NestedTestAllTypes parseFromData:data error:&error]; diff --git a/php/composer.json b/php/composer.json index 3dae2865..32b0f44c 100644 --- a/php/composer.json +++ b/php/composer.json @@ -18,7 +18,8 @@ "Google\\Protobuf\\": "tests/generated/Google/Protobuf", "Google\\Protobuf\\Internal\\": "src/Google/Protobuf/Internal", "GPBMetadata\\": "tests/generated/GPBMetadata", - "GPBMetadata\\Google\\Protobuf\\Internal\\": "src/GPBMetadata/Google/Protobuf/Internal" + "GPBMetadata\\Google\\Protobuf\\Internal\\": "src/GPBMetadata/Google/Protobuf/Internal", + "": "tests/generated" }, "files": [ "src/Google/Protobuf/descriptor.php" diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index 63bb6d0a..2186ab1f 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -225,8 +225,17 @@ void repeated_field_push_native(RepeatedField *intern, void *value TSRMLS_DC) { zend_hash_next_index_insert(ht, (void **)value, size, NULL); } +void repeated_field_create_with_field(zend_class_entry *ce, + const upb_fielddef *field, + zval **repeated_field TSRMLS_DC) { + upb_fieldtype_t type = upb_fielddef_type(field); + const zend_class_entry *msg_ce = field_type_class(field TSRMLS_CC); + repeated_field_create_with_type(ce, type, msg_ce, repeated_field TSRMLS_CC); +} + void repeated_field_create_with_type(zend_class_entry *ce, - const upb_fielddef *field, + upb_fieldtype_t type, + const zend_class_entry* msg_ce, zval **repeated_field TSRMLS_DC) { MAKE_STD_ZVAL(*repeated_field); Z_TYPE_PP(repeated_field) = IS_OBJECT; @@ -235,13 +244,8 @@ void repeated_field_create_with_type(zend_class_entry *ce, RepeatedField *intern = zend_object_store_get_object(*repeated_field TSRMLS_CC); - intern->type = upb_fielddef_type(field); - if (intern->type == UPB_TYPE_MESSAGE) { - const upb_msgdef *msg = upb_fielddef_msgsubdef(field); - zval *desc_php = get_def_obj(msg); - Descriptor *desc = zend_object_store_get_object(desc_php TSRMLS_CC); - intern->msg_ce = desc->klass; - } + intern->type = type; + intern->msg_ce = msg_ce; MAKE_STD_ZVAL(intern->array); repeated_field_array_init(intern->array, intern->type, 0 ZEND_FILE_LINE_CC); diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 32b158e2..52b9e885 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -252,39 +252,54 @@ PHP_METHOD(DescriptorPool, getGeneratedPool) { static void convert_to_class_name_inplace(char *class_name, const char* fullname, + const char* prefix, const char* package_name) { - size_t i; - bool first_char = false; + size_t i = 0, j; + bool first_char = true; size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name); + size_t prefix_len = prefix == NULL ? 0 : strlen(prefix); + size_t message_name_start = package_name == NULL ? 0 : pkg_name_len + 1; + size_t message_len = (strlen(fullname) - message_name_start); // In php, class name cannot be Empty. if (strcmp("google.protobuf.Empty", fullname) == 0) { - fullname = "google.protobuf.GPBEmpty"; + strcpy(class_name, "\\Google\\Protobuf\\GPBEmpty"); + return; } - if (pkg_name_len == 0) { - strcpy(class_name, fullname); - } else { - class_name[0] = '.'; - strcpy(&class_name[1], fullname); - for (i = 0; i <= pkg_name_len + 1; i++) { - // PHP package uses camel case. - if (!first_char && class_name[i] != '.') { - first_char = true; - class_name[i] += 'A' - 'a'; - } + if (pkg_name_len != 0) { + class_name[i++] = '\\'; + for (j = 0; j < pkg_name_len; j++) { // php packages are divided by '\'. - if (class_name[i] == '.') { + if (package_name[j] == '.') { + class_name[i++] = '\\'; + first_char = true; + } else if (first_char) { + // PHP package uses camel case. + if (package_name[j] < 'A' || package_name[j] > 'Z') { + class_name[i++] = package_name[j] + 'A' - 'a'; + } else { + class_name[i++] = package_name[j]; + } first_char = false; - class_name[i] = '\\'; + } else { + class_name[i++] = package_name[j]; } } + class_name[i++] = '\\'; + } + + if (prefix_len > 0) { + strcpy(class_name + i, prefix); + i += prefix_len; } // Submessage is concatenated with its containing messages by '_'. - for (i = pkg_name_len; i < strlen(class_name); i++) { - if (class_name[i] == '.') { - class_name[i] = '_'; + for (j = message_name_start; j < message_name_start + message_len; j++) { + if (fullname[j] == '.') { + class_name[i++] = '_'; + } else { + class_name[i++] = fullname[j]; } } } @@ -339,8 +354,13 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if \ * given message is google.protobuf.Empty.*/ \ const char *fullname = upb_##def_type_lower##_fullname(def_type_lower); \ - char *klass_name = ecalloc(sizeof(char), 5 + strlen(fullname)); \ - convert_to_class_name_inplace(klass_name, fullname, \ + const char *prefix = upb_filedef_phpprefix(files[0]); \ + size_t klass_name_len = strlen(fullname) + 5; \ + if (prefix != NULL) { \ + klass_name_len += strlen(prefix); \ + } \ + char *klass_name = ecalloc(sizeof(char), klass_name_len); \ + convert_to_class_name_inplace(klass_name, fullname, prefix, \ upb_filedef_package(files[0])); \ zend_class_entry **pce; \ if (zend_lookup_class(klass_name, strlen(klass_name), &pce TSRMLS_CC) == \ diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index ab98879d..fae152e3 100644 --- a/php/ext/google/protobuf/map.c +++ b/php/ext/google/protobuf/map.c @@ -146,6 +146,11 @@ static zend_function_entry map_field_methods[] = { ZEND_FE_END }; +// Forward declare static functions. + +static bool map_field_write_dimension(zval *object, zval *key, + zval *value TSRMLS_DC); + // ----------------------------------------------------------------------------- // MapField creation/desctruction // ----------------------------------------------------------------------------- @@ -183,6 +188,7 @@ void map_field_init(TSRMLS_D) { map_field_handlers = PEMALLOC(zend_object_handlers); memcpy(map_field_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + map_field_handlers->write_dimension = map_field_write_dimension; map_field_handlers->get_gc = map_field_get_gc; } @@ -235,7 +241,18 @@ void map_field_free(void *object TSRMLS_DC) { efree(object); } -void map_field_create_with_type(zend_class_entry *ce, const upb_fielddef *field, +void map_field_create_with_field(zend_class_entry *ce, const upb_fielddef *field, + zval **map_field TSRMLS_DC) { + const upb_fielddef *key_field = map_field_key(field); + const upb_fielddef *value_field = map_field_value(field); + map_field_create_with_type( + ce, upb_fielddef_type(key_field), upb_fielddef_type(value_field), + field_type_class(value_field TSRMLS_CC), map_field TSRMLS_CC); +} + +void map_field_create_with_type(zend_class_entry *ce, upb_fieldtype_t key_type, + upb_fieldtype_t value_type, + const zend_class_entry *msg_ce, zval **map_field TSRMLS_DC) { MAKE_STD_ZVAL(*map_field); Z_TYPE_PP(map_field) = IS_OBJECT; @@ -245,11 +262,9 @@ void map_field_create_with_type(zend_class_entry *ce, const upb_fielddef *field, Map* intern = (Map*)zend_object_store_get_object(*map_field TSRMLS_CC); - const upb_fielddef *key_field = map_field_key(field); - const upb_fielddef *value_field = map_field_value(field); - intern->key_type = upb_fielddef_type(key_field); - intern->value_type = upb_fielddef_type(value_field); - intern->msg_ce = field_type_class(value_field TSRMLS_CC); + intern->key_type = key_type; + intern->value_type = value_type; + intern->msg_ce = msg_ce; } static void map_field_free_element(void *object) { diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 28cea95c..2287f7e6 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -296,6 +296,7 @@ PHP_METHOD(Util, checkBool); PHP_METHOD(Util, checkString); PHP_METHOD(Util, checkBytes); PHP_METHOD(Util, checkMessage); +PHP_METHOD(Util, checkMapField); PHP_METHOD(Util, checkRepeatedField); // ----------------------------------------------------------------------------- @@ -349,7 +350,11 @@ const upb_fielddef* map_entry_key(const upb_msgdef* msgdef); const upb_fielddef* map_entry_value(const upb_msgdef* msgdef); zend_object_value map_field_create(zend_class_entry *ce TSRMLS_DC); -void map_field_create_with_type(zend_class_entry *ce, const upb_fielddef *field, +void map_field_create_with_field(zend_class_entry *ce, const upb_fielddef *field, + zval **map_field TSRMLS_DC); +void map_field_create_with_type(zend_class_entry *ce, upb_fieldtype_t key_type, + upb_fieldtype_t value_type, + const zend_class_entry *msg_ce, zval **map_field TSRMLS_DC); void map_field_free(void* object TSRMLS_DC); void* upb_value_memory(upb_value* v); @@ -392,9 +397,12 @@ struct RepeatedFieldIter { long position; }; -void repeated_field_create_with_type(zend_class_entry* ce, +void repeated_field_create_with_field(zend_class_entry* ce, const upb_fielddef* field, zval** repeated_field TSRMLS_DC); +void repeated_field_create_with_type(zend_class_entry* ce, upb_fieldtype_t type, + const zend_class_entry* msg_ce, + zval** repeated_field TSRMLS_DC); // Return the element at the index position from the repeated field. There is // not restriction on the type of stored elements. void *repeated_field_index_native(RepeatedField *intern, int index TSRMLS_DC); diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c index 1b239ee3..af7c292f 100644 --- a/php/ext/google/protobuf/storage.c +++ b/php/ext/google/protobuf/storage.c @@ -517,12 +517,12 @@ void layout_init(MessageLayout* layout, void* storage, *oneof_case = ONEOF_CASE_NONE; } else if (is_map_field(field)) { zval_ptr_dtor(property_ptr); - map_field_create_with_type(map_field_type, field, property_ptr TSRMLS_CC); + map_field_create_with_field(map_field_type, field, property_ptr TSRMLS_CC); DEREF(memory, zval**) = property_ptr; } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { zval_ptr_dtor(property_ptr); - repeated_field_create_with_type(repeated_field_type, field, - property_ptr TSRMLS_CC); + repeated_field_create_with_field(repeated_field_type, field, + property_ptr TSRMLS_CC); DEREF(memory, zval**) = property_ptr; } else { native_slot_init(upb_fielddef_type(field), memory, property_ptr); diff --git a/php/ext/google/protobuf/type_check.c b/php/ext/google/protobuf/type_check.c index d12d0025..fe9b18f0 100644 --- a/php/ext/google/protobuf/type_check.c +++ b/php/ext/google/protobuf/type_check.c @@ -51,6 +51,13 @@ ZEND_BEGIN_ARG_INFO_EX(arg_check_repeated, 0, 0, 2) ZEND_ARG_INFO(0, klass) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arg_check_map, 0, 0, 3) + ZEND_ARG_INFO(1, val) + ZEND_ARG_INFO(0, key_type) + ZEND_ARG_INFO(0, value_type) + ZEND_ARG_INFO(0, klass) +ZEND_END_ARG_INFO() + static zend_function_entry util_methods[] = { PHP_ME(Util, checkInt32, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(Util, checkUint32, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) @@ -63,6 +70,7 @@ static zend_function_entry util_methods[] = { PHP_ME(Util, checkString, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(Util, checkBytes, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(Util, checkMessage, arg_check_message, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkMapField, arg_check_map, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(Util, checkRepeatedField, arg_check_repeated, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_FE_END @@ -411,20 +419,114 @@ PHP_METHOD(Util, checkRepeatedField) { zval* val; long type; const zend_class_entry* klass = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol|C", &val, - repeated_field_type, &type, &klass) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl|C", &val, &type, + &klass) == FAILURE) { return; } - RepeatedField *intern = - (RepeatedField *)zend_object_store_get_object(val TSRMLS_CC); - if (to_fieldtype(type) != intern->type) { + if (Z_TYPE_P(val) == IS_ARRAY) { + HashTable* table = Z_ARRVAL_P(val); + HashPosition pointer; + void* memory; + zval* repeated_field; + + repeated_field_create_with_type(repeated_field_type, to_fieldtype(type), + klass, &repeated_field TSRMLS_CC); + RepeatedField* intern = + (RepeatedField*)zend_object_store_get_object(repeated_field TSRMLS_CC); + + for (zend_hash_internal_pointer_reset_ex(table, &pointer); + zend_hash_get_current_data_ex(table, (void**)&memory, &pointer) == + SUCCESS; + zend_hash_move_forward_ex(table, &pointer)) { + repeated_field_handlers->write_dimension(repeated_field, NULL, + *(zval**)memory TSRMLS_CC); + } + + Z_DELREF_P(repeated_field); + RETURN_ZVAL(repeated_field, 1, 0); + + } else if (Z_TYPE_P(val) == IS_OBJECT) { + if (!instanceof_function(Z_OBJCE_P(val), repeated_field_type TSRMLS_CC)) { + zend_error(E_USER_ERROR, "Given value is not an instance of %s.", + repeated_field_type->name); + return; + } + RepeatedField* intern = + (RepeatedField*)zend_object_store_get_object(val TSRMLS_CC); + if (to_fieldtype(type) != intern->type) { + zend_error(E_USER_ERROR, "Incorrect repeated field type."); + return; + } + if (klass != NULL && intern->msg_ce != klass) { + zend_error(E_USER_ERROR, + "Expect a repeated field of %s, but %s is given.", klass->name, + intern->msg_ce->name); + return; + } + RETURN_ZVAL(val, 1, 0); + } else { zend_error(E_USER_ERROR, "Incorrect repeated field type."); return; } - if (klass != NULL && intern->msg_ce != klass) { - zend_error(E_USER_ERROR, "Expect a repeated field of %s, but %s is given.", - klass->name, intern->msg_ce->name); + +} + +PHP_METHOD(Util, checkMapField) { + zval* val; + long key_type, value_type; + const zend_class_entry* klass = NULL; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll|C", &val, &key_type, + &value_type, &klass) == FAILURE) { + return; + } + + if (Z_TYPE_P(val) == IS_ARRAY) { + HashTable* table = Z_ARRVAL_P(val); + HashPosition pointer; + zval key, *map_field; + void* value; + + map_field_create_with_type(map_field_type, to_fieldtype(key_type), + to_fieldtype(value_type), klass, + &map_field TSRMLS_CC); + Map* intern = + (Map*)zend_object_store_get_object(map_field TSRMLS_CC); + + for (zend_hash_internal_pointer_reset_ex(table, &pointer); + zend_hash_get_current_data_ex(table, (void**)&value, &pointer) == + SUCCESS; + zend_hash_move_forward_ex(table, &pointer)) { + zend_hash_get_current_key_zval_ex(table, &key, &pointer); + map_field_handlers->write_dimension(map_field, &key, + *(zval**)value TSRMLS_CC); + } + + Z_DELREF_P(map_field); + RETURN_ZVAL(map_field, 1, 0); + } else if (Z_TYPE_P(val) == IS_OBJECT) { + if (!instanceof_function(Z_OBJCE_P(val), map_field_type TSRMLS_CC)) { + zend_error(E_USER_ERROR, "Given value is not an instance of %s.", + map_field_type->name); + return; + } + Map* intern = (Map*)zend_object_store_get_object(val TSRMLS_CC); + if (to_fieldtype(key_type) != intern->key_type) { + zend_error(E_USER_ERROR, "Incorrect map field key type."); + return; + } + if (to_fieldtype(value_type) != intern->value_type) { + zend_error(E_USER_ERROR, "Incorrect map field value type."); + return; + } + if (klass != NULL && intern->msg_ce != klass) { + zend_error(E_USER_ERROR, "Expect a map field of %s, but %s is given.", + klass->name, intern->msg_ce->name); + return; + } + RETURN_ZVAL(val, 1, 0); + } else { + zend_error(E_USER_ERROR, "Incorrect map field type."); return; } } diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c index e0c56f8e..70983016 100644 --- a/php/ext/google/protobuf/upb.c +++ b/php/ext/google/protobuf/upb.c @@ -377,13 +377,14 @@ bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s) { } else if (def->type == UPB_DEF_FIELD) { upb_status_seterrmsg(s, "standalone fielddefs can not be frozen"); goto err; - } else if (def->type == UPB_DEF_ENUM) { - if (!upb_validate_enumdef(upb_dyncast_enumdef(def), s)) { - goto err; - } } else { /* Set now to detect transitive closure in the second pass. */ def->came_from_user = true; + + if (def->type == UPB_DEF_ENUM && + !upb_validate_enumdef(upb_dyncast_enumdef(def), s)) { + goto err; + } } } @@ -710,43 +711,6 @@ upb_fielddef *upb_fielddef_new(const void *o) { return f; } -static upb_fielddef *upb_fielddef_dup(const upb_fielddef *f, - const void *owner) { - const char *srcname; - upb_fielddef *newf = upb_fielddef_new(owner); - if (!newf) return NULL; - upb_fielddef_settype(newf, upb_fielddef_type(f)); - upb_fielddef_setlabel(newf, upb_fielddef_label(f)); - upb_fielddef_setnumber(newf, upb_fielddef_number(f), NULL); - upb_fielddef_setname(newf, upb_fielddef_name(f), NULL); - if (f->default_is_string && f->defaultval.bytes) { - str_t *s = f->defaultval.bytes; - upb_fielddef_setdefaultstr(newf, s->str, s->len, NULL); - } else { - newf->default_is_string = f->default_is_string; - newf->defaultval = f->defaultval; - } - - if (f->subdef_is_symbolic) { - srcname = f->sub.name; /* Might be NULL. */ - } else { - srcname = f->sub.def ? upb_def_fullname(f->sub.def) : NULL; - } - if (srcname) { - char *newname = upb_gmalloc(strlen(f->sub.def->fullname) + 2); - if (!newname) { - upb_fielddef_unref(newf, owner); - return NULL; - } - strcpy(newname, "."); - strcat(newname, f->sub.def->fullname); - upb_fielddef_setsubdefname(newf, newname, NULL); - upb_gfree(newname); - } - - return newf; -} - bool upb_fielddef_typeisset(const upb_fielddef *f) { return f->type_is_set_; } @@ -1426,44 +1390,6 @@ err2: return NULL; } -static upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o, const void *owner); - -static upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner) { - bool ok; - upb_msg_field_iter i; - upb_msg_oneof_iter o; - - upb_msgdef *newm = upb_msgdef_new(owner); - if (!newm) return NULL; - ok = upb_def_setfullname(upb_msgdef_upcast_mutable(newm), - upb_def_fullname(upb_msgdef_upcast(m)), - NULL); - newm->map_entry = m->map_entry; - newm->syntax = m->syntax; - UPB_ASSERT(ok); - for(upb_msg_field_begin(&i, m); - !upb_msg_field_done(&i); - upb_msg_field_next(&i)) { - upb_fielddef *f = upb_fielddef_dup(upb_msg_iter_field(&i), &f); - /* Fields in oneofs are dup'd below. */ - if (upb_fielddef_containingoneof(f)) continue; - if (!f || !upb_msgdef_addfield(newm, f, &f, NULL)) { - upb_msgdef_unref(newm, owner); - return NULL; - } - } - for(upb_msg_oneof_begin(&o, m); - !upb_msg_oneof_done(&o); - upb_msg_oneof_next(&o)) { - upb_oneofdef *f = upb_oneofdef_dup(upb_msg_iter_oneof(&o), &f); - if (!f || !upb_msgdef_addoneof(newm, f, &f, NULL)) { - upb_msgdef_unref(newm, owner); - return NULL; - } - } - return newm; -} - bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status) { upb_def *d = upb_msgdef_upcast_mutable(m); return upb_def_freeze(&d, 1, status); @@ -1764,24 +1690,6 @@ err2: return NULL; } -static upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o, - const void *owner) { - bool ok; - upb_oneof_iter i; - upb_oneofdef *newo = upb_oneofdef_new(owner); - if (!newo) return NULL; - ok = upb_oneofdef_setname(newo, upb_oneofdef_name(o), NULL); - UPB_ASSERT(ok); - for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) { - upb_fielddef *f = upb_fielddef_dup(upb_oneof_iter_field(&i), &f); - if (!f || !upb_oneofdef_addfield(newo, f, &f, NULL)) { - upb_oneofdef_unref(newo, owner); - return NULL; - } - } - return newo; -} - const char *upb_oneofdef_name(const upb_oneofdef *o) { return o->name; } bool upb_oneofdef_setname(upb_oneofdef *o, const char *name, upb_status *s) { @@ -1950,6 +1858,7 @@ static void freefiledef(upb_refcounted *r) { upb_inttable_uninit(&f->deps); upb_gfree((void*)f->name); upb_gfree((void*)f->package); + upb_gfree((void*)f->phpprefix); upb_gfree(f); } @@ -1964,6 +1873,7 @@ upb_filedef *upb_filedef_new(const void *owner) { f->package = NULL; f->name = NULL; + f->phpprefix = NULL; f->syntax = UPB_SYNTAX_PROTO2; if (!upb_refcounted_init(upb_filedef_upcast_mutable(f), &upb_filedef_vtbl, @@ -1998,6 +1908,10 @@ const char *upb_filedef_package(const upb_filedef *f) { return f->package; } +const char *upb_filedef_phpprefix(const upb_filedef *f) { + return f->phpprefix; +} + upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { return f->syntax; } @@ -2054,6 +1968,18 @@ bool upb_filedef_setpackage(upb_filedef *f, const char *package, return true; } +bool upb_filedef_setphpprefix(upb_filedef *f, const char *phpprefix, + upb_status *s) { + phpprefix = upb_gstrdup(phpprefix); + if (!phpprefix) { + upb_upberr_setoom(s); + return false; + } + upb_gfree((void*)f->phpprefix); + f->phpprefix = phpprefix; + return true; +} + bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax, upb_status *s) { UPB_UNUSED(s); @@ -2240,57 +2166,14 @@ static bool symtab_add(upb_symtab *s, upb_def *const*defs, size_t n, fullname); goto err; } - upb_def_donateref(def, ref_donor, s); if (!upb_strtable_insert(&addtab, fullname, upb_value_ptr(def))) goto oom_err; - def->came_from_user = true; - } - } - - /* Add standalone fielddefs (ie. extensions) to the appropriate messages. - * If the appropriate message only exists in the existing symtab, duplicate - * it so we have a mutable copy we can add the fields to. */ - for (i = 0; i < n; i++) { - upb_def *def = defs[i]; - upb_fielddef *f = upb_dyncast_fielddef_mutable(def); - const char *msgname; - upb_value v; - upb_msgdef *m; - - if (!f) continue; - msgname = upb_fielddef_containingtypename(f); - /* We validated this earlier in this function. */ - UPB_ASSERT(msgname); - - /* If the extendee name is absolutely qualified, move past the initial ".". - * TODO(haberman): it is not obvious what it would mean if this was not - * absolutely qualified. */ - if (msgname[0] == '.') { - msgname++; - } - - if (upb_strtable_lookup(&addtab, msgname, &v)) { - /* Extendee is in the set of defs the user asked us to add. */ - m = upb_value_getptr(v); - } else { - /* Need to find and dup the extendee from the existing symtab. */ - const upb_msgdef *frozen_m = upb_symtab_lookupmsg(s, msgname); - if (!frozen_m) { - upb_status_seterrf(status, - "Tried to extend message %s that does not exist " - "in this SymbolTable.", - msgname); - goto err; - } - m = upb_msgdef_dup(frozen_m, s); - if (!m) goto oom_err; - if (!upb_strtable_insert(&addtab, msgname, upb_value_ptr(m))) { - upb_msgdef_unref(m, s); - goto oom_err; - } + upb_def_donateref(def, ref_donor, s); } - if (!upb_msgdef_addfield(m, f, ref_donor, status)) { + if (upb_dyncast_fielddef_mutable(def)) { + /* TODO(haberman): allow adding extensions attached to files. */ + upb_status_seterrf(status, "Can't add extensions to symtab.\n"); goto err; } } @@ -2372,15 +2255,9 @@ static bool symtab_add(upb_symtab *s, upb_def *const*defs, size_t n, for (i = 0; i < add_n; i++) { upb_def *def = (upb_def*)add_objs[i]; const char *name = upb_def_fullname(def); - upb_value v; bool success; - - if (upb_strtable_remove(&s->symtab, name, &v)) { - const upb_def *def = upb_value_getptr(v); - upb_def_unref(def, s); - } success = upb_strtable_insert(&s->symtab, name, upb_value_ptr(def)); - UPB_ASSERT(success == true); + UPB_ASSERT(success); } upb_gfree(add_defs); return true; @@ -3737,8 +3614,7 @@ static bool upb_visitor_visitmsg2(const upb_msg *msg, CHECK_TRUE(upb_sink_putfloat(sink, sel, upb_msgval_getfloat(val))); break; case UPB_TYPE_DOUBLE: - CHECK_TRUE( - upb_sink_putdouble(sink, sel, upb_msgval_getdouble(val))); + CHECK_TRUE(upb_sink_putdouble(sink, sel, upb_msgval_getdouble(val))); break; case UPB_TYPE_BOOL: CHECK_TRUE(upb_sink_putbool(sink, sel, upb_msgval_getbool(val))); @@ -3748,15 +3624,13 @@ static bool upb_visitor_visitmsg2(const upb_msg *msg, CHECK_TRUE(upb_sink_putint32(sink, sel, upb_msgval_getint32(val))); break; case UPB_TYPE_UINT32: - CHECK_TRUE( - upb_sink_putuint32(sink, sel, upb_msgval_getuint32(val))); + CHECK_TRUE(upb_sink_putuint32(sink, sel, upb_msgval_getuint32(val))); break; case UPB_TYPE_INT64: CHECK_TRUE(upb_sink_putint64(sink, sel, upb_msgval_getint64(val))); break; case UPB_TYPE_UINT64: - CHECK_TRUE( - upb_sink_putuint64(sink, sel, upb_msgval_getuint64(val))); + CHECK_TRUE(upb_sink_putuint64(sink, sel, upb_msgval_getuint64(val))); break; case UPB_TYPE_STRING: case UPB_TYPE_BYTES: @@ -6545,14 +6419,14 @@ size_t upb_env_bytesallocated(const upb_env *e) { static const upb_msgdef msgs[22]; -static const upb_fielddef fields[105]; +static const upb_fielddef fields[106]; static const upb_enumdef enums[5]; static const upb_tabent strentries[236]; static const upb_tabent intentries[18]; -static const upb_tabval arrays[184]; +static const upb_tabval arrays[186]; #ifdef UPB_DEBUG_REFS -static upb_inttable reftables[264]; +static upb_inttable reftables[266]; #endif static const upb_msgdef msgs[22] = { @@ -6567,20 +6441,20 @@ static const upb_msgdef msgs[22] = { UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 12, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, &reftables[16], &reftables[17]), UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 42, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, &reftables[18], &reftables[19]), UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, &reftables[20], &reftables[21]), - UPB_MSGDEF_INIT("google.protobuf.FileOptions", 31, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 39, 15), UPB_STRTABLE_INIT(16, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]), - UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 10, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[107], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]), - UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 15, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[115], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]), - UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[122], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]), - UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[123], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]), - UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[125], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]), - UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[129], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]), - UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[130], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]), - UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 19, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[132], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]), - UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[139], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]), - UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[148], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]), + UPB_MSGDEF_INIT("google.protobuf.FileOptions", 34, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 41, 16), UPB_STRTABLE_INIT(17, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]), + UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 10, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[109], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]), + UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 15, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[117], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]), + UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[124], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]), + UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[125], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]), + UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[127], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]), + UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[131], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]), + UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[132], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]), + UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 19, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[134], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]), + UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[141], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]), + UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[150], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]), }; -static const upb_fielddef fields[105] = { +static const upb_fielddef fields[106] = { UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 15, 6, {0},&reftables[44], &reftables[45]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 6, 1, {0},&reftables[46], &reftables[47]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 23, 12, {0},&reftables[48], &reftables[49]), @@ -6590,18 +6464,18 @@ static const upb_fielddef fields[105] = { UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[8], (const upb_def*)(&enums[2]), 6, 1, {0},&reftables[56], &reftables[57]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[7], NULL, 16, 7, {0},&reftables[58], &reftables[59]), UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[9], NULL, 30, 8, {0},&reftables[60], &reftables[61]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 8, 3, {0},&reftables[62], &reftables[63]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 8, 3, {0},&reftables[64], &reftables[65]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 6, 1, {0},&reftables[66], &reftables[67]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 8, 3, {0},&reftables[62], &reftables[63]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 6, 1, {0},&reftables[64], &reftables[65]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 8, 3, {0},&reftables[66], &reftables[67]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 23, &msgs[11], NULL, 21, 10, {0},&reftables[68], &reftables[69]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 7, 2, {0},&reftables[70], &reftables[71]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 6, 1, {0},&reftables[72], &reftables[73]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 6, 1, {0},&reftables[74], &reftables[75]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 6, 1, {0},&reftables[70], &reftables[71]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 7, 2, {0},&reftables[72], &reftables[73]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 6, 1, {0},&reftables[74], &reftables[75]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[20], NULL, 11, 4, {0},&reftables[76], &reftables[77]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[2], NULL, 3, 1, {0},&reftables[78], &reftables[79]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 3, 1, {0},&reftables[80], &reftables[81]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 18, 2, {0},&reftables[82], &reftables[83]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 13, 1, {0},&reftables[84], &reftables[85]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 13, 1, {0},&reftables[82], &reftables[83]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 18, 2, {0},&reftables[84], &reftables[85]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[7], NULL, 7, 2, {0},&reftables[86], &reftables[87]), UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[7]), 24, 4, {0},&reftables[88], &reftables[89]), UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[9], (const upb_def*)(&msgs[7]), 19, 3, {0},&reftables[90], &reftables[91]), @@ -6630,15 +6504,15 @@ static const upb_fielddef fields[105] = { UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[12], NULL, 6, 1, {0},&reftables[136], &reftables[137]), UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 10, 0, {0},&reftables[138], &reftables[139]), UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 6, 0, {0},&reftables[140], &reftables[141]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 8, 2, {0},&reftables[142], &reftables[143]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 2, 0, {0},&reftables[144], &reftables[145]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 5, 0, {0},&reftables[146], &reftables[147]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 32, 8, {0},&reftables[148], &reftables[149]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 4, 1, {0},&reftables[150], &reftables[151]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 22, 6, {0},&reftables[152], &reftables[153]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 4, 1, {0},&reftables[154], &reftables[155]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 4, 1, {0},&reftables[156], &reftables[157]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 8, 2, {0},&reftables[158], &reftables[159]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 5, 0, {0},&reftables[142], &reftables[143]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 32, 8, {0},&reftables[144], &reftables[145]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 4, 1, {0},&reftables[146], &reftables[147]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 4, 1, {0},&reftables[148], &reftables[149]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 8, 2, {0},&reftables[150], &reftables[151]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 8, 2, {0},&reftables[152], &reftables[153]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 2, 0, {0},&reftables[154], &reftables[155]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 4, 1, {0},&reftables[156], &reftables[157]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 22, 6, {0},&reftables[158], &reftables[159]), UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 2, 0, {0},&reftables[160], &reftables[161]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 10, 3, {0},&reftables[162], &reftables[163]), UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 15, 1, {0},&reftables[164], &reftables[165]), @@ -6649,58 +6523,59 @@ static const upb_fielddef fields[105] = { UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 28, 6, {0},&reftables[174], &reftables[175]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 19, 8, {0},&reftables[176], &reftables[177]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 12, 3, {0},&reftables[178], &reftables[179]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 25, 5, {0},&reftables[180], &reftables[181]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 20, 4, {0},&reftables[182], &reftables[183]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 20, 4, {0},&reftables[180], &reftables[181]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 25, 5, {0},&reftables[182], &reftables[183]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 3, 0, {0},&reftables[184], &reftables[185]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 3, 0, {0},&reftables[186], &reftables[187]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 7, 1, {0},&reftables[188], &reftables[189]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 3, 0, {0},&reftables[190], &reftables[191]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 3, 0, {0},&reftables[188], &reftables[189]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 7, 1, {0},&reftables[190], &reftables[191]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 7, 1, {0},&reftables[192], &reftables[193]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 10, 3, {0},&reftables[194], &reftables[195]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 25, 7, {0},&reftables[196], &reftables[197]), UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 7, 2, {0},&reftables[198], &reftables[199]), UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 4, 0, {0},&reftables[200], &reftables[201]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 9, 2, {0},&reftables[202], &reftables[203]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 35, 9, {0},&reftables[204], &reftables[205]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 19, 8, {0},&reftables[206], &reftables[207]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 37, 9, {0},&reftables[208], &reftables[209]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 31, 7, {0},&reftables[210], &reftables[211]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 14, 5, {0},&reftables[212], &reftables[213]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 16, 2, {0},&reftables[214], &reftables[215]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 21, 5, {0},&reftables[216], &reftables[217]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 7, 1, {0},&reftables[218], &reftables[219]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 2, 0, {0},&reftables[220], &reftables[221]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[222], &reftables[223]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 12, 5, {0},&reftables[224], &reftables[225]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 39, 11, {0},&reftables[226], &reftables[227]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 11, 3, {0},&reftables[228], &reftables[229]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[230], &reftables[231]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 13, 6, {0},&reftables[232], &reftables[233]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[234], &reftables[235]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[236], &reftables[237]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[238], &reftables[239]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[240], &reftables[241]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_class_prefix", 40, &msgs[11], NULL, 31, 16, {0},&reftables[202], &reftables[203]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 9, 2, {0},&reftables[204], &reftables[205]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 35, 9, {0},&reftables[206], &reftables[207]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 19, 8, {0},&reftables[208], &reftables[209]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 37, 9, {0},&reftables[210], &reftables[211]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 31, 7, {0},&reftables[212], &reftables[213]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 14, 5, {0},&reftables[214], &reftables[215]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 16, 2, {0},&reftables[216], &reftables[217]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 21, 5, {0},&reftables[218], &reftables[219]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 7, 1, {0},&reftables[220], &reftables[221]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 2, 0, {0},&reftables[222], &reftables[223]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[224], &reftables[225]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 12, 5, {0},&reftables[226], &reftables[227]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 39, 11, {0},&reftables[228], &reftables[229]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 11, 3, {0},&reftables[230], &reftables[231]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[232], &reftables[233]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 13, 6, {0},&reftables[234], &reftables[235]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[236], &reftables[237]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[238], &reftables[239]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[240], &reftables[241]), UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[242], &reftables[243]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[244], &reftables[245]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[246], &reftables[247]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 6, 0, {0},&reftables[248], &reftables[249]), - UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 11, 6, {0},&reftables[250], &reftables[251]), - UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 38, 10, {0},&reftables[252], &reftables[253]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[244], &reftables[245]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[246], &reftables[247]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[248], &reftables[249]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 6, 0, {0},&reftables[250], &reftables[251]), + UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 11, 6, {0},&reftables[252], &reftables[253]), + UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 38, 10, {0},&reftables[254], &reftables[255]), }; static const upb_enumdef enums[5] = { - UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[188]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[151], 4, 3), 0, &reftables[254], &reftables[255]), - UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[192]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[155], 19, 18), 0, &reftables[256], &reftables[257]), - UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[224]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[174], 3, 3), 0, &reftables[258], &reftables[259]), - UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.JSType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[228]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[177], 3, 3), 0, &reftables[260], &reftables[261]), - UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[232]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[180], 4, 3), 0, &reftables[262], &reftables[263]), + UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[188]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[153], 4, 3), 0, &reftables[256], &reftables[257]), + UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[192]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[157], 19, 18), 0, &reftables[258], &reftables[259]), + UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[224]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[176], 3, 3), 0, &reftables[260], &reftables[261]), + UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.JSType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[228]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[179], 3, 3), 0, &reftables[262], &reftables[263]), + UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[232]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[182], 4, 3), 0, &reftables[264], &reftables[265]), }; static const upb_tabent strentries[236] = { {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[82]), NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), NULL}, + {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, @@ -6709,38 +6584,38 @@ static const upb_tabent strentries[236] = { {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "nested_type"), UPB_TABVALUE_PTR_INIT(&fields[60]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL}, - {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[68]), NULL}, + {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[69]), NULL}, {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "oneof_decl"), UPB_TABVALUE_PTR_INIT(&fields[65]), NULL}, - {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[19]), &strentries[13]}, - {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[89]), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), &strentries[13]}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[90]), NULL}, {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[88]), NULL}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[89]), NULL}, {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL}, + {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL}, {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[49]), &strentries[26]}, - {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL}, - {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), &strentries[26]}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL}, {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "allow_alias"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[62]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[34]}, - {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL}, - {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[72]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), &strentries[34]}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "oneof_index"), UPB_TABVALUE_PTR_INIT(&fields[66]), NULL}, {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "label"), UPB_TABVALUE_PTR_INIT(&fields[40]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, @@ -6748,14 +6623,14 @@ static const upb_tabent strentries[236] = { {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[63]), &strentries[53]}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "extendee"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL}, - {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[94]), NULL}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[95]), NULL}, {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "json_name"), UPB_TABVALUE_PTR_INIT(&fields[38]), NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[93]), &strentries[50]}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[94]), &strentries[50]}, {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "default_value"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL}, {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL}, {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, @@ -6766,25 +6641,25 @@ static const upb_tabent strentries[236] = { {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "ctype"), UPB_TABVALUE_PTR_INIT(&fields[6]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "jstype"), UPB_TABVALUE_PTR_INIT(&fields[39]), NULL}, - {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[9]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[23]), NULL}, - {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL}, + {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[105]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), NULL}, - {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), NULL}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[87]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[91]), NULL}, + {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[92]), NULL}, {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "dependency"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL}, {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "message_type"), UPB_TABVALUE_PTR_INIT(&fields[47]), NULL}, {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "package"), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL}, - {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[69]), &strentries[86]}, - {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), NULL}, - {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[80]), &strentries[85]}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[68]), &strentries[86]}, + {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[19]), NULL}, + {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[81]), &strentries[85]}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "file"), UPB_TABVALUE_PTR_INIT(&fields[26]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, @@ -6792,7 +6667,7 @@ static const upb_tabent strentries[236] = { {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "cc_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[3]), NULL}, - {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "csharp_namespace"), UPB_TABVALUE_PTR_INIT(&fields[5]), NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "csharp_namespace"), UPB_TABVALUE_PTR_INIT(&fields[5]), &strentries[116]}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, @@ -6805,7 +6680,7 @@ static const upb_tabent strentries[236] = { {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "java_outer_classname"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL}, - {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[95]), NULL}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, @@ -6813,9 +6688,9 @@ static const upb_tabent strentries[236] = { {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\025", "\000", "\000", "\000", "java_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[32]), &strentries[118]}, {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "java_generate_equals_and_hash"), UPB_TABVALUE_PTR_INIT(&fields[31]), NULL}, - {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "php_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL}, {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "javanano_use_deprecated_package"), UPB_TABVALUE_PTR_INIT(&fields[37]), &strentries[123]}, - {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[81]), NULL}, + {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[82]), NULL}, {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optimize_for"), UPB_TABVALUE_PTR_INIT(&fields[67]), NULL}, {UPB_TABKEY_STR("\026", "\000", "\000", "\000", "java_string_check_utf8"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL}, {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[12]), &strentries[119]}, @@ -6825,32 +6700,32 @@ static const upb_tabent strentries[236] = { {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL}, - {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[9]), NULL}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL}, {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "map_entry"), UPB_TABVALUE_PTR_INIT(&fields[45]), NULL}, {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "no_standard_descriptor_accessor"), UPB_TABVALUE_PTR_INIT(&fields[61]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "client_streaming"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL}, - {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL}, + {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), NULL}, {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "input_type"), UPB_TABVALUE_PTR_INIT(&fields[29]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "output_type"), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL}, {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL}, - {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL}, - {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[72]), &strentries[150]}, + {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), &strentries[150]}, {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "method"), UPB_TABVALUE_PTR_INIT(&fields[48]), NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), &strentries[149]}, - {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL}, - {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[149]}, + {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL}, + {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, @@ -6860,15 +6735,15 @@ static const upb_tabent strentries[236] = { {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[87]), &strentries[167]}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[88]), &strentries[167]}, {UPB_TABKEY_STR("\031", "\000", "\000", "\000", "leading_detached_comments"), UPB_TABVALUE_PTR_INIT(&fields[43]), &strentries[165]}, - {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[92]), NULL}, + {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[93]), NULL}, {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "leading_comments"), UPB_TABVALUE_PTR_INIT(&fields[42]), &strentries[164]}, {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "path"), UPB_TABVALUE_PTR_INIT(&fields[78]), NULL}, {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "double_value"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL}, + {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[49]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, @@ -6878,9 +6753,9 @@ static const upb_tabent strentries[236] = { {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL}, + {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[80]), NULL}, {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "identifier_value"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL}, - {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[90]), &strentries[182]}, + {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[91]), &strentries[182]}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "is_extension"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL}, @@ -6937,64 +6812,64 @@ static const upb_tabent strentries[236] = { static const upb_tabent intentries[18] = { {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[95]), NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL}, + {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL}, + {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL}, {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL}, - {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL}, + {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL}, }; -static const upb_tabval arrays[184] = { +static const upb_tabval arrays[186] = { UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[52]), + UPB_TABVALUE_PTR_INIT(&fields[50]), UPB_TABVALUE_PTR_INIT(&fields[25]), UPB_TABVALUE_PTR_INIT(&fields[60]), - UPB_TABVALUE_PTR_INIT(&fields[19]), + UPB_TABVALUE_PTR_INIT(&fields[20]), UPB_TABVALUE_PTR_INIT(&fields[24]), UPB_TABVALUE_PTR_INIT(&fields[22]), - UPB_TABVALUE_PTR_INIT(&fields[68]), + UPB_TABVALUE_PTR_INIT(&fields[69]), UPB_TABVALUE_PTR_INIT(&fields[65]), + UPB_TABVALUE_PTR_INIT(&fields[84]), UPB_TABVALUE_PTR_INIT(&fields[83]), - UPB_TABVALUE_PTR_INIT(&fields[82]), UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[89]), + UPB_TABVALUE_PTR_INIT(&fields[90]), UPB_TABVALUE_PTR_INIT(&fields[18]), UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[88]), + UPB_TABVALUE_PTR_INIT(&fields[89]), UPB_TABVALUE_PTR_INIT(&fields[17]), UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[49]), - UPB_TABVALUE_PTR_INIT(&fields[102]), + UPB_TABVALUE_PTR_INIT(&fields[54]), + UPB_TABVALUE_PTR_INIT(&fields[103]), UPB_TABVALUE_PTR_INIT(&fields[74]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[1]), - UPB_TABVALUE_PTR_INIT(&fields[13]), + UPB_TABVALUE_PTR_INIT(&fields[14]), UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[53]), + UPB_TABVALUE_PTR_INIT(&fields[51]), UPB_TABVALUE_PTR_INIT(&fields[62]), - UPB_TABVALUE_PTR_INIT(&fields[73]), + UPB_TABVALUE_PTR_INIT(&fields[72]), UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[15]), + UPB_TABVALUE_PTR_INIT(&fields[13]), UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[55]), + UPB_TABVALUE_PTR_INIT(&fields[56]), UPB_TABVALUE_PTR_INIT(&fields[21]), UPB_TABVALUE_PTR_INIT(&fields[63]), UPB_TABVALUE_PTR_INIT(&fields[40]), - UPB_TABVALUE_PTR_INIT(&fields[93]), UPB_TABVALUE_PTR_INIT(&fields[94]), + UPB_TABVALUE_PTR_INIT(&fields[95]), UPB_TABVALUE_PTR_INIT(&fields[7]), UPB_TABVALUE_PTR_INIT(&fields[71]), UPB_TABVALUE_PTR_INIT(&fields[66]), @@ -7002,27 +6877,27 @@ static const upb_tabval arrays[184] = { UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[6]), UPB_TABVALUE_PTR_INIT(&fields[77]), - UPB_TABVALUE_PTR_INIT(&fields[10]), + UPB_TABVALUE_PTR_INIT(&fields[9]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[41]), UPB_TABVALUE_PTR_INIT(&fields[39]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[103]), + UPB_TABVALUE_PTR_INIT(&fields[104]), UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[54]), + UPB_TABVALUE_PTR_INIT(&fields[57]), UPB_TABVALUE_PTR_INIT(&fields[76]), UPB_TABVALUE_PTR_INIT(&fields[8]), UPB_TABVALUE_PTR_INIT(&fields[47]), - UPB_TABVALUE_PTR_INIT(&fields[20]), - UPB_TABVALUE_PTR_INIT(&fields[85]), - UPB_TABVALUE_PTR_INIT(&fields[23]), - UPB_TABVALUE_PTR_INIT(&fields[69]), + UPB_TABVALUE_PTR_INIT(&fields[19]), UPB_TABVALUE_PTR_INIT(&fields[86]), - UPB_TABVALUE_PTR_INIT(&fields[80]), - UPB_TABVALUE_PTR_INIT(&fields[104]), - UPB_TABVALUE_PTR_INIT(&fields[91]), + UPB_TABVALUE_PTR_INIT(&fields[23]), + UPB_TABVALUE_PTR_INIT(&fields[68]), + UPB_TABVALUE_PTR_INIT(&fields[87]), + UPB_TABVALUE_PTR_INIT(&fields[81]), + UPB_TABVALUE_PTR_INIT(&fields[105]), + UPB_TABVALUE_PTR_INIT(&fields[92]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[26]), UPB_TABVALUE_EMPTY_INIT, @@ -7043,7 +6918,7 @@ static const upb_tabval arrays[184] = { UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[3]), UPB_TABVALUE_PTR_INIT(&fields[32]), - UPB_TABVALUE_PTR_INIT(&fields[81]), + UPB_TABVALUE_PTR_INIT(&fields[82]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[31]), UPB_TABVALUE_EMPTY_INIT, @@ -7065,45 +6940,47 @@ static const upb_tabval arrays[184] = { UPB_TABVALUE_PTR_INIT(&fields[5]), UPB_TABVALUE_PTR_INIT(&fields[37]), UPB_TABVALUE_EMPTY_INIT, + UPB_TABVALUE_PTR_INIT(&fields[79]), + UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[46]), UPB_TABVALUE_PTR_INIT(&fields[61]), - UPB_TABVALUE_PTR_INIT(&fields[9]), + UPB_TABVALUE_PTR_INIT(&fields[11]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[45]), UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[56]), + UPB_TABVALUE_PTR_INIT(&fields[52]), UPB_TABVALUE_PTR_INIT(&fields[29]), UPB_TABVALUE_PTR_INIT(&fields[75]), UPB_TABVALUE_PTR_INIT(&fields[70]), UPB_TABVALUE_PTR_INIT(&fields[4]), - UPB_TABVALUE_PTR_INIT(&fields[84]), + UPB_TABVALUE_PTR_INIT(&fields[85]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[50]), + UPB_TABVALUE_PTR_INIT(&fields[55]), UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[57]), + UPB_TABVALUE_PTR_INIT(&fields[53]), UPB_TABVALUE_PTR_INIT(&fields[48]), - UPB_TABVALUE_PTR_INIT(&fields[72]), + UPB_TABVALUE_PTR_INIT(&fields[73]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[44]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[78]), - UPB_TABVALUE_PTR_INIT(&fields[87]), + UPB_TABVALUE_PTR_INIT(&fields[88]), UPB_TABVALUE_PTR_INIT(&fields[42]), - UPB_TABVALUE_PTR_INIT(&fields[92]), + UPB_TABVALUE_PTR_INIT(&fields[93]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[43]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_EMPTY_INIT, - UPB_TABVALUE_PTR_INIT(&fields[51]), + UPB_TABVALUE_PTR_INIT(&fields[49]), UPB_TABVALUE_PTR_INIT(&fields[28]), - UPB_TABVALUE_PTR_INIT(&fields[79]), + UPB_TABVALUE_PTR_INIT(&fields[80]), UPB_TABVALUE_PTR_INIT(&fields[59]), UPB_TABVALUE_PTR_INIT(&fields[16]), - UPB_TABVALUE_PTR_INIT(&fields[90]), + UPB_TABVALUE_PTR_INIT(&fields[91]), UPB_TABVALUE_PTR_INIT(&fields[0]), UPB_TABVALUE_EMPTY_INIT, UPB_TABVALUE_PTR_INIT(&fields[58]), @@ -7144,7 +7021,9 @@ static const upb_tabval arrays[184] = { }; #ifdef UPB_DEBUG_REFS -static upb_inttable reftables[264] = { +static upb_inttable reftables[266] = { + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), + UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR), @@ -7686,6 +7565,21 @@ static size_t file_onpackage(void *closure, const void *hd, const char *buf, return n; } +static size_t file_onphpprefix(void *closure, const void *hd, const char *buf, + size_t n, const upb_bufhandle *handle) { + upb_descreader *r = closure; + char *prefix; + bool ok; + UPB_UNUSED(hd); + UPB_UNUSED(handle); + + prefix = upb_gstrndup(buf, n); + ok = upb_filedef_setphpprefix(r->file, prefix, NULL); + upb_gfree(prefix); + UPB_ASSERT(ok); + return n; +} + static size_t file_onsyntax(void *closure, const void *hd, const char *buf, size_t n, const upb_bufhandle *handle) { upb_descreader *r = closure; @@ -8212,6 +8106,9 @@ static void reghandlers(const void *closure, upb_handlers *h) { upb_handlers_setbool(h, F(FieldOptions, packed), &field_onpacked, NULL); } else if (upbdefs_google_protobuf_MessageOptions_is(m)) { upb_handlers_setbool(h, F(MessageOptions, map_entry), &msg_onmapentry, NULL); + } else if (upbdefs_google_protobuf_FileOptions_is(m)) { + upb_handlers_setstring(h, F(FileOptions, php_class_prefix), + &file_onphpprefix, NULL); } UPB_ASSERT(upb_ok(upb_handlers_status(h))); @@ -10759,7 +10656,7 @@ static size_t encode_strbuf(void *c, const void *hd, const char *buf, T(double, double, dbl2uint64, encode_fixed64) T(float, float, flt2uint32, encode_fixed32) T(int64, int64_t, uint64_t, encode_varint) -T(int32, int32_t, uint32_t, encode_varint) +T(int32, int32_t, int64_t, encode_varint) T(fixed64, uint64_t, uint64_t, encode_fixed64) T(fixed32, uint32_t, uint32_t, encode_fixed32) T(bool, bool, bool, encode_varint) diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h index 5f780458..78f255f9 100644 --- a/php/ext/google/protobuf/upb.h +++ b/php/ext/google/protobuf/upb.h @@ -2972,6 +2972,11 @@ class upb::FileDef { const char* package() const; bool set_package(const char* package, Status* s); + /* Sets the php class prefix which is prepended to all php generated classes + / from this .proto. Default is empty. */ + const char* phpprefix() const; + bool set_phpprefix(const char* phpprefix, Status* s); + /* Syntax for the file. Defaults to proto2. */ upb_syntax_t syntax() const; void set_syntax(upb_syntax_t syntax); @@ -3025,6 +3030,7 @@ UPB_REFCOUNTED_CMETHODS(upb_filedef, upb_filedef_upcast) const char *upb_filedef_name(const upb_filedef *f); const char *upb_filedef_package(const upb_filedef *f); +const char *upb_filedef_phpprefix(const upb_filedef *f); upb_syntax_t upb_filedef_syntax(const upb_filedef *f); size_t upb_filedef_defcount(const upb_filedef *f); size_t upb_filedef_depcount(const upb_filedef *f); @@ -3034,6 +3040,8 @@ const upb_filedef *upb_filedef_dep(const upb_filedef *f, size_t i); bool upb_filedef_freeze(upb_filedef *f, upb_status *s); bool upb_filedef_setname(upb_filedef *f, const char *name, upb_status *s); bool upb_filedef_setpackage(upb_filedef *f, const char *package, upb_status *s); +bool upb_filedef_setphpprefix(upb_filedef *f, const char *phpprefix, + upb_status *s); bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax, upb_status *s); bool upb_filedef_adddef(upb_filedef *f, upb_def *def, const void *ref_donor, @@ -3792,6 +3800,12 @@ inline const char* FileDef::package() const { inline bool FileDef::set_package(const char* package, Status* s) { return upb_filedef_setpackage(this, package, s); } +inline const char* FileDef::phpprefix() const { + return upb_filedef_phpprefix(this); +} +inline bool FileDef::set_phpprefix(const char* phpprefix, Status* s) { + return upb_filedef_setphpprefix(this, phpprefix, s); +} inline int FileDef::def_count() const { return upb_filedef_defcount(this); } @@ -4006,6 +4020,7 @@ struct upb_filedef { const char *name; const char *package; + const char *phpprefix; upb_syntax_t syntax; upb_inttable defs; @@ -7212,6 +7227,7 @@ UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_java_string UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_javanano_use_deprecated_package(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 38); } UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_objc_class_prefix(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 36); } UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_optimize_for(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 9); } +UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_php_class_prefix(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 40); } UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_py_generic_services(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 18); } UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_uninterpreted_option(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 999); } UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_f_deprecated(const upb_msgdef *m) { UPB_ASSERT(upbdefs_google_protobuf_MessageOptions_is(m)); return upb_msgdef_itof(m, 3); } diff --git a/php/generate_descriptor_protos.sh b/php/generate_descriptor_protos.sh new file mode 100755 index 00000000..372ad69c --- /dev/null +++ b/php/generate_descriptor_protos.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Run this script to regenerate desriptor protos after the protocol compiler +# changes. + +if test ! -e src/google/protobuf/stubs/common.h; then + cat >&2 << __EOF__ +Could not find source code. Make sure you are running this script from the +root of the distribution tree. +__EOF__ + exit 1 +fi + +pushd src +./protoc --php_out=internal:../php/src google/protobuf/descriptor.proto +popd diff --git a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php index 7c5c8df4..1b6b3d60 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php @@ -144,6 +144,7 @@ class Descriptor ->optional('objc_class_prefix', \Google\Protobuf\Internal\GPBType::STRING, 36) ->optional('csharp_namespace', \Google\Protobuf\Internal\GPBType::STRING, 37) ->optional('swift_prefix', \Google\Protobuf\Internal\GPBType::STRING, 39) + ->optional('php_class_prefix', \Google\Protobuf\Internal\GPBType::STRING, 40) ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->finalizeToPool(); diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto.php b/php/src/Google/Protobuf/Internal/DescriptorProto.php index f076f6be..948c5876 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto.php @@ -117,8 +117,8 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message */ public function setField(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); - $this->field = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); + $this->field = $arr; $this->has_field = true; } @@ -140,8 +140,8 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message */ public function setExtension(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); - $this->extension = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); + $this->extension = $arr; $this->has_extension = true; } @@ -163,8 +163,8 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message */ public function setNestedType(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); - $this->nested_type = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); + $this->nested_type = $arr; $this->has_nested_type = true; } @@ -186,8 +186,8 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message */ public function setEnumType(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); - $this->enum_type = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); + $this->enum_type = $arr; $this->has_enum_type = true; } @@ -209,8 +209,8 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message */ public function setExtensionRange(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class); - $this->extension_range = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ExtensionRange::class); + $this->extension_range = $arr; $this->has_extension_range = true; } @@ -232,8 +232,8 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message */ public function setOneofDecl(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\OneofDescriptorProto::class); - $this->oneof_decl = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\OneofDescriptorProto::class); + $this->oneof_decl = $arr; $this->has_oneof_decl = true; } @@ -278,8 +278,8 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message */ public function setReservedRange(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class); - $this->reserved_range = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto_ReservedRange::class); + $this->reserved_range = $arr; $this->has_reserved_range = true; } @@ -311,8 +311,8 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message */ public function setReservedName(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); - $this->reserved_name = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); + $this->reserved_name = $arr; $this->has_reserved_name = true; } diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php index 9c5f245b..73f6edbd 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php @@ -77,8 +77,8 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message */ public function setValue(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumValueDescriptorProto::class); - $this->value = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumValueDescriptorProto::class); + $this->value = $arr; $this->has_value = true; } diff --git a/php/src/Google/Protobuf/Internal/EnumOptions.php b/php/src/Google/Protobuf/Internal/EnumOptions.php index a9c4e0d7..4fa0bce7 100644 --- a/php/src/Google/Protobuf/Internal/EnumOptions.php +++ b/php/src/Google/Protobuf/Internal/EnumOptions.php @@ -144,8 +144,8 @@ class EnumOptions extends \Google\Protobuf\Internal\Message */ public function setUninterpretedOption(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); - $this->uninterpreted_option = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); + $this->uninterpreted_option = $arr; $this->has_uninterpreted_option = true; } diff --git a/php/src/Google/Protobuf/Internal/EnumValueOptions.php b/php/src/Google/Protobuf/Internal/EnumValueOptions.php index 6446ecd4..232a6738 100644 --- a/php/src/Google/Protobuf/Internal/EnumValueOptions.php +++ b/php/src/Google/Protobuf/Internal/EnumValueOptions.php @@ -101,8 +101,8 @@ class EnumValueOptions extends \Google\Protobuf\Internal\Message */ public function setUninterpretedOption(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); - $this->uninterpreted_option = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); + $this->uninterpreted_option = $arr; $this->has_uninterpreted_option = true; } diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php index 06f26015..a3cd8ef9 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php @@ -2,11 +2,11 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto +namespace Google\Protobuf\Internal; + /** * Protobuf enum <code>google.protobuf.FieldDescriptorProto.Label</code> */ -namespace Google\Protobuf\Internal; - class FieldDescriptorProto_Label { /** diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php index 9bda76c2..8335f9b1 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php @@ -2,11 +2,11 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto +namespace Google\Protobuf\Internal; + /** * Protobuf enum <code>google.protobuf.FieldDescriptorProto.Type</code> */ -namespace Google\Protobuf\Internal; - class FieldDescriptorProto_Type { /** @@ -63,6 +63,9 @@ class FieldDescriptorProto_Type /** * <pre> * Tag-delimited aggregate. + * Group type is deprecated and not supported in proto3. However, Proto3 + * implementations should still be able to parse the group wire format and + * treat group fields as unknown fields. * </pre> * * <code>TYPE_GROUP = 10;</code> diff --git a/php/src/Google/Protobuf/Internal/FieldOptions.php b/php/src/Google/Protobuf/Internal/FieldOptions.php index af1393a5..8db7ed67 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions.php @@ -415,8 +415,8 @@ class FieldOptions extends \Google\Protobuf\Internal\Message */ public function setUninterpretedOption(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); - $this->uninterpreted_option = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); + $this->uninterpreted_option = $arr; $this->has_uninterpreted_option = true; } diff --git a/php/src/Google/Protobuf/Internal/FieldOptions_CType.php b/php/src/Google/Protobuf/Internal/FieldOptions_CType.php index 2ff2a478..f59f20be 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions_CType.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions_CType.php @@ -2,11 +2,11 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto +namespace Google\Protobuf\Internal; + /** * Protobuf enum <code>google.protobuf.FieldOptions.CType</code> */ -namespace Google\Protobuf\Internal; - class FieldOptions_CType { /** diff --git a/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php b/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php index 541c8ae5..0c6995b7 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php @@ -2,11 +2,11 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto +namespace Google\Protobuf\Internal; + /** * Protobuf enum <code>google.protobuf.FieldOptions.JSType</code> */ -namespace Google\Protobuf\Internal; - class FieldOptions_JSType { /** diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php index 39f67768..0363d9e9 100644 --- a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php @@ -206,8 +206,8 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function setDependency(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); - $this->dependency = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); + $this->dependency = $arr; $this->has_dependency = true; } @@ -237,8 +237,8 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function setPublicDependency(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); - $this->public_dependency = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); + $this->public_dependency = $arr; $this->has_public_dependency = true; } @@ -270,8 +270,8 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function setWeakDependency(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); - $this->weak_dependency = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); + $this->weak_dependency = $arr; $this->has_weak_dependency = true; } @@ -301,8 +301,8 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function setMessageType(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); - $this->message_type = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); + $this->message_type = $arr; $this->has_message_type = true; } @@ -324,8 +324,8 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function setEnumType(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); - $this->enum_type = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); + $this->enum_type = $arr; $this->has_enum_type = true; } @@ -347,8 +347,8 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function setService(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\ServiceDescriptorProto::class); - $this->service = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\ServiceDescriptorProto::class); + $this->service = $arr; $this->has_service = true; } @@ -370,8 +370,8 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message */ public function setExtension(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); - $this->extension = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); + $this->extension = $arr; $this->has_extension = true; } diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php index 20a165c4..0bcc8051 100644 --- a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php +++ b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php @@ -45,8 +45,8 @@ class FileDescriptorSet extends \Google\Protobuf\Internal\Message */ public function setFile(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FileDescriptorProto::class); - $this->file = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FileDescriptorProto::class); + $this->file = $arr; $this->has_file = true; } diff --git a/php/src/Google/Protobuf/Internal/FileOptions.php b/php/src/Google/Protobuf/Internal/FileOptions.php index 2422f3ee..22653a4f 100644 --- a/php/src/Google/Protobuf/Internal/FileOptions.php +++ b/php/src/Google/Protobuf/Internal/FileOptions.php @@ -178,6 +178,16 @@ class FileOptions extends \Google\Protobuf\Internal\Message private $has_swift_prefix = false; /** * <pre> + * Sets the php class prefix which is prepended to all php generated classes + * from this .proto. Default is empty. + * </pre> + * + * <code>optional string php_class_prefix = 40;</code> + */ + private $php_class_prefix = ''; + private $has_php_class_prefix = false; + /** + * <pre> * The parser stores options it doesn't recognize here. See above. * </pre> * @@ -708,6 +718,39 @@ class FileOptions extends \Google\Protobuf\Internal\Message /** * <pre> + * Sets the php class prefix which is prepended to all php generated classes + * from this .proto. Default is empty. + * </pre> + * + * <code>optional string php_class_prefix = 40;</code> + */ + public function getPhpClassPrefix() + { + return $this->php_class_prefix; + } + + /** + * <pre> + * Sets the php class prefix which is prepended to all php generated classes + * from this .proto. Default is empty. + * </pre> + * + * <code>optional string php_class_prefix = 40;</code> + */ + public function setPhpClassPrefix($var) + { + GPBUtil::checkString($var, True); + $this->php_class_prefix = $var; + $this->has_php_class_prefix = true; + } + + public function hasPhpClassPrefix() + { + return $this->has_php_class_prefix; + } + + /** + * <pre> * The parser stores options it doesn't recognize here. See above. * </pre> * @@ -727,8 +770,8 @@ class FileOptions extends \Google\Protobuf\Internal\Message */ public function setUninterpretedOption(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); - $this->uninterpreted_option = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); + $this->uninterpreted_option = $arr; $this->has_uninterpreted_option = true; } diff --git a/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php b/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php index 7fd488eb..b550e7f1 100644 --- a/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php +++ b/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php @@ -2,6 +2,8 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto +namespace Google\Protobuf\Internal; + /** * <pre> * Generated classes can be optimized for speed or code size. @@ -9,8 +11,6 @@ * * Protobuf enum <code>google.protobuf.FileOptions.OptimizeMode</code> */ -namespace Google\Protobuf\Internal; - class FileOptions_OptimizeMode { /** diff --git a/php/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php index ba1d2eb3..0e66ae6f 100644 --- a/php/src/Google/Protobuf/Internal/GPBUtil.php +++ b/php/src/Google/Protobuf/Internal/GPBUtil.php @@ -34,6 +34,7 @@ namespace Google\Protobuf\Internal; use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\RepeatedField; +use Google\Protobuf\Internal\MapField; class GPBUtil { @@ -175,19 +176,60 @@ class GPBUtil public static function checkRepeatedField(&$var, $type, $klass = null) { - if (!$var instanceof RepeatedField) { - trigger_error("Expect repeated field.", E_USER_ERROR); - } - if ($var->getType() != $type) { - trigger_error( - "Expect repeated field of different type.", - E_USER_ERROR); - } - if ($var->getType() === GPBType::MESSAGE && - $var->getClass() !== $klass) { - trigger_error( - "Expect repeated field of different message.", - E_USER_ERROR); + if (!$var instanceof RepeatedField && !is_array($var)) { + trigger_error("Expect array.", E_USER_ERROR); + } + if (is_array($var)) { + $tmp = new RepeatedField($type, $klass); + foreach ($var as $value) { + $tmp[] = $value; + } + return $tmp; + } else { + if ($var->getType() != $type) { + trigger_error( + "Expect repeated field of different type.", + E_USER_ERROR); + } + if ($var->getType() === GPBType::MESSAGE && + $var->getClass() !== $klass) { + trigger_error( + "Expect repeated field of different message.", + E_USER_ERROR); + } + return $var; + } + } + + public static function checkMapField(&$var, $key_type, $value_type, $klass = null) + { + if (!$var instanceof MapField && !is_array($var)) { + trigger_error("Expect dict.", E_USER_ERROR); + } + if (is_array($var)) { + $tmp = new MapField($key_type, $value_type, $klass); + foreach ($var as $key => $value) { + $tmp[$key] = $value; + } + return $tmp; + } else { + if ($var->getKeyType() != $key_type) { + trigger_error( + "Expect map field of key type.", + E_USER_ERROR); + } + if ($var->getValueType() != $value_type) { + trigger_error( + "Expect map field of value type.", + E_USER_ERROR); + } + if ($var->getValueType() === GPBType::MESSAGE && + $var->getValueClass() !== $klass) { + trigger_error( + "Expect map field of different value message.", + E_USER_ERROR); + } + return $var; } } diff --git a/php/src/Google/Protobuf/Internal/GPBWire.php b/php/src/Google/Protobuf/Internal/GPBWire.php index f75e0861..67eb1bee 100644 --- a/php/src/Google/Protobuf/Internal/GPBWire.php +++ b/php/src/Google/Protobuf/Internal/GPBWire.php @@ -403,10 +403,14 @@ class GPBWire return self::varint32Size($tag); } - public static function varint32Size($value) + public static function varint32Size($value, $sign_extended = false) { if ($value < 0) { - return 5; + if ($sign_extended) { + return 10; + } else { + return 5; + } } if ($value < (1 << 7)) { return 1; diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php index 8e493c2f..450854f1 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php @@ -61,8 +61,8 @@ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message */ public function setAnnotation(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation::class); - $this->annotation = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo_Annotation::class); + $this->annotation = $arr; $this->has_annotation = true; } diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php index dcc7edfe..ed22cc38 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php @@ -85,8 +85,8 @@ class GeneratedCodeInfo_Annotation extends \Google\Protobuf\Internal\Message */ public function setPath(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); - $this->path = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); + $this->path = $arr; $this->has_path = true; } diff --git a/php/src/Google/Protobuf/Internal/InputStream.php b/php/src/Google/Protobuf/Internal/InputStream.php index bf052c2f..de5ca978 100644 --- a/php/src/Google/Protobuf/Internal/InputStream.php +++ b/php/src/Google/Protobuf/Internal/InputStream.php @@ -70,7 +70,6 @@ class InputStream private $total_bytes_read; const MAX_VARINT_BYTES = 10; - const MAX_VARINT32_BYTES = 5; const DEFAULT_RECURSION_LIMIT = 100; const DEFAULT_TOTAL_BYTES_LIMIT = 33554432; // 32 << 20, 32MB diff --git a/php/src/Google/Protobuf/Internal/MapField.php b/php/src/Google/Protobuf/Internal/MapField.php index 14ee7ebe..68c10c08 100644 --- a/php/src/Google/Protobuf/Internal/MapField.php +++ b/php/src/Google/Protobuf/Internal/MapField.php @@ -204,6 +204,30 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable } /** + * @ignore + */ + public function getKeyType() + { + return $this->key_type; + } + + /** + * @ignore + */ + public function getValueType() + { + return $this->value_type; + } + + /** + * @ignore + */ + public function getValueClass() + { + return $this->klass; + } + + /** * Return the element at the given key. * * This will also be called for: $ele = $arr[$key] diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index ca4fde02..887c86ca 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -772,9 +772,11 @@ class Message case GPBType::SFIXED64: $size += 8; break; - case GPBType::UINT32: case GPBType::INT32: case GPBType::ENUM: + $size += GPBWire::varint32Size($value, true); + break; + case GPBType::UINT32: $size += GPBWire::varint32Size($value); break; case GPBType::UINT64: diff --git a/php/src/Google/Protobuf/Internal/MessageOptions.php b/php/src/Google/Protobuf/Internal/MessageOptions.php index e4a214cb..747f3294 100644 --- a/php/src/Google/Protobuf/Internal/MessageOptions.php +++ b/php/src/Google/Protobuf/Internal/MessageOptions.php @@ -320,8 +320,8 @@ class MessageOptions extends \Google\Protobuf\Internal\Message */ public function setUninterpretedOption(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); - $this->uninterpreted_option = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); + $this->uninterpreted_option = $arr; $this->has_uninterpreted_option = true; } diff --git a/php/src/Google/Protobuf/Internal/MethodOptions.php b/php/src/Google/Protobuf/Internal/MethodOptions.php index 3325e52b..6dca5854 100644 --- a/php/src/Google/Protobuf/Internal/MethodOptions.php +++ b/php/src/Google/Protobuf/Internal/MethodOptions.php @@ -129,8 +129,8 @@ class MethodOptions extends \Google\Protobuf\Internal\Message */ public function setUninterpretedOption(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); - $this->uninterpreted_option = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); + $this->uninterpreted_option = $arr; $this->has_uninterpreted_option = true; } diff --git a/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php b/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php index 62768b5c..ce4adfe7 100644 --- a/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php +++ b/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php @@ -2,6 +2,8 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: google/protobuf/descriptor.proto +namespace Google\Protobuf\Internal; + /** * <pre> * Is this method side-effect-free (or safe in HTTP parlance), or idempotent, @@ -11,8 +13,6 @@ * * Protobuf enum <code>google.protobuf.MethodOptions.IdempotencyLevel</code> */ -namespace Google\Protobuf\Internal; - class MethodOptions_IdempotencyLevel { /** diff --git a/php/src/Google/Protobuf/Internal/OneofOptions.php b/php/src/Google/Protobuf/Internal/OneofOptions.php index 083d9929..b61325d2 100644 --- a/php/src/Google/Protobuf/Internal/OneofOptions.php +++ b/php/src/Google/Protobuf/Internal/OneofOptions.php @@ -52,8 +52,8 @@ class OneofOptions extends \Google\Protobuf\Internal\Message */ public function setUninterpretedOption(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); - $this->uninterpreted_option = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); + $this->uninterpreted_option = $arr; $this->has_uninterpreted_option = true; } diff --git a/php/src/Google/Protobuf/Internal/OutputStream.php b/php/src/Google/Protobuf/Internal/OutputStream.php index 587ac352..8c6d9b68 100644 --- a/php/src/Google/Protobuf/Internal/OutputStream.php +++ b/php/src/Google/Protobuf/Internal/OutputStream.php @@ -39,7 +39,6 @@ class OutputStream private $buffer_size; private $current; - const MAX_VARINT32_BYTES = 5; const MAX_VARINT64_BYTES = 10; public function __construct($size) @@ -56,8 +55,8 @@ class OutputStream public function writeVarint32($value) { - $bytes = str_repeat(chr(0), self::MAX_VARINT32_BYTES); - $size = self::writeVarintToArray($value, $bytes, true); + $bytes = str_repeat(chr(0), self::MAX_VARINT64_BYTES); + $size = self::writeVarintToArray($value, $bytes); return $this->writeRaw($bytes, $size); } @@ -102,20 +101,16 @@ class OutputStream return true; } - private static function writeVarintToArray($value, &$buffer, $trim = false) + private static function writeVarintToArray($value, &$buffer) { $current = 0; $high = 0; $low = 0; if (PHP_INT_SIZE == 4) { - GPBUtil::divideInt64ToInt32($value, $high, $low, $trim); + GPBUtil::divideInt64ToInt32($value, $high, $low); } else { - if ($trim) { - $low = $value & 0xFFFFFFFF; - } else { - $low = $value; - } + $low = $value; } while ($low >= 0x80 || $low < 0) { diff --git a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php index 624bde84..47776202 100644 --- a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php @@ -77,8 +77,8 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message */ public function setMethod(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\MethodDescriptorProto::class); - $this->method = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\MethodDescriptorProto::class); + $this->method = $arr; $this->has_method = true; } diff --git a/php/src/Google/Protobuf/Internal/ServiceOptions.php b/php/src/Google/Protobuf/Internal/ServiceOptions.php index 5f3564e4..62323dba 100644 --- a/php/src/Google/Protobuf/Internal/ServiceOptions.php +++ b/php/src/Google/Protobuf/Internal/ServiceOptions.php @@ -101,8 +101,8 @@ class ServiceOptions extends \Google\Protobuf\Internal\Message */ public function setUninterpretedOption(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); - $this->uninterpreted_option = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); + $this->uninterpreted_option = $arr; $this->has_uninterpreted_option = true; } diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php index d2352ddd..eab60880 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php @@ -177,8 +177,8 @@ class SourceCodeInfo extends \Google\Protobuf\Internal\Message */ public function setLocation(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo_Location::class); - $this->location = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo_Location::class); + $this->location = $arr; $this->has_location = true; } diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php index d1bdb166..5a02b26c 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php @@ -179,8 +179,8 @@ class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message */ public function setPath(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); - $this->path = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); + $this->path = $arr; $this->has_path = true; } @@ -218,8 +218,8 @@ class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message */ public function setSpan(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); - $this->span = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); + $this->span = $arr; $this->has_span = true; } @@ -365,8 +365,8 @@ class SourceCodeInfo_Location extends \Google\Protobuf\Internal\Message */ public function setLeadingDetachedComments(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); - $this->leading_detached_comments = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); + $this->leading_detached_comments = $arr; $this->has_leading_detached_comments = true; } diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption.php b/php/src/Google/Protobuf/Internal/UninterpretedOption.php index c0f48310..28655019 100644 --- a/php/src/Google/Protobuf/Internal/UninterpretedOption.php +++ b/php/src/Google/Protobuf/Internal/UninterpretedOption.php @@ -84,8 +84,8 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message */ public function setName(&$var) { - GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption_NamePart::class); - $this->name = $var; + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption_NamePart::class); + $this->name = $arr; $this->has_name = true; } diff --git a/php/src/Google/Protobuf/descriptor.php b/php/src/Google/Protobuf/descriptor.php index 9e56ef27..2263af6e 100644 --- a/php/src/Google/Protobuf/descriptor.php +++ b/php/src/Google/Protobuf/descriptor.php @@ -78,14 +78,14 @@ class FileDescriptor $file->setPackage($proto->getPackage()); foreach ($proto->getMessageType() as $message_proto) { $file->addMessageType(Descriptor::buildFromProto( - $message_proto, $file->getPackage(), "")); + $message_proto, $proto, "")); } foreach ($proto->getEnumType() as $enum_proto) { $file->getEnumType()[] = $file->addEnumType( EnumDescriptor::buildFromProto( $enum_proto, - $file->getPackage(), + $proto, "")); } return $file; @@ -182,7 +182,7 @@ class Descriptor return $this->options; } - public static function buildFromProto($proto, $package, $containing) + public static function buildFromProto($proto, $file_proto, $containing) { $desc = new Descriptor(); @@ -192,7 +192,7 @@ class Descriptor getFullClassName( $proto, $containing, - $package, + $file_proto, $message_name_without_package, $classname, $fullname); @@ -207,7 +207,7 @@ class Descriptor // Handle nested types. foreach ($proto->getNestedType() as $nested_proto) { $desc->addNestedType(Descriptor::buildFromProto( - $nested_proto, $package, $message_name_without_package)); + $nested_proto, $file_proto, $message_name_without_package)); } // Handle oneof fields. @@ -220,43 +220,46 @@ class Descriptor } } -function addPrefixIfSpecial( +function getClassNameWithoutPackage( $name, - $package) + $file_proto) { - if ($name === "Empty" && $package === "google.protobuf") { + if ($name === "Empty" && $file_proto->getPackage() === "google.protobuf") { return "GPBEmpty"; } else { - return $name; + $option = $file_proto->getOptions(); + $prefix = is_null($option) ? "" : $option->getPhpClassPrefix(); + // Nested message class names are seperated by '_', and package names + // are seperated by '\'. + return $prefix . implode('_', array_map('ucwords', + explode('.', $name))); } } function getFullClassName( $proto, $containing, - $package, + $file_proto, &$message_name_without_package, &$classname, &$fullname) { // Full name needs to start with '.'. - $message_name_without_package = - addPrefixIfSpecial($proto->getName(), $package); + $message_name_without_package = $proto->getName(); if ($containing !== "") { $message_name_without_package = $containing . "." . $message_name_without_package; } + + $package = $file_proto->getPackage(); if ($package === "") { $fullname = "." . $message_name_without_package; } else { $fullname = "." . $package . "." . $message_name_without_package; } - // Nested message class names are seperated by '_', and package names are - // seperated by '\'. $class_name_without_package = - implode('_', array_map('ucwords', - explode('.', $message_name_without_package))); + getClassNameWithoutPackage($message_name_without_package, $file_proto); if ($package === "") { $classname = $class_name_without_package; } else { @@ -333,7 +336,7 @@ class EnumDescriptor return $this->klass; } - public static function buildFromProto($proto, $package, $containing) + public static function buildFromProto($proto, $file_proto, $containing) { $desc = new EnumDescriptor(); @@ -343,7 +346,7 @@ class EnumDescriptor getFullClassName( $proto, $containing, - $package, + $file_proto, $enum_name_without_package, $classname, $fullname); diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php index b54b1239..94adf793 100644 --- a/php/tests/encode_decode_test.php +++ b/php/tests/encode_decode_test.php @@ -190,6 +190,27 @@ class EncodeDecodeTest extends TestBase $m->mergeFromString($data); } + public function testEncodeNegativeInt32() + { + $m = new TestMessage(); + $m->setOptionalInt32(-1); + $data = $m->serializeToString(); + $this->assertSame("08ffffffffffffffffff01", bin2hex($data)); + } + + public function testDecodeNegativeInt32() + { + $m = new TestMessage(); + $this->assertEquals(0, $m->getOptionalInt32()); + $m->mergeFromString(hex2bin("08ffffffffffffffffff01")); + $this->assertEquals(-1, $m->getOptionalInt32()); + + $m = new TestMessage(); + $this->assertEquals(0, $m->getOptionalInt32()); + $m->mergeFromString(hex2bin("08ffffffff0f")); + $this->assertEquals(-1, $m->getOptionalInt32()); + } + # TODO(teboring): Add test back when php implementation is ready for json # encode/decode. # public function testJsonEncode() diff --git a/php/tests/gdb_test.sh b/php/tests/gdb_test.sh index 3c0d97a2..45a2841f 100755 --- a/php/tests/gdb_test.sh +++ b/php/tests/gdb_test.sh @@ -3,7 +3,7 @@ # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which # phpunit` --bootstrap autoload.php tmp_test.php # -gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php encode_decode_test.php +gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php array_test.php # # # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so # memory_leak_test.php diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index 7f8567b8..39e6c6c4 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -6,8 +6,10 @@ require_once('test_base.php'); require_once('test_util.php'); use Google\Protobuf\Internal\RepeatedField; +use Google\Protobuf\Internal\MapField; use Google\Protobuf\Internal\GPBType; use Foo\TestEnum; +use Foo\TestIncludePrefixMessage; use Foo\TestMessage; use Foo\TestMessage_Sub; @@ -526,6 +528,26 @@ class GeneratedClassTest extends TestBase $this->assertSame($repeated_int32, $m->getRepeatedInt32()); } + public function testRepeatedFieldViaArray() + { + $m = new TestMessage(); + + $arr = array(); + $m->setRepeatedInt32($arr); + $this->assertSame(0, count($m->getRepeatedInt32())); + + $arr = array(1, 2.1, "3"); + $m->setRepeatedInt32($arr); + $this->assertTrue($m->getRepeatedInt32() instanceof RepeatedField); + $this->assertSame("Google\Protobuf\Internal\RepeatedField", + get_class($m->getRepeatedInt32())); + $this->assertSame(3, count($m->getRepeatedInt32())); + $this->assertSame(1, $m->getRepeatedInt32()[0]); + $this->assertSame(2, $m->getRepeatedInt32()[1]); + $this->assertSame(3, $m->getRepeatedInt32()[2]); + $this->assertFalse($arr instanceof RepeatedField); + } + /** * @expectedException PHPUnit_Framework_Error */ @@ -569,6 +591,80 @@ class GeneratedClassTest extends TestBase } ######################################################### + # Test map field. + ######################################################### + + public function testMapField() + { + $m = new TestMessage(); + + $map_int32_int32 = new MapField(GPBType::INT32, GPBType::INT32); + $m->setMapInt32Int32($map_int32_int32); + $this->assertSame($map_int32_int32, $m->getMapInt32Int32()); + } + + public function testMapFieldViaArray() + { + $m = new TestMessage(); + + $dict = array(); + $m->setMapInt32Int32($dict); + $this->assertSame(0, count($m->getMapInt32Int32())); + + $dict = array(5 => 5, 6.1 => 6.1, "7" => "7"); + $m->setMapInt32Int32($dict); + $this->assertTrue($m->getMapInt32Int32() instanceof MapField); + $this->assertSame(3, count($m->getMapInt32Int32())); + $this->assertSame(5, $m->getMapInt32Int32()[5]); + $this->assertSame(6, $m->getMapInt32Int32()[6]); + $this->assertSame(7, $m->getMapInt32Int32()[7]); + $this->assertFalse($dict instanceof MapField); + } + + /** + * @expectedException PHPUnit_Framework_Error + */ + public function testMapFieldWrongTypeFail() + { + $m = new TestMessage(); + $a = 1; + $m->setMapInt32Int32($a); + } + + /** + * @expectedException PHPUnit_Framework_Error + */ + public function testMapFieldWrongObjectFail() + { + $m = new TestMessage(); + $m->setMapInt32Int32($m); + } + + /** + * @expectedException PHPUnit_Framework_Error + */ + public function testMapFieldWrongRepeatedTypeFail() + { + $m = new TestMessage(); + + $map_uint32_uint32 = new MapField(GPBType::UINT32, GPBType::UINT32); + $m->setMapInt32Int32($map_uint32_uint32); + } + + /** + * @expectedException PHPUnit_Framework_Error + */ + public function testMapFieldWrongRepeatedMessageClassFail() + { + $m = new TestMessage(); + + $map_int32_message = new MapField(GPBType::INT32, + GPBType::MESSAGE, + TestMessage::class); + $m->setMapInt32Message($map_int32_message); + } + + ######################################################### # Test oneof field. ######################################################### @@ -743,4 +839,17 @@ class GeneratedClassTest extends TestBase { $m = new NoNameSpaceEnum(); } + + ######################################################### + # Test message with given prefix. + ######################################################### + + public function testPrefixMessage() + { + $m = new TestIncludePrefixMessage(); + $n = new PrefixTestPrefix(); + $n->setA(1); + $m->setPrefixMessage($n); + $this->assertSame(1, $m->getPrefixMessage()->getA()); + } } diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index cfcbe62e..5dd79519 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -2,8 +2,10 @@ # phpunit has memory leak by itself. Thus, it cannot be used to test memory leak. +require_once('generated/PrefixTestPrefix.php'); require_once('generated/Bar/TestInclude.php'); require_once('generated/Foo/TestEnum.php'); +require_once('generated/Foo/TestIncludePrefixMessage.php'); require_once('generated/Foo/TestMessage.php'); require_once('generated/Foo/TestMessage_Sub.php'); require_once('generated/Foo/TestPackedMessage.php'); @@ -11,6 +13,7 @@ require_once('generated/Foo/TestPhpDoc.php'); require_once('generated/Foo/TestUnpackedMessage.php'); require_once('generated/GPBMetadata/Proto/Test.php'); require_once('generated/GPBMetadata/Proto/TestInclude.php'); +require_once('generated/GPBMetadata/Proto/TestPrefix.php'); require_once('test_util.php'); use Google\Protobuf\Internal\RepeatedField; diff --git a/php/tests/php_implementation_test.php b/php/tests/php_implementation_test.php index ec6b8d5a..e1249808 100644 --- a/php/tests/php_implementation_test.php +++ b/php/tests/php_implementation_test.php @@ -469,6 +469,11 @@ class ImplementationTest extends TestBase $output = new OutputStream(3); $output->writeVarint32(16384); $this->assertSame(hex2bin('808001'), $output->getData()); + + // Negative numbers are padded to be compatible with int64. + $output = new OutputStream(10); + $output->writeVarint32(-43); + $this->assertSame(hex2bin('D5FFFFFFFFFFFFFFFF01'), $output->getData()); } public function testWriteVarint64() @@ -496,13 +501,13 @@ class ImplementationTest extends TestBase { $m = new TestMessage(); TestUtil::setTestMessage($m); - $this->assertSame(481, $m->byteSize()); + $this->assertSame(506, $m->byteSize()); } public function testPackedByteSize() { $m = new TestPackedMessage(); TestUtil::setTestPackedMessage($m); - $this->assertSame(156, $m->byteSize()); + $this->assertSame(166, $m->byteSize()); } } diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index e5dee0fb..1a47a3f2 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -1,6 +1,7 @@ syntax = "proto3"; import 'proto/test_include.proto'; +import 'proto/test_prefix.proto'; package foo; @@ -142,3 +143,7 @@ message TestUnpackedMessage { message TestPhpDoc { int32 a = 1; } + +message TestIncludePrefixMessage { + TestPrefix prefix_message = 1; +} diff --git a/php/tests/proto/test_prefix.proto b/php/tests/proto/test_prefix.proto new file mode 100644 index 00000000..04582121 --- /dev/null +++ b/php/tests/proto/test_prefix.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +option php_class_prefix = "Prefix"; + +message TestPrefix { + int32 a = 1; +} diff --git a/php/tests/test_util.php b/php/tests/test_util.php index 9c8e34d2..61f94aa1 100644 --- a/php/tests/test_util.php +++ b/php/tests/test_util.php @@ -321,7 +321,7 @@ class TestUtil public static function getGoldenTestMessage() { return hex2bin( - "08D6FFFFFF0F" . + "08D6FFFFFFFFFFFFFFFF01" . "10D5FFFFFFFFFFFFFFFF01" . "182A" . "202B" . @@ -339,8 +339,8 @@ class TestUtil "800101" . "8A01020821" . - "F801D6FFFFFF0F" . - "F801CCFFFFFF0F" . + "F801D6FFFFFFFFFFFFFFFF01" . + "F801CCFFFFFFFFFFFFFFFF01" . "8002D5FFFFFFFFFFFFFFFF01" . "8002CBFFFFFFFFFFFFFFFF01" . "88022A" . @@ -374,7 +374,7 @@ class TestUtil "FA02020822" . "FA02020823" . - "BA040C08C2FFFFFF0F10C2FFFFFF0F" . + "BA041608C2FFFFFFFFFFFFFFFF0110C2FFFFFFFFFFFFFFFF01" . "C2041608C1FFFFFFFFFFFFFFFF0110C1FFFFFFFFFFFFFFFF01" . "CA0404083E103E" . "D20404083F103F" . @@ -489,7 +489,7 @@ class TestUtil public static function getGoldenTestPackedMessage() { return hex2bin( - "D2050AD6FFFFFF0FCCFFFFFF0F" . + "D20514D6FFFFFFFFFFFFFFFF01CCFFFFFFFFFFFFFFFF01" . "DA0514D5FFFFFFFFFFFFFFFF01CBFFFFFFFFFFFFFFFF01" . "E205022A34" . "EA05022B35" . @@ -509,7 +509,7 @@ class TestUtil public static function getGoldenTestUnpackedMessage() { return hex2bin( - "D005D6FFFFFF0FD005CCFFFFFF0F" . + "D005D6FFFFFFFFFFFFFFFF01D005CCFFFFFFFFFFFFFFFF01" . "D805D5FFFFFFFFFFFFFFFF01D805CBFFFFFFFFFFFFFFFF01" . "E0052AE00534" . "E8052BE80535" . diff --git a/protobuf.bzl b/protobuf.bzl index 73c396d5..9cb17f01 100644 --- a/protobuf.bzl +++ b/protobuf.bzl @@ -108,6 +108,7 @@ def _proto_gen_impl(ctx): arguments=args + import_flags + [s.path for s in srcs], executable=ctx.executable.protoc, mnemonic="ProtoCompile", + use_default_shell_env=True, ) return struct( diff --git a/ruby/Rakefile b/ruby/Rakefile index 40d0a314..a329a777 100644 --- a/ruby/Rakefile +++ b/ruby/Rakefile @@ -64,13 +64,13 @@ else task 'gem:windows' do require 'rake_compiler_dock' - RakeCompilerDock.sh "bundle && IN_DOCKER=true rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0" + RakeCompilerDock.sh "bundle && IN_DOCKER=true rake cross native gem RUBY_CC_VERSION=2.4.0:2.3.0:2.2.2:2.1.5:2.0.0" end if RUBY_PLATFORM =~ /darwin/ task 'gem:native' do system "rake genproto" - system "rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0" + system "rake cross native gem RUBY_CC_VERSION=2.4.0:2.3.0:2.2.2:2.1.5:2.0.0" end else task 'gem:native' => [:genproto, 'gem:windows'] diff --git a/ruby/ext/google/protobuf_c/map.c b/ruby/ext/google/protobuf_c/map.c index 12f1f9dd..4be54c39 100644 --- a/ruby/ext/google/protobuf_c/map.c +++ b/ruby/ext/google/protobuf_c/map.c @@ -654,6 +654,35 @@ VALUE Map_hash(VALUE _self) { /* * call-seq: + * Map.to_h => {} + * + * Returns a Ruby Hash object containing all the values within the map + */ +VALUE Map_to_h(VALUE _self) { + Map* self = ruby_to_Map(_self); + VALUE hash = rb_hash_new(); + upb_strtable_iter it; + for (upb_strtable_begin(&it, &self->table); + !upb_strtable_done(&it); + upb_strtable_next(&it)) { + VALUE key = table_key_to_ruby( + self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it)); + upb_value v = upb_strtable_iter_value(&it); + void* mem = value_memory(&v); + VALUE value = native_slot_get(self->value_type, + self->value_type_class, + mem); + + if (self->value_type == UPB_TYPE_MESSAGE) { + value = Message_to_h(value); + } + rb_hash_aset(hash, key, value); + } + return hash; +} + +/* + * call-seq: * Map.inspect => string * * Returns a string representing this map's elements. It will be formatted as @@ -804,6 +833,8 @@ void Map_register(VALUE module) { rb_define_method(klass, "dup", Map_dup, 0); rb_define_method(klass, "==", Map_eq, 1); rb_define_method(klass, "hash", Map_hash, 0); + rb_define_method(klass, "to_hash", Map_to_h, 0); + rb_define_method(klass, "to_h", Map_to_h, 0); rb_define_method(klass, "inspect", Map_inspect, 0); rb_define_method(klass, "merge", Map_merge, 1); rb_include_module(klass, rb_mEnumerable); diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index 837a974b..29911140 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -394,7 +394,12 @@ VALUE Message_inspect(VALUE _self) { return str; } - +/* + * call-seq: + * Message.to_h => {} + * + * Returns the message as a Ruby Hash object, with keys as symbols. + */ VALUE Message_to_h(VALUE _self) { MessageHeader* self; VALUE hash; @@ -410,8 +415,13 @@ VALUE Message_to_h(VALUE _self) { VALUE msg_value = layout_get(self->descriptor->layout, Message_data(self), field); VALUE msg_key = ID2SYM(rb_intern(upb_fielddef_name(field))); - if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { + if (upb_fielddef_ismap(field)) { + msg_value = Map_to_h(msg_value); + } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { msg_value = RepeatedField_to_ary(msg_value); + } else if (msg_value != Qnil && + upb_fielddef_type(field) == UPB_TYPE_MESSAGE) { + msg_value = Message_to_h(msg_value); } rb_hash_aset(hash, msg_key, msg_value); } diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h index d5ced567..520e9d9b 100644 --- a/ruby/ext/google/protobuf_c/protobuf.h +++ b/ruby/ext/google/protobuf_c/protobuf.h @@ -424,6 +424,7 @@ VALUE Map_dup(VALUE _self); VALUE Map_deep_copy(VALUE _self); VALUE Map_eq(VALUE _self, VALUE _other); VALUE Map_hash(VALUE _self); +VALUE Map_to_h(VALUE _self); VALUE Map_inspect(VALUE _self); VALUE Map_merge(VALUE _self, VALUE hashmap); VALUE Map_merge_into_self(VALUE _self, VALUE hashmap); @@ -496,6 +497,7 @@ VALUE Message_deep_copy(VALUE _self); VALUE Message_eq(VALUE _self, VALUE _other); VALUE Message_hash(VALUE _self); VALUE Message_inspect(VALUE _self); +VALUE Message_to_h(VALUE _self); VALUE Message_index(VALUE _self, VALUE field_name); VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value); VALUE Message_descriptor(VALUE klass); diff --git a/ruby/ext/google/protobuf_c/wrap_memcpy.c b/ruby/ext/google/protobuf_c/wrap_memcpy.c index 158952a8..394a52f9 100644 --- a/ruby/ext/google/protobuf_c/wrap_memcpy.c +++ b/ruby/ext/google/protobuf_c/wrap_memcpy.c @@ -30,15 +30,15 @@ #include <string.h> -// On x86-64 Linux, we link against the 2.2.5 version of memcpy so that we -// avoid depending on the 2.14 version of the symbol. This way, distributions -// that are using pre-2.14 versions of glibc can successfully use the gem we -// distribute (https://github.com/google/protobuf/issues/2783). +// On x86-64 Linux with glibc, we link against the 2.2.5 version of memcpy so +// that we avoid depending on the 2.14 version of the symbol. This way, +// distributions that are using pre-2.14 versions of glibc can successfully use +// the gem we distribute (https://github.com/google/protobuf/issues/2783). // // This wrapper is enabled by passing the linker flags -Wl,-wrap,memcpy in // extconf.rb. #ifdef __linux__ -#ifdef __x86_64__ +#if defined(__x86_64__) && defined(__GNU_LIBRARY__) __asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); void *__wrap_memcpy(void *dest, const void *src, size_t n) { return memcpy(dest, src, n); diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index 97bf9970..1e30ae4d 100644 --- a/ruby/google-protobuf.gemspec +++ b/ruby/google-protobuf.gemspec @@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.name = "google-protobuf" - s.version = "3.2.0" - s.licenses = ["BSD"] + s.version = "3.2.0.1" + s.licenses = ["BSD-3-Clause"] s.summary = "Protocol Buffers" s.description = "Protocol Buffers are Google's data interchange format." s.homepage = "https://developers.google.com/protocol-buffers" @@ -15,12 +15,12 @@ Gem::Specification.new do |s| else s.files += Dir.glob('ext/**/*') s.extensions= ["ext/google/protobuf_c/extconf.rb"] - s.add_development_dependency "rake-compiler-dock", "~> 0.5.1" + s.add_development_dependency "rake-compiler-dock", "~> 0.6.0" end s.test_files = ["tests/basic.rb", "tests/stress.rb", "tests/generated_code_test.rb"] s.add_development_dependency "rake-compiler", "~> 0.9.5" - s.add_development_dependency "test-unit", "~> 3.0.9" + s.add_development_dependency "test-unit", '~> 3.0', '>= 3.0.9' s.add_development_dependency "rubygems-tasks", "~> 0.2.4" end diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index ca81e3a5..34251234 100644 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -927,6 +927,16 @@ module BasicTest :repeated_uint64=>[] } assert_equal expected_result, m.to_h + + m = MapMessage.new( + :map_string_int32 => {"a" => 1, "b" => 2}, + :map_string_msg => {"a" => TestMessage2.new(:foo => 1), + "b" => TestMessage2.new(:foo => 2)}) + expected_result = { + :map_string_int32 => {"a" => 1, "b" => 2}, + :map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}} + } + assert_equal expected_result, m.to_h end diff --git a/src/Makefile.am b/src/Makefile.am index 8c25a10a..bcd81576 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -169,6 +169,7 @@ nobase_include_HEADERS = \ google/protobuf/compiler/python/python_generator.h \ google/protobuf/compiler/ruby/ruby_generator.h \ google/protobuf/util/type_resolver.h \ + google/protobuf/util/delimited_message_util.h \ google/protobuf/util/field_comparator.h \ google/protobuf/util/field_mask_util.h \ google/protobuf/util/json_util.h \ @@ -180,6 +181,10 @@ lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) libprotobuf_lite_la_LDFLAGS = -version-info 12:0:0 -export-dynamic -no-undefined +if HAVE_LD_VERSION_SCRIPT +libprotobuf_lite_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotobuf-lite.map +EXTRA_libprotobuf_lite_la_DEPENDENCIES = libprotobuf-lite.map +endif libprotobuf_lite_la_SOURCES = \ google/protobuf/stubs/atomicops_internals_x86_gcc.cc \ google/protobuf/stubs/atomicops_internals_x86_msvc.cc \ @@ -221,6 +226,10 @@ libprotobuf_lite_la_SOURCES = \ libprotobuf_la_LIBADD = $(PTHREAD_LIBS) libprotobuf_la_LDFLAGS = -version-info 12:0:0 -export-dynamic -no-undefined +if HAVE_LD_VERSION_SCRIPT +libprotobuf_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotobuf.map +EXTRA_libprotobuf_la_DEPENDENCIES = libprotobuf.map +endif libprotobuf_la_SOURCES = \ $(libprotobuf_lite_la_SOURCES) \ google/protobuf/any.pb.cc \ @@ -259,6 +268,7 @@ libprotobuf_la_SOURCES = \ google/protobuf/io/zero_copy_stream_impl.cc \ google/protobuf/compiler/importer.cc \ google/protobuf/compiler/parser.cc \ + google/protobuf/util/delimited_message_util.cc \ google/protobuf/util/field_comparator.cc \ google/protobuf/util/field_mask_util.cc \ google/protobuf/util/internal/constants.h \ @@ -305,6 +315,10 @@ nodist_libprotobuf_la_SOURCES = $(nodist_libprotobuf_lite_la_SOURCES) libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc_la_LDFLAGS = -version-info 12:0:0 -export-dynamic -no-undefined +if HAVE_LD_VERSION_SCRIPT +libprotoc_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotoc.map +EXTRA_libprotoc_la_DEPENDENCIES = libprotoc.map +endif libprotoc_la_SOURCES = \ google/protobuf/compiler/code_generator.cc \ google/protobuf/compiler/command_line_interface.cc \ @@ -580,6 +594,9 @@ EXTRA_DIST = \ google/protobuf/compiler/ruby/ruby_generated_code_pb.rb \ google/protobuf/compiler/package_info.h \ google/protobuf/compiler/zip_output_unittest.sh \ + libprotobuf-lite.map \ + libprotobuf.map \ + libprotoc.map \ README.md protoc_lite_outputs = \ @@ -785,6 +802,7 @@ protobuf_test_SOURCES = \ google/protobuf/compiler/ruby/ruby_generator_unittest.cc \ google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc \ google/protobuf/compiler/csharp/csharp_generator_unittest.cc \ + google/protobuf/util/delimited_message_util_test.cc \ google/protobuf/util/field_comparator_test.cc \ google/protobuf/util/field_mask_util_test.cc \ google/protobuf/util/internal/default_value_objectwriter_test.cc \ diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 621d98c5..f516477b 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -1452,7 +1452,7 @@ CommandLineInterface::InterpretArgument(const string& name, void CommandLineInterface::PrintHelpText() { // Sorry for indentation here; line wrapping would be uglier. - std::cerr << + std::cout << "Usage: " << executable_name_ << " [OPTION] PROTO_FILES\n" "Parse PROTO_FILES and generate output based on the options given:\n" " -IPATH, --proto_path=PATH Specify the directory in which to search for\n" @@ -1499,7 +1499,7 @@ void CommandLineInterface::PrintHelpText() { " occupied fields numbers.\n" << std::endl; if (!plugin_prefix_.empty()) { - std::cerr << + std::cout << " --plugin=EXECUTABLE Specifies a plugin executable to use.\n" " Normally, protoc searches the PATH for\n" " plugins, but you may specify additional\n" @@ -1515,7 +1515,7 @@ void CommandLineInterface::PrintHelpText() { // FIXME(kenton): If the text is long enough it will wrap, which is ugly, // but fixing this nicely (e.g. splitting on spaces) is probably more // trouble than it's worth. - std::cerr << " " << iter->first << "=OUT_DIR " + std::cout << " " << iter->first << "=OUT_DIR " << string(19 - iter->first.size(), ' ') // Spaces for alignment. << iter->second.help_text << std::endl; } diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index cce1018a..eab14f60 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -156,6 +156,11 @@ class CommandLineInterfaceTest : public testing::Test { // Checks that the captured stdout is the same as the expected_text. void ExpectCapturedStdout(const string& expected_text); + // Checks that Run() returned zero and the stdout contains the given + // substring. + void ExpectCapturedStdoutSubstringWithZeroReturnCode( + const string& expected_substring); + // Returns true if ExpectErrorSubstring(expected_substring) would pass, but // does not fail otherwise. bool HasAlternateErrorSubstring(const string& expected_substring); @@ -488,6 +493,11 @@ void CommandLineInterfaceTest::ExpectCapturedStdout( EXPECT_EQ(expected_text, captured_stdout_); } +void CommandLineInterfaceTest::ExpectCapturedStdoutSubstringWithZeroReturnCode( + const string& expected_substring) { + EXPECT_EQ(0, return_code_); + EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, captured_stdout_); +} void CommandLineInterfaceTest::ExpectFileContent( const string& filename, const string& content) { @@ -1703,11 +1713,11 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) { TEST_F(CommandLineInterfaceTest, HelpText) { Run("test_exec_name --help"); - ExpectErrorSubstringWithZeroReturnCode("Usage: test_exec_name "); - ExpectErrorSubstringWithZeroReturnCode("--test_out=OUT_DIR"); - ExpectErrorSubstringWithZeroReturnCode("Test output."); - ExpectErrorSubstringWithZeroReturnCode("--alt_out=OUT_DIR"); - ExpectErrorSubstringWithZeroReturnCode("Alt output."); + ExpectCapturedStdoutSubstringWithZeroReturnCode("Usage: test_exec_name "); + ExpectCapturedStdoutSubstringWithZeroReturnCode("--test_out=OUT_DIR"); + ExpectCapturedStdoutSubstringWithZeroReturnCode("Test output."); + ExpectCapturedStdoutSubstringWithZeroReturnCode("--alt_out=OUT_DIR"); + ExpectCapturedStdoutSubstringWithZeroReturnCode("Alt output."); } TEST_F(CommandLineInterfaceTest, GccFormatErrors) { diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 0e5e2f18..f2e013c0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -54,6 +54,39 @@ namespace google { namespace protobuf { namespace compiler { namespace cpp { +namespace { +// The list of names that are defined as macros on some platforms. We need to +// #undef them for the generated code to compile. +const char* kMacroNames[] = {"major", "minor"}; + +bool IsMacroName(const string& name) { + // Just do a linear search as the number of elements is very small. + for (int i = 0; i < GOOGLE_ARRAYSIZE(kMacroNames); ++i) { + if (name == kMacroNames[i]) return true; + } + return false; +} + +void CollectMacroNames(const Descriptor* message, vector<string>* names) { + for (int i = 0; i < message->field_count(); ++i) { + const FieldDescriptor* field = message->field(i); + if (IsMacroName(field->name())) { + names->push_back(field->name()); + } + } + for (int i = 0; i < message->nested_type_count(); ++i) { + CollectMacroNames(message->nested_type(i), names); + } +} + +void CollectMacroNames(const FileDescriptor* file, vector<string>* names) { + for (int i = 0; i < file->message_type_count(); ++i) { + CollectMacroNames(file->message_type(i), names); + } +} + + +} // namespace // =================================================================== @@ -103,10 +136,23 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) FileGenerator::~FileGenerator() {} +void FileGenerator::GenerateMacroUndefs(io::Printer* printer) { + vector<string> names_to_undef; + CollectMacroNames(file_, &names_to_undef); + for (int i = 0; i < names_to_undef.size(); ++i) { + printer->Print( + "#ifdef $name$\n" + "#undef $name$\n" + "#endif\n", + "name", names_to_undef[i]); + } +} + void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print( "// @@protoc_insertion_point(includes)\n"); + GenerateMacroUndefs(printer); GenerateForwardDeclarations(printer); diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h index 25d6eabf..e3fbb96d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.h +++ b/src/google/protobuf/compiler/cpp/cpp_file.h @@ -133,6 +133,15 @@ class FileGenerator { void GenerateProto2NamespaceEnumSpecializations(io::Printer* printer); + // Sometimes the names we use in a .proto file happen to be defined as macros + // on some platforms (e.g., macro/minor used in plugin.proto are defined as + // macros in sys/types.h on FreeBSD and a few other platforms). To make the + // generated code compile on these platforms, we either have to undef the + // macro for these few platforms, or rename the field name for all platforms. + // Since these names are part of protobuf public API, renaming is generally + // a breaking change so we prefer the #undef approach. + void GenerateMacroUndefs(io::Printer* printer); + const FileDescriptor* file_; const Options options_; diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 6274ba29..1373ffc2 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -1462,9 +1462,9 @@ GenerateClassDefinition(io::Printer* printer) { // Some InitDefault and Shutdown are defined as static member functions of // TableStruct such that they are also allowed to access private members. printer->Print( - "friend struct $dllexport_decl$ $file_namespace$::TableStruct;\n", + "friend struct $file_namespace$::TableStruct;\n", // Vars. - "dllexport_decl", options_.dllexport_decl, "file_namespace", + "file_namespace", FileLevelNamespace(descriptor_->file()->name())); printer->Outdent(); diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 652c5d78..3b8d7ab8 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -1453,6 +1453,7 @@ void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) { "\n" "private volatile com.google.protobuf.Message cachedUnpackValue;\n" "\n" + "@java.lang.SuppressWarnings(\"unchecked\")\n" "public <T extends com.google.protobuf.Message> T unpack(\n" " java.lang.Class<T> clazz)\n" " throws com.google.protobuf.InvalidProtocolBufferException {\n" diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index 9720cacf..e84321bb 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -345,6 +345,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { } printer->Print( + "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n" "protected final Object dynamicMethod(\n" " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" " Object arg0, Object arg1) {\n" diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index ec9a2365..db72ea1a 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -90,7 +90,7 @@ std::string MessagePrefix(const Descriptor* message) { message->file()->package() == "google.protobuf") { return "GPB"; } else { - return ""; + return (message->file()->options()).php_class_prefix(); } } @@ -103,8 +103,12 @@ std::string MessageName(const Descriptor* message, bool is_descriptor) { } message_name = MessagePrefix(message) + message_name; - return PhpName(message->file()->package(), is_descriptor) + '\\' + - message_name; + if (message->file()->package() == "") { + return message_name; + } else { + return PhpName(message->file()->package(), is_descriptor) + '\\' + + message_name; + } } std::string MessageFullName(const Descriptor* message, bool is_descriptor) { @@ -439,9 +443,31 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, // Type check. if (field->is_map()) { + const Descriptor* map_entry = field->message_type(); + const FieldDescriptor* key = map_entry->FindFieldByName("key"); + const FieldDescriptor* value = map_entry->FindFieldByName("value"); + printer->Print( + "$arr = GPBUtil::checkMapField($var, " + "\\Google\\Protobuf\\Internal\\GPBType::^key_type^, " + "\\Google\\Protobuf\\Internal\\GPBType::^value_type^", + "key_type", ToUpper(key->type_name()), + "value_type", ToUpper(value->type_name())); + if (value->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print( + ", \\^class_name^);\n", + "class_name", + MessageName(value->message_type(), is_descriptor) + "::class"); + } else if (value->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + printer->Print( + ", ^class_name^);\n", + "class_name", + EnumName(value->enum_type(), is_descriptor) + "::class"); + } else { + printer->Print(");\n"); + } } else if (field->is_repeated()) { printer->Print( - "GPBUtil::checkRepeatedField($var, " + "$arr = GPBUtil::checkRepeatedField($var, " "\\Google\\Protobuf\\Internal\\GPBType::^type^", "type", ToUpper(field->type_name())); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { @@ -480,6 +506,10 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, printer->Print( "$this->writeOneof(^number^, $var);\n", "number", IntToString(field->number())); + } else if (field->is_repeated()) { + printer->Print( + "$this->^name^ = $arr;\n", + "name", field->name()); } else { printer->Print( "$this->^name^ = $var;\n", diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 4310ff1e..d044fbbe 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -164,11 +164,12 @@ void AddDescriptorsImpl() { "\t\022B\n\004file\030\017 \003(\01324.google.protobuf.compil" "er.CodeGeneratorResponse.File\032>\n\004File\022\014\n" "\004name\030\001 \001(\t\022\027\n\017insertion_point\030\002 \001(\t\022\017\n\007" - "content\030\017 \001(\tB7\n\034com.google.protobuf.com" - "pilerB\014PluginProtosZ\tplugin_go" + "content\030\017 \001(\tBg\n\034com.google.protobuf.com" + "pilerB\014PluginProtosZ9github.com/golang/p" + "rotobuf/protoc-gen-go/plugin;plugin_go" }; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - descriptor, 590); + descriptor, 638); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes); ::google::protobuf::protobuf_google_2fprotobuf_2fdescriptor_2eproto::AddDescriptors(); diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 1b91daca..ff8b949f 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -30,6 +30,12 @@ #include <google/protobuf/unknown_field_set.h> #include <google/protobuf/descriptor.pb.h> // @@protoc_insertion_point(includes) +#ifdef major +#undef major +#endif +#ifdef minor +#undef minor +#endif namespace google { namespace protobuf { class DescriptorProto; @@ -270,7 +276,7 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::int32 major_; ::google::protobuf::int32 minor_; ::google::protobuf::int32 patch_; - friend struct LIBPROTOC_EXPORT protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -421,7 +427,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_; ::google::protobuf::internal::ArenaStringPtr parameter_; ::google::protobuf::compiler::Version* compiler_version_; - friend struct LIBPROTOC_EXPORT protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -560,7 +566,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::internal::ArenaStringPtr insertion_point_; ::google::protobuf::internal::ArenaStringPtr content_; - friend struct LIBPROTOC_EXPORT protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -678,7 +684,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_; ::google::protobuf::internal::ArenaStringPtr error_; - friend struct LIBPROTOC_EXPORT protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; }; // =================================================================== diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto index 6e4da2c1..bf91d76e 100644 --- a/src/google/protobuf/compiler/plugin.proto +++ b/src/google/protobuf/compiler/plugin.proto @@ -49,7 +49,7 @@ package google.protobuf.compiler; option java_package = "com.google.protobuf.compiler"; option java_outer_classname = "PluginProtos"; -option go_package = "plugin_go"; +option go_package = "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go"; import "google/protobuf/descriptor.proto"; diff --git a/src/google/protobuf/compiler/zip_writer.cc b/src/google/protobuf/compiler/zip_writer.cc index 458cced2..07d52b18 100644 --- a/src/google/protobuf/compiler/zip_writer.cc +++ b/src/google/protobuf/compiler/zip_writer.cc @@ -28,36 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// 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: ambrose@google.com (Ambrose Feinstein), // kenton@google.com (Kenton Varda) // diff --git a/src/google/protobuf/compiler/zip_writer.h b/src/google/protobuf/compiler/zip_writer.h index 03db4d57..737f4d42 100644 --- a/src/google/protobuf/compiler/zip_writer.h +++ b/src/google/protobuf/compiler/zip_writer.h @@ -28,36 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// 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: kenton@google.com (Kenton Varda) #include <vector> diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 2a270d65..57fbfd86 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -252,22 +252,24 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, objc_class_prefix_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_namespace_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, swift_prefix_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, php_class_prefix_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_), 0, 1, - 6, 7, 8, - 14, - 2, 9, + 15, + 2, 10, 11, 12, 13, + 14, 3, 4, 5, + 6, ~0u, GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _internal_metadata_), @@ -421,20 +423,20 @@ static const ::google::protobuf::internal::MigrationSchema schemas[] = { { 116, 123, sizeof(EnumValueDescriptorProto)}, { 126, 133, sizeof(ServiceDescriptorProto)}, { 136, 146, sizeof(MethodDescriptorProto)}, - { 152, 172, sizeof(FileOptions)}, - { 188, 197, sizeof(MessageOptions)}, - { 202, 213, sizeof(FieldOptions)}, - { 220, 225, sizeof(OneofOptions)}, - { 226, 233, sizeof(EnumOptions)}, - { 236, 242, sizeof(EnumValueOptions)}, - { 244, 250, sizeof(ServiceOptions)}, - { 252, 259, sizeof(MethodOptions)}, - { 262, 268, sizeof(UninterpretedOption_NamePart)}, - { 270, 281, sizeof(UninterpretedOption)}, - { 288, 297, sizeof(SourceCodeInfo_Location)}, - { 302, 307, sizeof(SourceCodeInfo)}, - { 308, 316, sizeof(GeneratedCodeInfo_Annotation)}, - { 320, 325, sizeof(GeneratedCodeInfo)}, + { 152, 173, sizeof(FileOptions)}, + { 190, 199, sizeof(MessageOptions)}, + { 204, 215, sizeof(FieldOptions)}, + { 222, 227, sizeof(OneofOptions)}, + { 228, 235, sizeof(EnumOptions)}, + { 238, 244, sizeof(EnumValueOptions)}, + { 246, 252, sizeof(ServiceOptions)}, + { 254, 261, sizeof(MethodOptions)}, + { 264, 270, sizeof(UninterpretedOption_NamePart)}, + { 272, 283, sizeof(UninterpretedOption)}, + { 290, 299, sizeof(SourceCodeInfo_Location)}, + { 304, 309, sizeof(SourceCodeInfo)}, + { 310, 318, sizeof(GeneratedCodeInfo_Annotation)}, + { 322, 327, sizeof(GeneratedCodeInfo)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { @@ -662,7 +664,7 @@ void AddDescriptorsImpl() { "\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.g" "oogle.protobuf.MethodOptions\022\037\n\020client_s" "treaming\030\005 \001(\010:\005false\022\037\n\020server_streamin" - "g\030\006 \001(\010:\005false\"\232\005\n\013FileOptions\022\024\n\014java_p" + "g\030\006 \001(\010:\005false\"\264\005\n\013FileOptions\022\024\n\014java_p" "ackage\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001" "(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022)" "\n\035java_generate_equals_and_hash\030\024 \001(\010B\002\030" @@ -675,70 +677,71 @@ void AddDescriptorsImpl() { "se\022\031\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enab" "le_arenas\030\037 \001(\010:\005false\022\031\n\021objc_class_pre" "fix\030$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014s" - "wift_prefix\030\' \001(\t\022C\n\024uninterpreted_optio" + "wift_prefix\030\' \001(\t\022\030\n\020php_class_prefix\030( " + "\001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo" + "gle.protobuf.UninterpretedOption\":\n\014Opti" + "mizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LI" + "TE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\354\001\n\016Messag" + "eOptions\022&\n\027message_set_wire_format\030\001 \001(" + "\010:\005false\022.\n\037no_standard_descriptor_acces" + "sor\030\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005fa" + "lse\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024uninterpreted_" + "option\030\347\007 \003(\0132$.google.protobuf.Uninterp" + "retedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\t\"\236\003\n\014FieldOp" + "tions\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.F" + "ieldOptions.CType:\006STRING\022\016\n\006packed\030\002 \001(" + "\010\022\?\n\006jstype\030\006 \001(\0162$.google.protobuf.Fiel" + "dOptions.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010" + ":\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004we" + "ak\030\n \001(\010:\005false\022C\n\024uninterpreted_option\030" + "\347\007 \003(\0132$.google.protobuf.UninterpretedOp" + "tion\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014S" + "TRING_PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r" + "\n\tJS_STRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J" + "\004\010\004\020\005\"^\n\014OneofOptions\022C\n\024uninterpreted_o" + "ption\030\347\007 \003(\0132$.google.protobuf.Uninterpr" + "etedOption*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n" + "\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005" + "false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g" + "oogle.protobuf.UninterpretedOption*\t\010\350\007\020" + "\200\200\200\200\002\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030" + "\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 " + "\003(\0132$.google.protobuf.UninterpretedOptio" + "n*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprec" + "ated\030! \001(\010:\005false\022C\n\024uninterpreted_optio" "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted" - "Option\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCOD" - "E_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010" - "&\020\'\"\354\001\n\016MessageOptions\022&\n\027message_set_wi" - "re_format\030\001 \001(\010:\005false\022.\n\037no_standard_de" - "scriptor_accessor\030\002 \001(\010:\005false\022\031\n\ndeprec" - "ated\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024" - "uninterpreted_option\030\347\007 \003(\0132$.google.pro" - "tobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\010" - "\020\t\"\236\003\n\014FieldOptions\022:\n\005ctype\030\001 \001(\0162#.goo" - "gle.protobuf.FieldOptions.CType:\006STRING\022" - "\016\n\006packed\030\002 \001(\010\022\?\n\006jstype\030\006 \001(\0162$.google" - ".protobuf.FieldOptions.JSType:\tJS_NORMAL" - "\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(" - "\010:\005false\022\023\n\004weak\030\n \001(\010:\005false\022C\n\024uninter" - "preted_option\030\347\007 \003(\0132$.google.protobuf.U" - "ninterpretedOption\"/\n\005CType\022\n\n\006STRING\020\000\022" - "\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002\"5\n\006JSType\022\r\n" - "\tJS_NORMAL\020\000\022\r\n\tJS_STRING\020\001\022\r\n\tJS_NUMBER" - "\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005\"^\n\014OneofOptions\022C\n\024u" - "ninterpreted_option\030\347\007 \003(\0132$.google.prot" - "obuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013" - "EnumOptions\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndepr" - "ecated\030\003 \001(\010:\005false\022C\n\024uninterpreted_opt" - "ion\030\347\007 \003(\0132$.google.protobuf.Uninterpret" - "edOption*\t\010\350\007\020\200\200\200\200\002\"}\n\020EnumValueOptions\022" - "\031\n\ndeprecated\030\001 \001(\010:\005false\022C\n\024uninterpre" - "ted_option\030\347\007 \003(\0132$.google.protobuf.Unin" - "terpretedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOpt" - "ions\022\031\n\ndeprecated\030! \001(\010:\005false\022C\n\024unint" - "erpreted_option\030\347\007 \003(\0132$.google.protobuf" - ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMeth" - "odOptions\022\031\n\ndeprecated\030! \001(\010:\005false\022_\n\021" - "idempotency_level\030\" \001(\0162/.google.protobu" - "f.MethodOptions.IdempotencyLevel:\023IDEMPO" - "TENCY_UNKNOWN\022C\n\024uninterpreted_option\030\347\007" - " \003(\0132$.google.protobuf.UninterpretedOpti" - "on\"P\n\020IdempotencyLevel\022\027\n\023IDEMPOTENCY_UN" - "KNOWN\020\000\022\023\n\017NO_SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTE" - "NT\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOption\022" - ";\n\004name\030\002 \003(\0132-.google.protobuf.Uninterp" - "retedOption.NamePart\022\030\n\020identifier_value" - "\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022ne" - "gative_int_value\030\005 \001(\003\022\024\n\014double_value\030\006" - " \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017aggregate_" - "value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_part\030\001 \002" - "(\t\022\024\n\014is_extension\030\002 \002(\010\"\325\001\n\016SourceCodeI" - "nfo\022:\n\010location\030\001 \003(\0132(.google.protobuf." - "SourceCodeInfo.Location\032\206\001\n\010Location\022\020\n\004" - "path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020lead" - "ing_comments\030\003 \001(\t\022\031\n\021trailing_comments\030" - "\004 \001(\t\022!\n\031leading_detached_comments\030\006 \003(\t" - "\"\247\001\n\021GeneratedCodeInfo\022A\n\nannotation\030\001 \003" - "(\0132-.google.protobuf.GeneratedCodeInfo.A" - "nnotation\032O\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020" - "\001\022\023\n\013source_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n" - "\003end\030\004 \001(\005B\214\001\n\023com.google.protobufB\020Desc" - "riptorProtosH\001Z>github.com/golang/protob" - "uf/protoc-gen-go/descriptor;descriptor\242\002" - "\003GPB\252\002\032Google.Protobuf.Reflection" + "Option*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\nd" + "eprecated\030! \001(\010:\005false\022_\n\021idempotency_le" + "vel\030\" \001(\0162/.google.protobuf.MethodOption" + "s.IdempotencyLevel:\023IDEMPOTENCY_UNKNOWN\022" + "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google." + "protobuf.UninterpretedOption\"P\n\020Idempote" + "ncyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_" + "SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200" + "\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132" + "-.google.protobuf.UninterpretedOption.Na" + "mePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posi" + "tive_int_value\030\004 \001(\004\022\032\n\022negative_int_val" + "ue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string" + "_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n" + "\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exten" + "sion\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010locatio" + "n\030\001 \003(\0132(.google.protobuf.SourceCodeInfo" + ".Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001" + "\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003" + " \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!\n\031leadi" + "ng_detached_comments\030\006 \003(\t\"\247\001\n\021Generated" + "CodeInfo\022A\n\nannotation\030\001 \003(\0132-.google.pr" + "otobuf.GeneratedCodeInfo.Annotation\032O\n\nA" + "nnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_fi" + "le\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\214\001\n" + "\023com.google.protobufB\020DescriptorProtosH\001" + "Z>github.com/golang/protobuf/protoc-gen-" + "go/descriptor;descriptor\242\002\003GPB\252\002\032Google." + "Protobuf.Reflection" }; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - descriptor, 5553); + descriptor, 5579); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); @@ -8076,6 +8079,7 @@ const int FileOptions::kCcEnableArenasFieldNumber; const int FileOptions::kObjcClassPrefixFieldNumber; const int FileOptions::kCsharpNamespaceFieldNumber; const int FileOptions::kSwiftPrefixFieldNumber; +const int FileOptions::kPhpClassPrefixFieldNumber; const int FileOptions::kUninterpretedOptionFieldNumber; #endif // !defined(_MSC_VER) || _MSC_VER >= 1900 @@ -8119,6 +8123,10 @@ FileOptions::FileOptions(const FileOptions& from) if (from.has_swift_prefix()) { swift_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.swift_prefix_); } + php_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (from.has_php_class_prefix()) { + php_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_class_prefix_); + } ::memcpy(&java_multiple_files_, &from.java_multiple_files_, reinterpret_cast<char*>(&optimize_for_) - reinterpret_cast<char*>(&java_multiple_files_) + sizeof(optimize_for_)); @@ -8133,6 +8141,7 @@ void FileOptions::SharedCtor() { objc_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); csharp_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); swift_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + php_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); ::memset(&java_multiple_files_, 0, reinterpret_cast<char*>(&cc_enable_arenas_) - reinterpret_cast<char*>(&java_multiple_files_) + sizeof(cc_enable_arenas_)); optimize_for_ = 1; @@ -8150,6 +8159,7 @@ void FileOptions::SharedDtor() { objc_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); csharp_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); swift_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + php_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } void FileOptions::SetCachedSize(int size) const { @@ -8179,7 +8189,7 @@ void FileOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions) _extensions_.Clear(); uninterpreted_option_.Clear(); - if (_has_bits_[0 / 32] & 63u) { + if (_has_bits_[0 / 32] & 127u) { if (has_java_package()) { GOOGLE_DCHECK(!java_package_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*java_package_.UnsafeRawStringPointer())->clear(); @@ -8204,14 +8214,15 @@ void FileOptions::Clear() { GOOGLE_DCHECK(!swift_prefix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*swift_prefix_.UnsafeRawStringPointer())->clear(); } + if (has_php_class_prefix()) { + GOOGLE_DCHECK(!php_class_prefix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); + (*php_class_prefix_.UnsafeRawStringPointer())->clear(); + } } - if (_has_bits_[0 / 32] & 192u) { - ::memset(&java_multiple_files_, 0, reinterpret_cast<char*>(&java_generate_equals_and_hash_) - - reinterpret_cast<char*>(&java_multiple_files_) + sizeof(java_generate_equals_and_hash_)); - } - if (_has_bits_[8 / 32] & 32512u) { - ::memset(&java_string_check_utf8_, 0, reinterpret_cast<char*>(&cc_enable_arenas_) - - reinterpret_cast<char*>(&java_string_check_utf8_) + sizeof(cc_enable_arenas_)); + java_multiple_files_ = false; + if (_has_bits_[8 / 32] & 65280u) { + ::memset(&java_generate_equals_and_hash_, 0, reinterpret_cast<char*>(&cc_enable_arenas_) - + reinterpret_cast<char*>(&java_generate_equals_and_hash_) + sizeof(cc_enable_arenas_)); optimize_for_ = 1; } _has_bits_.Clear(); @@ -8455,6 +8466,22 @@ bool FileOptions::MergePartialFromCodedStream( break; } + // optional string php_class_prefix = 40; + case 40: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(322u)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_php_class_prefix())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->php_class_prefix().data(), this->php_class_prefix().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.FileOptions.php_class_prefix"); + } else { + goto handle_unusual; + } + break; + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == @@ -8605,6 +8632,16 @@ void FileOptions::SerializeWithCachedSizes( 39, this->swift_prefix(), output); } + // optional string php_class_prefix = 40; + if (has_php_class_prefix()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->php_class_prefix().data(), this->php_class_prefix().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.php_class_prefix"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 40, this->php_class_prefix(), output); + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( @@ -8738,6 +8775,17 @@ void FileOptions::SerializeWithCachedSizes( 39, this->swift_prefix(), target); } + // optional string php_class_prefix = 40; + if (has_php_class_prefix()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->php_class_prefix().data(), this->php_class_prefix().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.php_class_prefix"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 40, this->php_class_prefix(), target); + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: @@ -8822,18 +8870,25 @@ size_t FileOptions::ByteSizeLong() const { this->swift_prefix()); } + // optional string php_class_prefix = 40; + if (has_php_class_prefix()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->php_class_prefix()); + } + // optional bool java_multiple_files = 10 [default = false]; if (has_java_multiple_files()) { total_size += 1 + 1; } + } + if (_has_bits_[8 / 32] & 65280u) { // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; if (has_java_generate_equals_and_hash()) { total_size += 2 + 1; } - } - if (_has_bits_[8 / 32] & 32512u) { // optional bool java_string_check_utf8 = 27 [default = false]; if (has_java_string_check_utf8()) { total_size += 2 + 1; @@ -8924,14 +8979,18 @@ void FileOptions::MergeFrom(const FileOptions& from) { set_has_swift_prefix(); swift_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.swift_prefix_); } + if (from.has_php_class_prefix()) { + set_has_php_class_prefix(); + php_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_class_prefix_); + } if (from.has_java_multiple_files()) { set_java_multiple_files(from.java_multiple_files()); } + } + if (from._has_bits_[8 / 32] & 65280u) { if (from.has_java_generate_equals_and_hash()) { set_java_generate_equals_and_hash(from.java_generate_equals_and_hash()); } - } - if (from._has_bits_[8 / 32] & 32512u) { if (from.has_java_string_check_utf8()) { set_java_string_check_utf8(from.java_string_check_utf8()); } @@ -8991,6 +9050,7 @@ void FileOptions::InternalSwap(FileOptions* other) { objc_class_prefix_.Swap(&other->objc_class_prefix_); csharp_namespace_.Swap(&other->csharp_namespace_); swift_prefix_.Swap(&other->swift_prefix_); + php_class_prefix_.Swap(&other->php_class_prefix_); std::swap(java_multiple_files_, other->java_multiple_files_); std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_); std::swap(java_string_check_utf8_, other->java_string_check_utf8_); @@ -9140,13 +9200,13 @@ void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_c // optional bool java_multiple_files = 10 [default = false]; bool FileOptions::has_java_multiple_files() const { - return (_has_bits_[0] & 0x00000040u) != 0; + return (_has_bits_[0] & 0x00000080u) != 0; } void FileOptions::set_has_java_multiple_files() { - _has_bits_[0] |= 0x00000040u; + _has_bits_[0] |= 0x00000080u; } void FileOptions::clear_has_java_multiple_files() { - _has_bits_[0] &= ~0x00000040u; + _has_bits_[0] &= ~0x00000080u; } void FileOptions::clear_java_multiple_files() { java_multiple_files_ = false; @@ -9164,13 +9224,13 @@ void FileOptions::set_java_multiple_files(bool value) { // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; bool FileOptions::has_java_generate_equals_and_hash() const { - return (_has_bits_[0] & 0x00000080u) != 0; + return (_has_bits_[0] & 0x00000100u) != 0; } void FileOptions::set_has_java_generate_equals_and_hash() { - _has_bits_[0] |= 0x00000080u; + _has_bits_[0] |= 0x00000100u; } void FileOptions::clear_has_java_generate_equals_and_hash() { - _has_bits_[0] &= ~0x00000080u; + _has_bits_[0] &= ~0x00000100u; } void FileOptions::clear_java_generate_equals_and_hash() { java_generate_equals_and_hash_ = false; @@ -9188,13 +9248,13 @@ void FileOptions::set_java_generate_equals_and_hash(bool value) { // optional bool java_string_check_utf8 = 27 [default = false]; bool FileOptions::has_java_string_check_utf8() const { - return (_has_bits_[0] & 0x00000100u) != 0; + return (_has_bits_[0] & 0x00000200u) != 0; } void FileOptions::set_has_java_string_check_utf8() { - _has_bits_[0] |= 0x00000100u; + _has_bits_[0] |= 0x00000200u; } void FileOptions::clear_has_java_string_check_utf8() { - _has_bits_[0] &= ~0x00000100u; + _has_bits_[0] &= ~0x00000200u; } void FileOptions::clear_java_string_check_utf8() { java_string_check_utf8_ = false; @@ -9212,13 +9272,13 @@ void FileOptions::set_java_string_check_utf8(bool value) { // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; bool FileOptions::has_optimize_for() const { - return (_has_bits_[0] & 0x00004000u) != 0; + return (_has_bits_[0] & 0x00008000u) != 0; } void FileOptions::set_has_optimize_for() { - _has_bits_[0] |= 0x00004000u; + _has_bits_[0] |= 0x00008000u; } void FileOptions::clear_has_optimize_for() { - _has_bits_[0] &= ~0x00004000u; + _has_bits_[0] &= ~0x00008000u; } void FileOptions::clear_optimize_for() { optimize_for_ = 1; @@ -9299,13 +9359,13 @@ void FileOptions::set_allocated_go_package(::std::string* go_package) { // optional bool cc_generic_services = 16 [default = false]; bool FileOptions::has_cc_generic_services() const { - return (_has_bits_[0] & 0x00000200u) != 0; + return (_has_bits_[0] & 0x00000400u) != 0; } void FileOptions::set_has_cc_generic_services() { - _has_bits_[0] |= 0x00000200u; + _has_bits_[0] |= 0x00000400u; } void FileOptions::clear_has_cc_generic_services() { - _has_bits_[0] &= ~0x00000200u; + _has_bits_[0] &= ~0x00000400u; } void FileOptions::clear_cc_generic_services() { cc_generic_services_ = false; @@ -9323,13 +9383,13 @@ void FileOptions::set_cc_generic_services(bool value) { // optional bool java_generic_services = 17 [default = false]; bool FileOptions::has_java_generic_services() const { - return (_has_bits_[0] & 0x00000400u) != 0; + return (_has_bits_[0] & 0x00000800u) != 0; } void FileOptions::set_has_java_generic_services() { - _has_bits_[0] |= 0x00000400u; + _has_bits_[0] |= 0x00000800u; } void FileOptions::clear_has_java_generic_services() { - _has_bits_[0] &= ~0x00000400u; + _has_bits_[0] &= ~0x00000800u; } void FileOptions::clear_java_generic_services() { java_generic_services_ = false; @@ -9347,13 +9407,13 @@ void FileOptions::set_java_generic_services(bool value) { // optional bool py_generic_services = 18 [default = false]; bool FileOptions::has_py_generic_services() const { - return (_has_bits_[0] & 0x00000800u) != 0; + return (_has_bits_[0] & 0x00001000u) != 0; } void FileOptions::set_has_py_generic_services() { - _has_bits_[0] |= 0x00000800u; + _has_bits_[0] |= 0x00001000u; } void FileOptions::clear_has_py_generic_services() { - _has_bits_[0] &= ~0x00000800u; + _has_bits_[0] &= ~0x00001000u; } void FileOptions::clear_py_generic_services() { py_generic_services_ = false; @@ -9371,13 +9431,13 @@ void FileOptions::set_py_generic_services(bool value) { // optional bool deprecated = 23 [default = false]; bool FileOptions::has_deprecated() const { - return (_has_bits_[0] & 0x00001000u) != 0; + return (_has_bits_[0] & 0x00002000u) != 0; } void FileOptions::set_has_deprecated() { - _has_bits_[0] |= 0x00001000u; + _has_bits_[0] |= 0x00002000u; } void FileOptions::clear_has_deprecated() { - _has_bits_[0] &= ~0x00001000u; + _has_bits_[0] &= ~0x00002000u; } void FileOptions::clear_deprecated() { deprecated_ = false; @@ -9395,13 +9455,13 @@ void FileOptions::set_deprecated(bool value) { // optional bool cc_enable_arenas = 31 [default = false]; bool FileOptions::has_cc_enable_arenas() const { - return (_has_bits_[0] & 0x00002000u) != 0; + return (_has_bits_[0] & 0x00004000u) != 0; } void FileOptions::set_has_cc_enable_arenas() { - _has_bits_[0] |= 0x00002000u; + _has_bits_[0] |= 0x00004000u; } void FileOptions::clear_has_cc_enable_arenas() { - _has_bits_[0] &= ~0x00002000u; + _has_bits_[0] &= ~0x00004000u; } void FileOptions::clear_cc_enable_arenas() { cc_enable_arenas_ = false; @@ -9603,6 +9663,68 @@ void FileOptions::set_allocated_swift_prefix(::std::string* swift_prefix) { // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.swift_prefix) } +// optional string php_class_prefix = 40; +bool FileOptions::has_php_class_prefix() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +void FileOptions::set_has_php_class_prefix() { + _has_bits_[0] |= 0x00000040u; +} +void FileOptions::clear_has_php_class_prefix() { + _has_bits_[0] &= ~0x00000040u; +} +void FileOptions::clear_php_class_prefix() { + php_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_php_class_prefix(); +} +const ::std::string& FileOptions::php_class_prefix() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_class_prefix) + return php_class_prefix_.GetNoArena(); +} +void FileOptions::set_php_class_prefix(const ::std::string& value) { + set_has_php_class_prefix(); + php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_class_prefix) +} +#if LANG_CXX11 +void FileOptions::set_php_class_prefix(::std::string&& value) { + set_has_php_class_prefix(); + php_class_prefix_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_class_prefix) +} +#endif +void FileOptions::set_php_class_prefix(const char* value) { + set_has_php_class_prefix(); + php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_class_prefix) +} +void FileOptions::set_php_class_prefix(const char* value, size_t size) { + set_has_php_class_prefix(); + php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_class_prefix) +} +::std::string* FileOptions::mutable_php_class_prefix() { + set_has_php_class_prefix(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_class_prefix) + return php_class_prefix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +::std::string* FileOptions::release_php_class_prefix() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_class_prefix) + clear_has_php_class_prefix(); + return php_class_prefix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +void FileOptions::set_allocated_php_class_prefix(::std::string* php_class_prefix) { + if (php_class_prefix != NULL) { + set_has_php_class_prefix(); + } else { + clear_has_php_class_prefix(); + } + php_class_prefix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), php_class_prefix); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_class_prefix) +} + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; int FileOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 73b7a8dd..10708963 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -355,7 +355,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message ::google::protobuf::internal::HasBits<1> _has_bits_; mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -619,7 +619,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag ::google::protobuf::internal::ArenaStringPtr syntax_; ::google::protobuf::FileOptions* options_; ::google::protobuf::SourceCodeInfo* source_code_info_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -724,7 +724,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto mutable int _cached_size_; ::google::protobuf::int32 start_; ::google::protobuf::int32 end_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -829,7 +829,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protob mutable int _cached_size_; ::google::protobuf::int32 start_; ::google::protobuf::int32 end_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -1061,7 +1061,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* ::google::protobuf::RepeatedPtrField< ::std::string> reserved_name_; ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::MessageOptions* options_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -1374,7 +1374,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa ::google::protobuf::int32 oneof_index_; int label_; int type_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -1489,7 +1489,7 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa mutable int _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::OneofOptions* options_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -1617,7 +1617,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_; ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::EnumOptions* options_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -1742,7 +1742,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::EnumValueOptions* options_; ::google::protobuf::int32 number_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -1870,7 +1870,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_; ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::ServiceOptions* options_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -2041,7 +2041,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess ::google::protobuf::MethodOptions* options_; bool client_streaming_; bool server_streaming_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -2250,6 +2250,21 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@p ::std::string* release_swift_prefix(); void set_allocated_swift_prefix(::std::string* swift_prefix); + // optional string php_class_prefix = 40; + bool has_php_class_prefix() const; + void clear_php_class_prefix(); + static const int kPhpClassPrefixFieldNumber = 40; + const ::std::string& php_class_prefix() const; + void set_php_class_prefix(const ::std::string& value); + #if LANG_CXX11 + void set_php_class_prefix(::std::string&& value); + #endif + void set_php_class_prefix(const char* value); + void set_php_class_prefix(const char* value, size_t size); + ::std::string* mutable_php_class_prefix(); + ::std::string* release_php_class_prefix(); + void set_allocated_php_class_prefix(::std::string* php_class_prefix); + // optional bool java_multiple_files = 10 [default = false]; bool has_java_multiple_files() const; void clear_java_multiple_files(); @@ -2346,6 +2361,8 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@p void clear_has_csharp_namespace(); void set_has_swift_prefix(); void clear_has_swift_prefix(); + void set_has_php_class_prefix(); + void clear_has_php_class_prefix(); ::google::protobuf::internal::ExtensionSet _extensions_; @@ -2359,6 +2376,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@p ::google::protobuf::internal::ArenaStringPtr objc_class_prefix_; ::google::protobuf::internal::ArenaStringPtr csharp_namespace_; ::google::protobuf::internal::ArenaStringPtr swift_prefix_; + ::google::protobuf::internal::ArenaStringPtr php_class_prefix_; bool java_multiple_files_; bool java_generate_equals_and_hash_; bool java_string_check_utf8_; @@ -2368,7 +2386,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@p bool deprecated_; bool cc_enable_arenas_; int optimize_for_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -2509,7 +2527,7 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message /* bool no_standard_descriptor_accessor_; bool deprecated_; bool map_entry_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -2726,7 +2744,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@ bool lazy_; bool deprecated_; bool weak_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -2827,7 +2845,7 @@ class LIBPROTOBUF_EXPORT OneofOptions : public ::google::protobuf::Message /* @@ ::google::protobuf::internal::HasBits<1> _has_bits_; mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -2948,7 +2966,7 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message /* @@p ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; bool allow_alias_; bool deprecated_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -3059,7 +3077,7 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message / mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; bool deprecated_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -3170,7 +3188,7 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message /* mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; bool deprecated_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -3319,7 +3337,7 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message /* @ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; bool deprecated_; int idempotency_level_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -3435,7 +3453,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu mutable int _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_part_; bool is_extension_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -3619,7 +3637,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag ::google::protobuf::uint64 positive_int_value_; ::google::protobuf::int64 negative_int_value_; double double_value_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -3791,7 +3809,7 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me ::google::protobuf::RepeatedPtrField< ::std::string> leading_detached_comments_; ::google::protobuf::internal::ArenaStringPtr leading_comments_; ::google::protobuf::internal::ArenaStringPtr trailing_comments_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -3891,7 +3909,7 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message /* ::google::protobuf::internal::HasBits<1> _has_bits_; mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -4028,7 +4046,7 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobu ::google::protobuf::internal::ArenaStringPtr source_file_; ::google::protobuf::int32 begin_; ::google::protobuf::int32 end_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -4128,7 +4146,7 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message ::google::protobuf::internal::HasBits<1> _has_bits_; mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation > annotation_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // =================================================================== @@ -6585,13 +6603,13 @@ inline void FileOptions::set_allocated_java_outer_classname(::std::string* java_ // optional bool java_multiple_files = 10 [default = false]; inline bool FileOptions::has_java_multiple_files() const { - return (_has_bits_[0] & 0x00000040u) != 0; + return (_has_bits_[0] & 0x00000080u) != 0; } inline void FileOptions::set_has_java_multiple_files() { - _has_bits_[0] |= 0x00000040u; + _has_bits_[0] |= 0x00000080u; } inline void FileOptions::clear_has_java_multiple_files() { - _has_bits_[0] &= ~0x00000040u; + _has_bits_[0] &= ~0x00000080u; } inline void FileOptions::clear_java_multiple_files() { java_multiple_files_ = false; @@ -6609,13 +6627,13 @@ inline void FileOptions::set_java_multiple_files(bool value) { // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; inline bool FileOptions::has_java_generate_equals_and_hash() const { - return (_has_bits_[0] & 0x00000080u) != 0; + return (_has_bits_[0] & 0x00000100u) != 0; } inline void FileOptions::set_has_java_generate_equals_and_hash() { - _has_bits_[0] |= 0x00000080u; + _has_bits_[0] |= 0x00000100u; } inline void FileOptions::clear_has_java_generate_equals_and_hash() { - _has_bits_[0] &= ~0x00000080u; + _has_bits_[0] &= ~0x00000100u; } inline void FileOptions::clear_java_generate_equals_and_hash() { java_generate_equals_and_hash_ = false; @@ -6633,13 +6651,13 @@ inline void FileOptions::set_java_generate_equals_and_hash(bool value) { // optional bool java_string_check_utf8 = 27 [default = false]; inline bool FileOptions::has_java_string_check_utf8() const { - return (_has_bits_[0] & 0x00000100u) != 0; + return (_has_bits_[0] & 0x00000200u) != 0; } inline void FileOptions::set_has_java_string_check_utf8() { - _has_bits_[0] |= 0x00000100u; + _has_bits_[0] |= 0x00000200u; } inline void FileOptions::clear_has_java_string_check_utf8() { - _has_bits_[0] &= ~0x00000100u; + _has_bits_[0] &= ~0x00000200u; } inline void FileOptions::clear_java_string_check_utf8() { java_string_check_utf8_ = false; @@ -6657,13 +6675,13 @@ inline void FileOptions::set_java_string_check_utf8(bool value) { // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; inline bool FileOptions::has_optimize_for() const { - return (_has_bits_[0] & 0x00004000u) != 0; + return (_has_bits_[0] & 0x00008000u) != 0; } inline void FileOptions::set_has_optimize_for() { - _has_bits_[0] |= 0x00004000u; + _has_bits_[0] |= 0x00008000u; } inline void FileOptions::clear_has_optimize_for() { - _has_bits_[0] &= ~0x00004000u; + _has_bits_[0] &= ~0x00008000u; } inline void FileOptions::clear_optimize_for() { optimize_for_ = 1; @@ -6744,13 +6762,13 @@ inline void FileOptions::set_allocated_go_package(::std::string* go_package) { // optional bool cc_generic_services = 16 [default = false]; inline bool FileOptions::has_cc_generic_services() const { - return (_has_bits_[0] & 0x00000200u) != 0; + return (_has_bits_[0] & 0x00000400u) != 0; } inline void FileOptions::set_has_cc_generic_services() { - _has_bits_[0] |= 0x00000200u; + _has_bits_[0] |= 0x00000400u; } inline void FileOptions::clear_has_cc_generic_services() { - _has_bits_[0] &= ~0x00000200u; + _has_bits_[0] &= ~0x00000400u; } inline void FileOptions::clear_cc_generic_services() { cc_generic_services_ = false; @@ -6768,13 +6786,13 @@ inline void FileOptions::set_cc_generic_services(bool value) { // optional bool java_generic_services = 17 [default = false]; inline bool FileOptions::has_java_generic_services() const { - return (_has_bits_[0] & 0x00000400u) != 0; + return (_has_bits_[0] & 0x00000800u) != 0; } inline void FileOptions::set_has_java_generic_services() { - _has_bits_[0] |= 0x00000400u; + _has_bits_[0] |= 0x00000800u; } inline void FileOptions::clear_has_java_generic_services() { - _has_bits_[0] &= ~0x00000400u; + _has_bits_[0] &= ~0x00000800u; } inline void FileOptions::clear_java_generic_services() { java_generic_services_ = false; @@ -6792,13 +6810,13 @@ inline void FileOptions::set_java_generic_services(bool value) { // optional bool py_generic_services = 18 [default = false]; inline bool FileOptions::has_py_generic_services() const { - return (_has_bits_[0] & 0x00000800u) != 0; + return (_has_bits_[0] & 0x00001000u) != 0; } inline void FileOptions::set_has_py_generic_services() { - _has_bits_[0] |= 0x00000800u; + _has_bits_[0] |= 0x00001000u; } inline void FileOptions::clear_has_py_generic_services() { - _has_bits_[0] &= ~0x00000800u; + _has_bits_[0] &= ~0x00001000u; } inline void FileOptions::clear_py_generic_services() { py_generic_services_ = false; @@ -6816,13 +6834,13 @@ inline void FileOptions::set_py_generic_services(bool value) { // optional bool deprecated = 23 [default = false]; inline bool FileOptions::has_deprecated() const { - return (_has_bits_[0] & 0x00001000u) != 0; + return (_has_bits_[0] & 0x00002000u) != 0; } inline void FileOptions::set_has_deprecated() { - _has_bits_[0] |= 0x00001000u; + _has_bits_[0] |= 0x00002000u; } inline void FileOptions::clear_has_deprecated() { - _has_bits_[0] &= ~0x00001000u; + _has_bits_[0] &= ~0x00002000u; } inline void FileOptions::clear_deprecated() { deprecated_ = false; @@ -6840,13 +6858,13 @@ inline void FileOptions::set_deprecated(bool value) { // optional bool cc_enable_arenas = 31 [default = false]; inline bool FileOptions::has_cc_enable_arenas() const { - return (_has_bits_[0] & 0x00002000u) != 0; + return (_has_bits_[0] & 0x00004000u) != 0; } inline void FileOptions::set_has_cc_enable_arenas() { - _has_bits_[0] |= 0x00002000u; + _has_bits_[0] |= 0x00004000u; } inline void FileOptions::clear_has_cc_enable_arenas() { - _has_bits_[0] &= ~0x00002000u; + _has_bits_[0] &= ~0x00004000u; } inline void FileOptions::clear_cc_enable_arenas() { cc_enable_arenas_ = false; @@ -7048,6 +7066,68 @@ inline void FileOptions::set_allocated_swift_prefix(::std::string* swift_prefix) // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.swift_prefix) } +// optional string php_class_prefix = 40; +inline bool FileOptions::has_php_class_prefix() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FileOptions::set_has_php_class_prefix() { + _has_bits_[0] |= 0x00000040u; +} +inline void FileOptions::clear_has_php_class_prefix() { + _has_bits_[0] &= ~0x00000040u; +} +inline void FileOptions::clear_php_class_prefix() { + php_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_php_class_prefix(); +} +inline const ::std::string& FileOptions::php_class_prefix() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_class_prefix) + return php_class_prefix_.GetNoArena(); +} +inline void FileOptions::set_php_class_prefix(const ::std::string& value) { + set_has_php_class_prefix(); + php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_class_prefix) +} +#if LANG_CXX11 +inline void FileOptions::set_php_class_prefix(::std::string&& value) { + set_has_php_class_prefix(); + php_class_prefix_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_class_prefix) +} +#endif +inline void FileOptions::set_php_class_prefix(const char* value) { + set_has_php_class_prefix(); + php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_class_prefix) +} +inline void FileOptions::set_php_class_prefix(const char* value, size_t size) { + set_has_php_class_prefix(); + php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_class_prefix) +} +inline ::std::string* FileOptions::mutable_php_class_prefix() { + set_has_php_class_prefix(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_class_prefix) + return php_class_prefix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileOptions::release_php_class_prefix() { + // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_class_prefix) + clear_has_php_class_prefix(); + return php_class_prefix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_allocated_php_class_prefix(::std::string* php_class_prefix) { + if (php_class_prefix != NULL) { + set_has_php_class_prefix(); + } else { + clear_has_php_class_prefix(); + } + php_class_prefix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), php_class_prefix); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_class_prefix) +} + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; inline int FileOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index e5f83e62..be223683 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -376,6 +376,10 @@ message FileOptions { // to prefix the types/symbols defined. optional string swift_prefix = 39; + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 61a23897..88878b58 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -678,7 +678,7 @@ class Map { const Key& key() const { return k_; } Key& key() { return k_; } - value_type* const value() const { return v_; } + value_type* value() const { return v_; } value_type*& value() { return v_; } private: @@ -1290,7 +1290,9 @@ class Map { // Return a power of two no less than max(kMinTableSize, n). // Assumes either n < kMinTableSize or n is a power of two. size_type TableSize(size_type n) { - return n < kMinTableSize ? kMinTableSize : n; + return n < static_cast<size_type>(kMinTableSize) + ? static_cast<size_type>(kMinTableSize) + : n; } // Use alloc_ to allocate an array of n objects of type U. diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h index 07604e17..86510d14 100644 --- a/src/google/protobuf/stubs/bytestream.h +++ b/src/google/protobuf/stubs/bytestream.h @@ -64,7 +64,7 @@ namespace protobuf { namespace strings { // An abstract interface for an object that consumes a sequence of bytes. This -// interface offers 3 different ways to append data, and a Flush() function. +// interface offers a way to append data as well as a Flush() function. // // Example: // diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h index 6f0633c4..6ec5e001 100644 --- a/src/google/protobuf/stubs/port.h +++ b/src/google/protobuf/stubs/port.h @@ -44,6 +44,8 @@ #include <stdint.h> #endif +#include <google/protobuf/stubs/platform_macros.h> + #undef PROTOBUF_LITTLE_ENDIAN #ifdef _WIN32 // Assuming windows is always little-endian. @@ -359,7 +361,12 @@ class Bits { } static uint32 Log2FloorNonZero64(uint64 n) { -#if defined(__GNUC__) + // arm-nacl-clang runs into an instruction-selection failure when it + // encounters __builtin_clzll: + // https://bugs.chromium.org/p/nativeclient/issues/detail?id=4395 + // To work around this, when we build for NaCl we use the portable + // implementation instead. +#if defined(__GNUC__) && !defined(GOOGLE_PROTOBUF_OS_NACL) return 63 ^ __builtin_clzll(n); #else return Log2FloorNonZero64_Portable(n); diff --git a/src/google/protobuf/stubs/shared_ptr.h b/src/google/protobuf/stubs/shared_ptr.h index d250bf4d..7da114e9 100644 --- a/src/google/protobuf/stubs/shared_ptr.h +++ b/src/google/protobuf/stubs/shared_ptr.h @@ -428,11 +428,11 @@ class enable_shared_from_this { shared_ptr<T> shared_from_this() { // Behavior is undefined if the precondition isn't satisfied; we choose // to die with a CHECK failure. - CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; + GOOGLE_CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; return weak_this_.lock(); } shared_ptr<const T> shared_from_this() const { - CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; + GOOGLE_CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; return weak_this_.lock(); } @@ -456,7 +456,8 @@ class enable_shared_from_this { template<typename T> void shared_ptr<T>::MaybeSetupWeakThis(enable_shared_from_this<T>* ptr) { if (ptr) { - CHECK(ptr->weak_this_.expired()) << "Object already owned by a shared_ptr"; + GOOGLE_CHECK(ptr->weak_this_.expired()) + << "Object already owned by a shared_ptr"; ptr->weak_this_ = *this; } } diff --git a/src/google/protobuf/stubs/stringpiece_unittest.cc b/src/google/protobuf/stubs/stringpiece_unittest.cc index a52d81f8..a6a87595 100644 --- a/src/google/protobuf/stubs/stringpiece_unittest.cc +++ b/src/google/protobuf/stubs/stringpiece_unittest.cc @@ -783,11 +783,13 @@ TEST(FindOneCharTest, EdgeCases) { EXPECT_EQ(StringPiece::npos, a.rfind('x')); } +#ifdef PROTOBUF_HAS_DEATH_TEST #ifndef NDEBUG TEST(NonNegativeLenTest, NonNegativeLen) { EXPECT_DEATH(StringPiece("xyz", -1), "len >= 0"); } #endif // ndef DEBUG +#endif // PROTOBUF_HAS_DEATH_TEST } // namespace } // namespace protobuf diff --git a/src/google/protobuf/util/delimited_message_util.cc b/src/google/protobuf/util/delimited_message_util.cc new file mode 100644 index 00000000..16378782 --- /dev/null +++ b/src/google/protobuf/util/delimited_message_util.cc @@ -0,0 +1,79 @@ +// Adapted from the patch of kenton@google.com (Kenton Varda) +// See https://github.com/google/protobuf/pull/710 for details. + +#include <google/protobuf/util/delimited_message_util.h> + +namespace google { +namespace protobuf { +namespace util { + +bool SerializeDelimitedToFileDescriptor(const MessageLite& message, int file_descriptor) { + io::FileOutputStream output(file_descriptor); + return SerializeDelimitedToZeroCopyStream(message, &output); +} + +bool SerializeDelimitedToOstream(const MessageLite& message, ostream* output) { + { + io::OstreamOutputStream zero_copy_output(output); + if (!SerializeDelimitedToZeroCopyStream(message, &zero_copy_output)) return false; + } + return output->good(); +} + +bool ParseDelimitedFromZeroCopyStream(MessageLite* message, io::ZeroCopyInputStream* input, bool* clean_eof) { + google::protobuf::io::CodedInputStream coded_input(input); + return ParseDelimitedFromCodedStream(message, &coded_input, clean_eof); +} + +bool ParseDelimitedFromCodedStream(MessageLite* message, io::CodedInputStream* input, bool* clean_eof) { + if (clean_eof != NULL) *clean_eof = false; + int start = input->CurrentPosition(); + + // Read the size. + uint32 size; + if (!input->ReadVarint32(&size)) { + if (clean_eof != NULL) *clean_eof = input->CurrentPosition() == start; + return false; + } + + // Tell the stream not to read beyond that size. + google::protobuf::io::CodedInputStream::Limit limit = input->PushLimit(size); + + // Parse the message. + if (!message->MergeFromCodedStream(input)) return false; + if (!input->ConsumedEntireMessage()) return false; + + // Release the limit. + input->PopLimit(limit); + + return true; +} + +bool SerializeDelimitedToZeroCopyStream(const MessageLite& message, io::ZeroCopyOutputStream* output) { + google::protobuf::io::CodedOutputStream coded_output(output); + return SerializeDelimitedToCodedStream(message, &coded_output); +} + +bool SerializeDelimitedToCodedStream(const MessageLite& message, io::CodedOutputStream* output) { + // Write the size. + int size = message.ByteSize(); + output->WriteVarint32(size); + + // Write the content. + uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size); + if (buffer != NULL) { + // Optimization: The message fits in one buffer, so use the faster + // direct-to-array serialization path. + message.SerializeWithCachedSizesToArray(buffer); + } else { + // Slightly-slower path when the message is multiple buffers. + message.SerializeWithCachedSizes(output); + if (output->HadError()) return false; + } + + return true; +} + +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/util/delimited_message_util.h b/src/google/protobuf/util/delimited_message_util.h new file mode 100644 index 00000000..302d4781 --- /dev/null +++ b/src/google/protobuf/util/delimited_message_util.h @@ -0,0 +1,66 @@ +// Adapted from the patch of kenton@google.com (Kenton Varda) +// See https://github.com/google/protobuf/pull/710 for details. + +#ifndef GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__ +#define GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__ + +#include <ostream> + +#include <google/protobuf/message_lite.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> + +namespace google { +namespace protobuf { +namespace util { + +// Write a single size-delimited message from the given stream. Delimited +// format allows a single file or stream to contain multiple messages, +// whereas normally writing multiple non-delimited messages to the same +// stream would cause them to be merged. A delimited message is a varint +// encoding the message size followed by a message of exactly that size. +// +// Note that if you want to *read* a delimited message from a file descriptor +// or istream, you will need to construct an io::FileInputStream or +// io::OstreamInputStream (implementations of io::ZeroCopyStream) and use the +// utility function ParseDelimitedFromZeroCopyStream(). You must then +// continue to use the same ZeroCopyInputStream to read all further data from +// the stream until EOF. This is because these ZeroCopyInputStream +// implementations are buffered: they read a big chunk of data at a time, +// then parse it. As a result, they may read past the end of the delimited +// message. There is no way for them to push the extra data back into the +// underlying source, so instead you must keep using the same stream object. +bool LIBPROTOBUF_EXPORT SerializeDelimitedToFileDescriptor(const MessageLite& message, int file_descriptor); + +bool LIBPROTOBUF_EXPORT SerializeDelimitedToOstream(const MessageLite& message, ostream* output); + +// Read a single size-delimited message from the given stream. Delimited +// format allows a single file or stream to contain multiple messages, +// whereas normally parsing consumes the entire input. A delimited message +// is a varint encoding the message size followed by a message of exactly +// that size. +// +// If |clean_eof| is not NULL, then it will be set to indicate whether the +// stream ended cleanly. That is, if the stream ends without this method +// having read any data at all from it, then *clean_eof will be set true, +// otherwise it will be set false. Note that these methods return false +// on EOF, but they also return false on other errors, so |clean_eof| is +// needed to distinguish a clean end from errors. +bool LIBPROTOBUF_EXPORT ParseDelimitedFromZeroCopyStream(MessageLite* message, io::ZeroCopyInputStream* input, bool* clean_eof); + +bool LIBPROTOBUF_EXPORT ParseDelimitedFromCodedStream(MessageLite* message, io::CodedInputStream* input, bool* clean_eof); + +// Write a single size-delimited message from the given stream. Delimited +// format allows a single file or stream to contain multiple messages, +// whereas normally writing multiple non-delimited messages to the same +// stream would cause them to be merged. A delimited message is a varint +// encoding the message size followed by a message of exactly that size. +bool LIBPROTOBUF_EXPORT SerializeDelimitedToZeroCopyStream(const MessageLite& message, io::ZeroCopyOutputStream* output); + +bool LIBPROTOBUF_EXPORT SerializeDelimitedToCodedStream(const MessageLite& message, io::CodedOutputStream* output); + +} // namespace util +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__ diff --git a/src/google/protobuf/util/delimited_message_util_test.cc b/src/google/protobuf/util/delimited_message_util_test.cc new file mode 100644 index 00000000..b261d43c --- /dev/null +++ b/src/google/protobuf/util/delimited_message_util_test.cc @@ -0,0 +1,57 @@ +// Adapted from the patch of kenton@google.com (Kenton Varda) +// See https://github.com/google/protobuf/pull/710 for details. + +#include <google/protobuf/util/delimited_message_util.h> + +#include <sstream> + +#include <google/protobuf/test_util.h> +#include <google/protobuf/unittest.pb.h> +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> + +namespace google { +namespace protobuf { +namespace util { + +TEST(DelimitedMessageUtilTest, DelimitedMessages) { + stringstream stream; + + { + protobuf_unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + EXPECT_TRUE(SerializeDelimitedToOstream(message1, &stream)); + + protobuf_unittest::TestPackedTypes message2; + TestUtil::SetPackedFields(&message2); + EXPECT_TRUE(SerializeDelimitedToOstream(message2, &stream)); + } + + { + bool clean_eof; + io::IstreamInputStream zstream(&stream); + + protobuf_unittest::TestAllTypes message1; + clean_eof = true; + EXPECT_TRUE(ParseDelimitedFromZeroCopyStream(&message1, + &zstream, &clean_eof)); + EXPECT_FALSE(clean_eof); + TestUtil::ExpectAllFieldsSet(message1); + + protobuf_unittest::TestPackedTypes message2; + clean_eof = true; + EXPECT_TRUE(ParseDelimitedFromZeroCopyStream(&message2, + &zstream, &clean_eof)); + EXPECT_FALSE(clean_eof); + TestUtil::ExpectPackedFieldsSet(message2); + + clean_eof = false; + EXPECT_FALSE(ParseDelimitedFromZeroCopyStream(&message2, + &zstream, &clean_eof)); + EXPECT_TRUE(clean_eof); + } +} + +} // namespace util +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index 250cf0be..b33ad206 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -65,6 +65,7 @@ DefaultValueObjectWriter::DefaultValueObjectWriter( current_(NULL), root_(NULL), suppress_empty_list_(false), + preserve_proto_field_names_(false), field_scrub_callback_(NULL), ow_(ow) {} @@ -191,7 +192,8 @@ void DefaultValueObjectWriter::RegisterFieldScrubCallBack( DefaultValueObjectWriter::Node::Node( const string& name, const google::protobuf::Type* type, NodeKind kind, const DataPiece& data, bool is_placeholder, const std::vector<string>& path, - bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback) + bool suppress_empty_list, bool preserve_proto_field_names, + FieldScrubCallBack* field_scrub_callback) : name_(name), type_(type), kind_(kind), @@ -200,6 +202,7 @@ DefaultValueObjectWriter::Node::Node( is_placeholder_(is_placeholder), path_(path), suppress_empty_list_(suppress_empty_list), + preserve_proto_field_names_(preserve_proto_field_names), field_scrub_callback_(field_scrub_callback) {} DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild( @@ -370,10 +373,12 @@ void DefaultValueObjectWriter::Node::PopulateChildren( // If the child field is of primitive type, sets its data to the default // value of its type. google::protobuf::scoped_ptr<Node> child(new Node( - field.json_name(), field_type, kind, + preserve_proto_field_names_ ? field.name() : field.json_name(), + field_type, kind, kind == PRIMITIVE ? CreateDefaultDataPieceForField(field, typeinfo) : DataPiece::NullData(), - true, path, suppress_empty_list_, field_scrub_callback_)); + true, path, suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_)); new_children.push_back(child.release()); } // Adds all leftover nodes in children_ to the beginning of new_child. @@ -470,6 +475,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( std::vector<string> path; root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(), false, path, suppress_empty_list_, + preserve_proto_field_names_, field_scrub_callback_.get())); root_->PopulateChildren(typeinfo_); current_ = root_.get(); @@ -486,7 +492,8 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( : NULL), OBJECT, DataPiece::NullData(), false, child == NULL ? current_->path() : child->path(), - suppress_empty_list_, field_scrub_callback_.get())); + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); child = node.get(); current_->AddChild(node.release()); } @@ -518,6 +525,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( std::vector<string> path; root_.reset(new Node(name.ToString(), &type_, LIST, DataPiece::NullData(), false, path, suppress_empty_list_, + preserve_proto_field_names_, field_scrub_callback_.get())); current_ = root_.get(); return this; @@ -528,7 +536,8 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( google::protobuf::scoped_ptr<Node> node( new Node(name.ToString(), NULL, LIST, DataPiece::NullData(), false, child == NULL ? current_->path() : child->path(), - suppress_empty_list_, field_scrub_callback_.get())); + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); child = node.get(); current_->AddChild(node.release()); } @@ -589,7 +598,8 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, google::protobuf::scoped_ptr<Node> node( new Node(name.ToString(), NULL, PRIMITIVE, data, false, child == NULL ? current_->path() : child->path(), - suppress_empty_list_, field_scrub_callback_.get())); + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); current_->AddChild(node.release()); } else { child->set_data(data); diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h index dc4551c9..ddf23594 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.h +++ b/src/google/protobuf/util/internal/default_value_objectwriter.h @@ -126,6 +126,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // are written. void set_suppress_empty_list(bool value) { suppress_empty_list_ = value; } + // If set to true, original proto field names are used + void set_preserve_proto_field_names(bool value) { preserve_proto_field_names_ = value; } + private: enum NodeKind { PRIMITIVE = 0, @@ -141,7 +144,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { Node(const string& name, const google::protobuf::Type* type, NodeKind kind, const DataPiece& data, bool is_placeholder, const std::vector<string>& path, bool suppress_empty_list, - FieldScrubCallBack* field_scrub_callback); + bool preserve_proto_field_names, FieldScrubCallBack* field_scrub_callback); virtual ~Node() { for (int i = 0; i < children_.size(); ++i) { delete children_[i]; @@ -220,6 +223,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // Whether to suppress empty list output. bool suppress_empty_list_; + // Whether to preserve original proto field names + bool preserve_proto_field_names_; + // Pointer to function for determining whether a field needs to be scrubbed // or not. This callback is owned by the creator of this node. FieldScrubCallBack* field_scrub_callback_; @@ -268,6 +274,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // Whether to suppress output of empty lists. bool suppress_empty_list_; + // Whether to preserve original proto field names + bool preserve_proto_field_names_; + // Unique Pointer to function for determining whether a field needs to be // scrubbed or not. FieldScrubCallBackPtr field_scrub_callback_; diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index f9fd7b01..61491af0 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -121,6 +121,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( type_(type), use_lower_camel_for_enums_(false), use_ints_for_enums_(false), + preserve_proto_field_names_(false), recursion_depth_(0), max_recursion_depth_(kDefaultMaxRecursionDepth), render_unknown_fields_(false), @@ -137,6 +138,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( type_(type), use_lower_camel_for_enums_(false), use_ints_for_enums_(false), + preserve_proto_field_names_(false), recursion_depth_(0), max_recursion_depth_(kDefaultMaxRecursionDepth), render_unknown_fields_(false), @@ -200,7 +202,11 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, last_tag = tag; field = FindAndVerifyField(type, tag); if (field != NULL) { - field_name = field->json_name(); + if (preserve_proto_field_names_) { + field_name = field->name(); + } else { + field_name = field->json_name(); + } } } if (field == NULL) { diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h index 63d5f455..5f443d9d 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.h +++ b/src/google/protobuf/util/internal/protostream_objectsource.h @@ -116,6 +116,11 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { use_ints_for_enums_ = value; } + // Sets whether to use original proto field names + void set_preserve_proto_field_names(bool value) { + preserve_proto_field_names_ = value; + } + // Sets the max recursion depth of proto message to be deserialized. Proto // messages over this depth will fail to be deserialized. // Default value is 64. @@ -294,6 +299,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { // Whether to render enums as ints always. Defaults to false. bool use_ints_for_enums_; + // Whether to preserve proto field names + bool preserve_proto_field_names_; + // Tracks current recursion depth. mutable int recursion_depth_; diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index a9b15e68..97ef8fff 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -74,6 +74,8 @@ using google::protobuf::testing::Primitive; using google::protobuf::testing::Proto3Message; using google::protobuf::testing::Publisher; using google::protobuf::testing::StructType; +using google::protobuf::testing::TestJsonName1; +using google::protobuf::testing::TestJsonName2; using google::protobuf::testing::TimestampDuration; using google::protobuf::testing::ValueWrapper; using google::protobuf::testing::oneofs::OneOfsRequest; @@ -271,6 +273,26 @@ TEST_P(ProtoStreamObjectWriterTest, CustomJsonName) { CheckOutput(book); } +// Test that two messages can have different fields mapped to the same JSON +// name. See: https://github.com/google/protobuf/issues/1415 +TEST_P(ProtoStreamObjectWriterTest, ConflictingJsonName) { + ResetTypeInfo(TestJsonName1::descriptor()); + TestJsonName1 message1; + message1.set_one_value(12345); + ow_->StartObject("") + ->RenderInt32("value", 12345) + ->EndObject(); + CheckOutput(message1); + + ResetTypeInfo(TestJsonName2::descriptor()); + TestJsonName2 message2; + message2.set_another_value(12345); + ow_->StartObject("") + ->RenderInt32("value", 12345) + ->EndObject(); + CheckOutput(message2); +} + TEST_P(ProtoStreamObjectWriterTest, IntEnumValuesAreAccepted) { Book book; book.set_title("Some Book"); diff --git a/src/google/protobuf/util/internal/testdata/books.proto b/src/google/protobuf/util/internal/testdata/books.proto index 9fe4f7aa..869271f4 100644 --- a/src/google/protobuf/util/internal/testdata/books.proto +++ b/src/google/protobuf/util/internal/testdata/books.proto @@ -190,3 +190,12 @@ message Cyclic { repeated Author m_author = 5; optional Cyclic m_cyclic = 4; } + +// Test that two messages can have different fields mapped to the same JSON +// name. See: https://github.com/google/protobuf/issues/1415 +message TestJsonName1 { + optional int32 one_value = 1 [json_name = "value"]; +} +message TestJsonName2 { + optional int32 another_value = 1 [json_name = "value"]; +} diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc index 17d58475..a5d903f1 100644 --- a/src/google/protobuf/util/internal/type_info.cc +++ b/src/google/protobuf/util/internal/type_info.cc @@ -107,12 +107,12 @@ class TypeInfoForTypeResolver : public TypeInfo { virtual const google::protobuf::Field* FindField( const google::protobuf::Type* type, StringPiece camel_case_name) const { - if (indexed_types_.find(type) == indexed_types_.end()) { - PopulateNameLookupTable(type); - indexed_types_.insert(type); - } + std::map<const google::protobuf::Type*, + CamelCaseNameTable>::const_iterator it = indexed_types_.find(type); + const CamelCaseNameTable& camel_case_name_table = (it == indexed_types_.end()) + ? PopulateNameLookupTable(type, &indexed_types_[type]) : it->second; StringPiece name = - FindWithDefault(camel_case_name_table_, camel_case_name, StringPiece()); + FindWithDefault(camel_case_name_table, camel_case_name, StringPiece()); if (name.empty()) { // Didn't find a mapping. Use whatever provided. name = camel_case_name; @@ -123,6 +123,7 @@ class TypeInfoForTypeResolver : public TypeInfo { private: typedef util::StatusOr<const google::protobuf::Type*> StatusOrType; typedef util::StatusOr<const google::protobuf::Enum*> StatusOrEnum; + typedef std::map<StringPiece, StringPiece> CamelCaseNameTable; template <typename T> static void DeleteCachedTypes(std::map<StringPiece, T>* cached_types) { @@ -134,32 +135,35 @@ class TypeInfoForTypeResolver : public TypeInfo { } } - void PopulateNameLookupTable(const google::protobuf::Type* type) const { + const CamelCaseNameTable& PopulateNameLookupTable( + const google::protobuf::Type* type, + CamelCaseNameTable* camel_case_name_table) const { for (int i = 0; i < type->fields_size(); ++i) { const google::protobuf::Field& field = type->fields(i); StringPiece name = field.name(); StringPiece camel_case_name = field.json_name(); const StringPiece* existing = InsertOrReturnExisting( - &camel_case_name_table_, camel_case_name, name); + camel_case_name_table, camel_case_name, name); if (existing && *existing != name) { GOOGLE_LOG(WARNING) << "Field '" << name << "' and '" << *existing << "' map to the same camel case name '" << camel_case_name << "'."; } } + return *camel_case_name_table; } TypeResolver* type_resolver_; // Stores string values that will be referenced by StringPieces in - // cached_types_, cached_enums_ and camel_case_name_table_. + // cached_types_, cached_enums_. mutable std::set<string> string_storage_; mutable std::map<StringPiece, StatusOrType> cached_types_; mutable std::map<StringPiece, StatusOrEnum> cached_enums_; - mutable std::set<const google::protobuf::Type*> indexed_types_; - mutable std::map<StringPiece, StringPiece> camel_case_name_table_; + mutable std::map<const google::protobuf::Type*, + CamelCaseNameTable> indexed_types_; }; } // namespace diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc index 129b6eaf..8595a881 100644 --- a/src/google/protobuf/util/json_util.cc +++ b/src/google/protobuf/util/json_util.cc @@ -83,12 +83,16 @@ util::Status BinaryToJsonStream(TypeResolver* resolver, RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type)); converter::ProtoStreamObjectSource proto_source(&in_stream, resolver, type); proto_source.set_use_ints_for_enums(options.always_print_enums_as_ints); + proto_source.set_preserve_proto_field_names( + options.preserve_proto_field_names); io::CodedOutputStream out_stream(json_output); converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "", &out_stream); if (options.always_print_primitive_fields) { converter::DefaultValueObjectWriter default_value_writer( resolver, type, &json_writer); + default_value_writer.set_preserve_proto_field_names( + options.preserve_proto_field_names); return proto_source.WriteTo(&default_value_writer); } else { return proto_source.WriteTo(&json_writer); diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h index 53b1d1ba..dd9a736f 100644 --- a/src/google/protobuf/util/json_util.h +++ b/src/google/protobuf/util/json_util.h @@ -64,10 +64,13 @@ struct JsonPrintOptions { // Whether to always print enums as ints. By default they are rendered as // strings. bool always_print_enums_as_ints; + // Whether to preserve proto field names + bool preserve_proto_field_names; JsonPrintOptions() : add_whitespace(false), always_print_primitive_fields(false), - always_print_enums_as_ints(false) { + always_print_enums_as_ints(false), + preserve_proto_field_names(false) { } }; diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc index 53c8a0f8..7c03d674 100644 --- a/src/google/protobuf/util/json_util_test.cc +++ b/src/google/protobuf/util/json_util_test.cc @@ -159,6 +159,43 @@ TEST_F(JsonUtilTest, TestDefaultValues) { "\"repeatedMessageValue\":[]" "}", ToJson(m, options)); + + options.preserve_proto_field_names = true; + m.set_string_value("i am a test string value"); + m.set_bytes_value("i am a test bytes value"); + EXPECT_EQ( + "{\"bool_value\":false," + "\"int32_value\":0," + "\"int64_value\":\"0\"," + "\"uint32_value\":0," + "\"uint64_value\":\"0\"," + "\"float_value\":0," + "\"double_value\":0," + "\"string_value\":\"i am a test string value\"," + "\"bytes_value\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\"," + "\"enum_value\":\"FOO\"," + "\"repeated_bool_value\":[]," + "\"repeated_int32_value\":[]," + "\"repeated_int64_value\":[]," + "\"repeated_uint32_value\":[]," + "\"repeated_uint64_value\":[]," + "\"repeated_float_value\":[]," + "\"repeated_double_value\":[]," + "\"repeated_string_value\":[]," + "\"repeated_bytes_value\":[]," + "\"repeated_enum_value\":[]," + "\"repeated_message_value\":[]" + "}", + ToJson(m, options)); +} + +TEST_F(JsonUtilTest, TestPreserveProtoFieldNames) { + TestMessage m; + m.mutable_message_value(); + + JsonPrintOptions options; + options.preserve_proto_field_names = true; + EXPECT_EQ("{\"message_value\":{}}", ToJson(m, options)); } TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) { diff --git a/src/libprotobuf-lite.map b/src/libprotobuf-lite.map new file mode 100644 index 00000000..39155466 --- /dev/null +++ b/src/libprotobuf-lite.map @@ -0,0 +1,9 @@ +{ + global: + extern "C++" { + *google*; + }; + + local: + *; +}; diff --git a/src/libprotobuf.map b/src/libprotobuf.map new file mode 100644 index 00000000..39155466 --- /dev/null +++ b/src/libprotobuf.map @@ -0,0 +1,9 @@ +{ + global: + extern "C++" { + *google*; + }; + + local: + *; +}; diff --git a/src/libprotoc.map b/src/libprotoc.map new file mode 100644 index 00000000..39155466 --- /dev/null +++ b/src/libprotoc.map @@ -0,0 +1,9 @@ +{ + global: + extern "C++" { + *google*; + }; + + local: + *; +}; @@ -350,6 +350,7 @@ build_ruby_all() { build_javascript() { internal_build_cpp cd js && npm install && npm test && cd .. + cd conformance && make test_nodejs && cd .. } generate_php_test_proto() { @@ -358,7 +359,7 @@ generate_php_test_proto() { # Generate test file rm -rf generated mkdir generated - ../../src/protoc --php_out=generated proto/test.proto proto/test_include.proto proto/test_no_namespace.proto + ../../src/protoc --php_out=generated proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto pushd ../../src ./protoc --php_out=../php/tests/generated google/protobuf/empty.proto popd |