diff options
72 files changed, 1421 insertions, 319 deletions
@@ -181,6 +181,17 @@ cc_library( deps = [":protobuf_lite"], ) +# This provides just the header files for use in projects that need to build +# shared libraries for dynamic loading. This target is available until Bazel +# adds native support for such use cases. +# TODO(keveman): Remove this target once the support gets added to Bazel. +cc_library( + name = "protobuf_headers", + hdrs = glob(["src/**/*.h"]), + includes = ["src/"], + visibility = ["//visibility:public"], +) + objc_library( name = "protobuf_objc", hdrs = ["objectivec/GPBProtocolBuffers.h"], @@ -565,12 +576,12 @@ java_library( srcs = glob([ "java/util/src/main/java/com/google/protobuf/util/*.java", ]), + visibility = ["//visibility:public"], deps = [ "protobuf_java", "//external:gson", "//external:guava", ], - visibility = ["//visibility:public"], ) ################################################################################ @@ -591,8 +602,8 @@ py_library( "python/google/protobuf/internal/test_util.py", ], ), - srcs_version = "PY2AND3", imports = ["python"], + srcs_version = "PY2AND3", ) cc_binary( @@ -657,8 +668,8 @@ config_setting( internal_copied_filegroup( name = "protos_python", srcs = WELL_KNOWN_PROTOS, - strip_prefix = "src", dest = "python", + strip_prefix = "src", ) # TODO(dzc): Remove this once py_proto_library can have labels in srcs, in @@ -680,7 +691,7 @@ py_proto_library( protoc = ":protoc", py_libs = [ ":python_srcs", - "//external:six" + "//external:six", ], srcs_version = "PY2AND3", visibility = ["//visibility:public"], @@ -694,13 +705,14 @@ py_proto_library( internal_copied_filegroup( name = "protos_python_test", srcs = LITE_TEST_PROTOS + TEST_PROTOS, - strip_prefix = "src", dest = "python", + strip_prefix = "src", ) # TODO(dzc): Remove this once py_proto_library can have labels in srcs, in # which case we can simply add :protos_python_test in srcs. COPIED_LITE_TEST_PROTOS = ["python/" + s for s in RELATIVE_LITE_TEST_PROTOS] + COPIED_TEST_PROTOS = ["python/" + s for s in RELATIVE_TEST_PROTOS] py_proto_library( @@ -770,10 +782,10 @@ internal_protobuf_py_tests( ) proto_lang_toolchain( - name = "cc_toolchain", - command_line = "--cpp_out=$(OUT)", - runtime = ":protobuf", - visibility = ["//visibility:public"], + name = "cc_toolchain", + command_line = "--cpp_out=$(OUT)", + runtime = ":protobuf", + visibility = ["//visibility:public"], ) proto_lang_toolchain( diff --git a/Makefile.am b/Makefile.am index c8f7f696..3222417f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -795,6 +795,7 @@ ruby_EXTRA_DIST= \ ruby/ext/google/protobuf_c/storage.c \ ruby/ext/google/protobuf_c/upb.c \ ruby/ext/google/protobuf_c/upb.h \ + ruby/ext/google/protobuf_c/wrap_memcpy.c \ ruby/google-protobuf.gemspec \ ruby/lib/google/protobuf/message_exts.rb \ ruby/lib/google/protobuf/repeated_field.rb \ 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/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 bf8e5a6c..978fd0c5 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) @@ -122,6 +123,7 @@ set(tests_files ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/metadata_test.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/importer_unittest.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment_unittest.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/conformance_php.php b/conformance/conformance_php.php index 69001971..20fb5082 100755 --- a/conformance/conformance_php.php +++ b/conformance/conformance_php.php @@ -46,7 +46,7 @@ function doTest($request) $response = new \Conformance\ConformanceResponse(); if ($request->getPayload() == "protobuf_payload") { try { - $test_message->decode($request->getProtobufPayload()); + $test_message->mergeFromString($request->getProtobufPayload()); } catch (Exception $e) { $response->setParseError($e->getMessage()); return $response; @@ -65,7 +65,7 @@ function doTest($request) if ($request->getRequestedOutputFormat() == WireFormat::UNSPECIFIED) { trigger_error("Unspecified output format.", E_USER_ERROR); } elseif ($request->getRequestedOutputFormat() == WireFormat::PROTOBUF) { - $response->setProtobufPayload($test_message->encode()); + $response->setProtobufPayload($test_message->serializeToString()); } elseif ($request->getRequestedOutputFormat() == WireFormat::JSON) { $response->setJsonPayload($test_message->jsonEncode()); } @@ -89,11 +89,11 @@ function doTestIO() } $request = new \Conformance\ConformanceRequest(); - $request->decode($serialized_request); + $request->mergeFromString($serialized_request); $response = doTest($request); - $serialized_response = $response->encode(); + $serialized_response = $response->serializeToString(); fwrite(STDOUT, pack("V", strlen($serialized_response))); fwrite(STDOUT, $serialized_response); diff --git a/conformance/update_failure_list.py b/conformance/update_failure_list.py index 69f210e3..63f453df 100755 --- a/conformance/update_failure_list.py +++ b/conformance/update_failure_list.py @@ -57,7 +57,7 @@ for remove_file in (args.remove_list or []): with open(remove_file) as f: for line in f: if line in add_set: - raise "Asked to both add and remove test: " + line + raise Exception("Asked to both add and remove test: " + line) remove_set.add(line.strip()) add_list = sorted(add_set, reverse=True) diff --git a/docs/third_party.md b/docs/third_party.md index 98ac66fc..a1f918a7 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -23,7 +23,7 @@ These are projects we know about implementing Protocol Buffers for other program * C#: https://silentorbit.com/protobuf/ * C#/.NET/WCF/VB: http://code.google.com/p/protobuf-net/ * Clojure: http://github.com/ninjudd/clojure-protobuf -* Common Lisp: http://www.prism.gatech.edu/~ndantam3/docs/s-protobuf/ +* Common Lisp: http://github.com/ndantam/s-protobuf * Common Lisp: http://github.com/brown/protobuf * D: https://github.com/msoucy/dproto * D: http://256.makerslocal.org/wiki/index.php/ProtocolBuffer diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java index 7639efcf..37180da8 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java @@ -328,8 +328,11 @@ public abstract class AbstractMessage extends AbstractMessageLite.Builder implements Message.Builder { // The compiler produces an error if this is not declared explicitly. + // Method isn't abstract to bypass Java 1.6 compiler issue http://bugs.java.com/view_bug.do?bug_id=6908259 @Override - public abstract BuilderType clone(); + public BuilderType clone() { + throw new UnsupportedOperationException("clone() should be implemented in subclasses."); + } /** TODO(jieluo): Clear it when all subclasses have implemented this method. */ @Override 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..838700f7 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 { 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/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile index c5ee1ec0..b7583fc7 100644 --- a/jenkins/docker/Dockerfile +++ b/jenkins/docker/Dockerfile @@ -78,9 +78,6 @@ RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ # -- For C++ benchmarks -- cmake \ # -- For PHP -- - php5.5 \ - php5.5-dev \ - php5.5-xml \ php5.6 \ php5.6-dev \ php5.6-xml \ @@ -143,19 +140,28 @@ RUN cd /tmp && \ ################## # PHP dependencies. +RUN wget http://am1.php.net/get/php-5.5.38.tar.bz2/from/this/mirror +RUN mv mirror php-5.5.38.tar.bz2 +RUN tar -xvf php-5.5.38.tar.bz2 +RUN cd php-5.5.38 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.5-zts && \ + make && make install && cd .. +RUN cd php-5.5.38 && make clean && ./configure --prefix=/usr/local/php-5.5 && \ + make && make install && cd .. RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" RUN php composer-setup.php RUN mv composer.phar /usr/bin/composer RUN php -r "unlink('composer-setup.php');" +RUN composer config -g -- disable-tls true +RUN composer config -g -- secure-http false RUN cd /tmp && \ rm -rf protobuf && \ git clone https://github.com/google/protobuf.git && \ cd protobuf && \ git reset 46ae90dc5e145b12fffa7e053a908a9f3e066286 && \ cd php && \ - 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 && \ + ln -sfn /usr/local/php-5.5/bin/php /usr/bin/php && \ + ln -sfn /usr/local/php-5.5/bin/php-config /usr/bin/php-config && \ + ln -sfn /usr/local/php-5.5/bin/phpize /usr/bin/phpize && \ composer install && \ mv vendor /usr/local/vendor-5.5 && \ ln -sfn /usr/bin/php5.6 /usr/bin/php && \ @@ -168,11 +174,6 @@ RUN cd /tmp && \ ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize && \ composer install && \ mv vendor /usr/local/vendor-7.0 -RUN wget http://am1.php.net/get/php-5.5.38.tar.bz2/from/this/mirror -RUN mv mirror php-5.5.38.tar.bz2 -RUN tar -xvf php-5.5.38.tar.bz2 -RUN cd php-5.5.38 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.5-zts && \ - make && make install ################## # Go dependencies. 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/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index 63bb6d0a..ab2eaf90 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); +} + 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/encode_decode.c b/php/ext/google/protobuf/encode_decode.c index 78b12a06..e5a5f307 100644 --- a/php/ext/google/protobuf/encode_decode.c +++ b/php/ext/google/protobuf/encode_decode.c @@ -1234,7 +1234,7 @@ static const upb_handlers* msgdef_json_serialize_handlers( // PHP encode/decode methods // ----------------------------------------------------------------------------- -PHP_METHOD(Message, encode) { +PHP_METHOD(Message, serializeToString) { zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis())); Descriptor* desc = (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC); @@ -1260,7 +1260,7 @@ PHP_METHOD(Message, encode) { } } -PHP_METHOD(Message, decode) { +PHP_METHOD(Message, mergeFromString) { zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis())); Descriptor* desc = (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC); diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index ab98879d..4a3829d6 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); +} + +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/message.c b/php/ext/google/protobuf/message.c index b35df311..59ce6ae6 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -39,8 +39,8 @@ zend_object_handlers* message_handlers; static zend_function_entry message_methods[] = { PHP_ME(Message, clear, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, encode, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, decode, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Message, serializeToString, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Message, mergeFromString, NULL, ZEND_ACC_PUBLIC) PHP_ME(Message, jsonEncode, NULL, ZEND_ACC_PUBLIC) PHP_ME(Message, jsonDecode, NULL, ZEND_ACC_PUBLIC) PHP_ME(Message, mergeFrom, NULL, ZEND_ACC_PUBLIC) diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 1562bbaf..2287f7e6 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -267,8 +267,8 @@ PHP_METHOD(Message, __construct); const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor *desc, const void *owner); -PHP_METHOD(Message, encode); -PHP_METHOD(Message, decode); +PHP_METHOD(Message, serializeToString); +PHP_METHOD(Message, mergeFromString); PHP_METHOD(Message, jsonEncode); PHP_METHOD(Message, jsonDecode); @@ -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..718682ac 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,112 @@ 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); + } + + 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); + } + + 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..aca1eb6e 100644 --- a/php/ext/google/protobuf/upb.c +++ b/php/ext/google/protobuf/upb.c @@ -10759,7 +10759,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/src/Google/Protobuf/Internal/DescriptorPool.php b/php/src/Google/Protobuf/Internal/DescriptorPool.php index 23b304ac..1ef403cf 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorPool.php +++ b/php/src/Google/Protobuf/Internal/DescriptorPool.php @@ -58,7 +58,7 @@ class DescriptorPool public function internalAddGeneratedFile($data) { $files = new FileDescriptorSet(); - $files->decode($data); + $files->mergeFromString($data); $file = FileDescriptor::buildFromProto($files->getFile()[0]); foreach ($file->getMessageType() as &$desc) { 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/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 17ef8536..887c86ca 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -562,12 +562,14 @@ class Message * Parses a protocol buffer contained in a string. * * This function takes a string in the (non-human-readable) binary wire - * format, matching the encoding output by encode(). + * format, matching the encoding output by serializeToString(). + * See mergeFrom() for merging behavior, if the field is already set in the + * specified message. * * @param string $data Binary protobuf data. * @return bool Return true on success. */ - public function decode($data) + public function mergeFromString($data) { $input = new InputStream($data); $this->parseFromStream($input); @@ -714,7 +716,7 @@ class Message * Serialize the message to string. * @return string Serialized binary protobuf data. */ - public function encode() + public function serializeToString() { $output = new OutputStream($this->byteSize()); $this->serializeToStream($output); @@ -770,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/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/tests/encode_decode_test.php b/php/tests/encode_decode_test.php index 3218aa63..ba4fff69 100644 --- a/php/tests/encode_decode_test.php +++ b/php/tests/encode_decode_test.php @@ -21,7 +21,7 @@ class EncodeDecodeTest extends TestBase $this->setFields($from); $this->expectFields($from); - $data = $from->encode(); + $data = $from->serializeToString(); $this->assertSame(bin2hex(TestUtil::getGoldenTestMessage()), bin2hex($data)); } @@ -29,7 +29,7 @@ class EncodeDecodeTest extends TestBase public function testDecode() { $to = new TestMessage(); - $to->decode(TestUtil::getGoldenTestMessage()); + $to->mergeFromString(TestUtil::getGoldenTestMessage()); $this->expectFields($to); } @@ -40,10 +40,10 @@ class EncodeDecodeTest extends TestBase $this->setFields($from); $this->expectFields($from); - $data = $from->encode(); + $data = $from->serializeToString(); $to = new TestMessage(); - $to->decode($data); + $to->mergeFromString($data); $this->expectFields($to); } @@ -52,10 +52,10 @@ class EncodeDecodeTest extends TestBase $from = new TestMessage(); $this->expectEmptyFields($from); - $data = $from->encode(); + $data = $from->serializeToString(); $to = new TestMessage(); - $to->decode($data); + $to->mergeFromString($data); $this->expectEmptyFields($to); } @@ -64,29 +64,29 @@ class EncodeDecodeTest extends TestBase $m = new TestMessage(); $m->setOneofInt32(1); - $data = $m->encode(); + $data = $m->serializeToString(); $n = new TestMessage(); - $n->decode($data); + $n->mergeFromString($data); $this->assertSame(1, $n->getOneofInt32()); $m->setOneofFloat(2.0); - $data = $m->encode(); + $data = $m->serializeToString(); $n = new TestMessage(); - $n->decode($data); + $n->mergeFromString($data); $this->assertSame(2.0, $n->getOneofFloat()); $m->setOneofString('abc'); - $data = $m->encode(); + $data = $m->serializeToString(); $n = new TestMessage(); - $n->decode($data); + $n->mergeFromString($data); $this->assertSame('abc', $n->getOneofString()); $sub_m = new TestMessage_Sub(); $sub_m->setA(1); $m->setOneofMessage($sub_m); - $data = $m->encode(); + $data = $m->serializeToString(); $n = new TestMessage(); - $n->decode($data); + $n->mergeFromString($data); $this->assertSame(1, $n->getOneofMessage()->getA()); } @@ -95,20 +95,20 @@ class EncodeDecodeTest extends TestBase $from = new TestPackedMessage(); TestUtil::setTestPackedMessage($from); $this->assertSame(TestUtil::getGoldenTestPackedMessage(), - $from->encode()); + $from->serializeToString()); } public function testPackedDecodePacked() { $to = new TestPackedMessage(); - $to->decode(TestUtil::getGoldenTestPackedMessage()); + $to->mergeFromString(TestUtil::getGoldenTestPackedMessage()); TestUtil::assertTestPackedMessage($to); } public function testPackedDecodeUnpacked() { $to = new TestPackedMessage(); - $to->decode(TestUtil::getGoldenTestUnpackedMessage()); + $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage()); TestUtil::assertTestPackedMessage($to); } @@ -117,20 +117,20 @@ class EncodeDecodeTest extends TestBase $from = new TestUnpackedMessage(); TestUtil::setTestPackedMessage($from); $this->assertSame(TestUtil::getGoldenTestUnpackedMessage(), - $from->encode()); + $from->serializeToString()); } public function testUnpackedDecodePacked() { $to = new TestUnpackedMessage(); - $to->decode(TestUtil::getGoldenTestPackedMessage()); + $to->mergeFromString(TestUtil::getGoldenTestPackedMessage()); TestUtil::assertTestPackedMessage($to); } public function testUnpackedDecodeUnpacked() { $to = new TestUnpackedMessage(); - $to->decode(TestUtil::getGoldenTestUnpackedMessage()); + $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage()); TestUtil::assertTestPackedMessage($to); } @@ -161,19 +161,54 @@ class EncodeDecodeTest extends TestBase $msg = new TestMessage(); foreach ($testVals as $original => $encoded) { $msg->setOptionalInt64($original); - $data = $msg->encode(); + $data = $msg->serializeToString(); $this->assertSame($encoded, bin2hex($data)); $msg->setOptionalInt64(0); - $msg->decode($data); + $msg->mergeFromString($data); $this->assertEquals($original, $msg->getOptionalInt64()); } } + public function testDecodeToExistingMessage() + { + $m1 = new TestMessage(); + $this->setFields($m1); + $this->expectFields($m1); + + $m2 = new TestMessage(); + $this->setFields2($m2); + $data = $m2->serializeToString(); + + $m1->mergeFromString($data); + $this->expectFieldsMerged($m1); + } + public function testDecodeFieldNonExist() { $data = hex2bin('c80501'); $m = new TestMessage(); - $m->decode($data); + $m->mergeFromString($data); + } + + public function testEncodeNegativeInt32() + { + $m = new TestMessage(); + $m->setOptionalInt32(-1); + $data = $m->encode(); + $this->assertSame("08ffffffffffffffffff01", bin2hex($data)); + } + + public function testDecodeNegativeInt32() + { + $m = new TestMessage(); + $this->assertEquals(0, $m->getOptionalInt32()); + $m->decode(hex2bin("08ffffffffffffffffff01")); + $this->assertEquals(-1, $m->getOptionalInt32()); + + $m = new TestMessage(); + $this->assertEquals(0, $m->getOptionalInt32()); + $m->decode(hex2bin("08ffffffff0f")); + $this->assertEquals(-1, $m->getOptionalInt32()); } # TODO(teboring): Add test back when php implementation is ready for json diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index 7f8567b8..4c3bca2d 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -6,6 +6,7 @@ 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\TestMessage; @@ -526,6 +527,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 +590,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. ######################################################### diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index d4776d6f..cfcbe62e 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -22,10 +22,10 @@ $from = new TestMessage(); TestUtil::setTestMessage($from); TestUtil::assertTestMessage($from); -$data = $from->encode(); +$data = $from->serializeToString(); $to = new TestMessage(); -$to->decode($data); +$to->mergeFromString($data); TestUtil::assertTestMessage($to); @@ -43,9 +43,9 @@ assert(1 === $m->getOneofInt32()); assert(0.0 === $m->getOneofFloat()); assert('' === $m->getOneofString()); assert(NULL === $m->getOneofMessage()); -$data = $m->encode(); +$data = $m->serializeToString(); $n = new TestMessage(); -$n->decode($data); +$n->mergeFromString($data); assert(1 === $n->getOneofInt32()); $m->setOneofFloat(2.0); @@ -53,9 +53,9 @@ assert(0 === $m->getOneofInt32()); assert(2.0 === $m->getOneofFloat()); assert('' === $m->getOneofString()); assert(NULL === $m->getOneofMessage()); -$data = $m->encode(); +$data = $m->serializeToString(); $n = new TestMessage(); -$n->decode($data); +$n->mergeFromString($data); assert(2.0 === $n->getOneofFloat()); $m->setOneofString('abc'); @@ -63,9 +63,9 @@ assert(0 === $m->getOneofInt32()); assert(0.0 === $m->getOneofFloat()); assert('abc' === $m->getOneofString()); assert(NULL === $m->getOneofMessage()); -$data = $m->encode(); +$data = $m->serializeToString(); $n = new TestMessage(); -$n->decode($data); +$n->mergeFromString($data); assert('abc' === $n->getOneofString()); $sub_m = new TestMessage_Sub(); @@ -75,9 +75,9 @@ assert(0 === $m->getOneofInt32()); assert(0.0 === $m->getOneofFloat()); assert('' === $m->getOneofString()); assert(1 === $m->getOneofMessage()->getA()); -$data = $m->encode(); +$data = $m->serializeToString(); $n = new TestMessage(); -$n->decode($data); +$n->mergeFromString($data); assert(1 === $n->getOneofMessage()->getA()); $from = new TestMessage(); diff --git a/php/tests/php_implementation_test.php b/php/tests/php_implementation_test.php index 00125db4..e1249808 100644 --- a/php/tests/php_implementation_test.php +++ b/php/tests/php_implementation_test.php @@ -290,14 +290,14 @@ class ImplementationTest extends TestBase public function testDecode() { $m = new TestMessage(); - $m->decode(TestUtil::getGoldenTestMessage()); + $m->mergeFromString(TestUtil::getGoldenTestMessage()); TestUtil::assertTestMessage($m); } public function testDescriptorDecode() { $file_desc_set = new FileDescriptorSet(); - $file_desc_set->decode(hex2bin( + $file_desc_set->mergeFromString(hex2bin( "0a3b0a12746573745f696e636c7564652e70726f746f120362617222180a" . "0b54657374496e636c75646512090a0161180120012805620670726f746f33")); @@ -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 c971df21..e5dee0fb 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -100,6 +100,7 @@ message TestMessage { enum TestEnum { ZERO = 0; ONE = 1; + TWO = 2; } message TestPackedMessage { diff --git a/php/tests/test_base.php b/php/tests/test_base.php index 729fea3b..67048f4c 100644 --- a/php/tests/test_base.php +++ b/php/tests/test_base.php @@ -12,6 +12,11 @@ class TestBase extends PHPUnit_Framework_TestCase TestUtil::setTestMessage($m); } + public function setFields2(TestMessage $m) + { + TestUtil::setTestMessage2($m); + } + public function expectFields(TestMessage $m) { $this->assertSame(-44, $m->getOptionalSint32()); @@ -98,6 +103,139 @@ class TestBase extends PHPUnit_Framework_TestCase $this->assertEquals(36, $m->getMapInt32Message()[1]->GetA()); } + // Test message merged from setFields and setFields2. + public function expectFieldsMerged(TestMessage $m) + { + $this->assertSame(-144, $m->getOptionalSint32()); + $this->assertSame(146, $m->getOptionalFixed32()); + $this->assertSame(-146, $m->getOptionalSfixed32()); + $this->assertSame(11.5, $m->getOptionalFloat()); + $this->assertSame(11.6, $m->getOptionalDouble()); + $this->assertSame(true, $m->getOptionalBool()); + $this->assertSame('aa', $m->getOptionalString()); + $this->assertSame('bb', $m->getOptionalBytes()); + $this->assertSame(133, $m->getOptionalMessage()->getA()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('-143', $m->getOptionalInt64()); + $this->assertSame('143', $m->getOptionalUint64()); + $this->assertSame('-145', $m->getOptionalSint64()); + $this->assertSame('147', $m->getOptionalFixed64()); + $this->assertSame('-147', $m->getOptionalSfixed64()); + } else { + $this->assertSame(-143, $m->getOptionalInt64()); + $this->assertSame(143, $m->getOptionalUint64()); + $this->assertSame(-145, $m->getOptionalSint64()); + $this->assertSame(147, $m->getOptionalFixed64()); + $this->assertSame(-147, $m->getOptionalSfixed64()); + } + + $this->assertEquals(-42, $m->getRepeatedInt32()[0]); + $this->assertEquals(42, $m->getRepeatedUint32()[0]); + $this->assertEquals(-43, $m->getRepeatedInt64()[0]); + $this->assertEquals(43, $m->getRepeatedUint64()[0]); + $this->assertEquals(-44, $m->getRepeatedSint32()[0]); + $this->assertEquals(-45, $m->getRepeatedSint64()[0]); + $this->assertEquals(46, $m->getRepeatedFixed32()[0]); + $this->assertEquals(47, $m->getRepeatedFixed64()[0]); + $this->assertEquals(-46, $m->getRepeatedSfixed32()[0]); + $this->assertEquals(-47, $m->getRepeatedSfixed64()[0]); + $this->assertEquals(1.5, $m->getRepeatedFloat()[0]); + $this->assertEquals(1.6, $m->getRepeatedDouble()[0]); + $this->assertEquals(true, $m->getRepeatedBool()[0]); + $this->assertEquals('a', $m->getRepeatedString()[0]); + $this->assertEquals('b', $m->getRepeatedBytes()[0]); + $this->assertEquals(TestEnum::ZERO, $m->getRepeatedEnum()[0]); + $this->assertEquals(34, $m->getRepeatedMessage()[0]->GetA()); + + $this->assertEquals(-52, $m->getRepeatedInt32()[1]); + $this->assertEquals(52, $m->getRepeatedUint32()[1]); + $this->assertEquals(-53, $m->getRepeatedInt64()[1]); + $this->assertEquals(53, $m->getRepeatedUint64()[1]); + $this->assertEquals(-54, $m->getRepeatedSint32()[1]); + $this->assertEquals(-55, $m->getRepeatedSint64()[1]); + $this->assertEquals(56, $m->getRepeatedFixed32()[1]); + $this->assertEquals(57, $m->getRepeatedFixed64()[1]); + $this->assertEquals(-56, $m->getRepeatedSfixed32()[1]); + $this->assertEquals(-57, $m->getRepeatedSfixed64()[1]); + $this->assertEquals(2.5, $m->getRepeatedFloat()[1]); + $this->assertEquals(2.6, $m->getRepeatedDouble()[1]); + $this->assertEquals(false, $m->getRepeatedBool()[1]); + $this->assertEquals('c', $m->getRepeatedString()[1]); + $this->assertEquals('d', $m->getRepeatedBytes()[1]); + $this->assertEquals(TestEnum::ONE, $m->getRepeatedEnum()[1]); + $this->assertEquals(35, $m->getRepeatedMessage()[1]->GetA()); + + $this->assertEquals(-142, $m->getRepeatedInt32()[2]); + $this->assertEquals(142, $m->getRepeatedUint32()[2]); + $this->assertEquals(-143, $m->getRepeatedInt64()[2]); + $this->assertEquals(143, $m->getRepeatedUint64()[2]); + $this->assertEquals(-144, $m->getRepeatedSint32()[2]); + $this->assertEquals(-145, $m->getRepeatedSint64()[2]); + $this->assertEquals(146, $m->getRepeatedFixed32()[2]); + $this->assertEquals(147, $m->getRepeatedFixed64()[2]); + $this->assertEquals(-146, $m->getRepeatedSfixed32()[2]); + $this->assertEquals(-147, $m->getRepeatedSfixed64()[2]); + $this->assertEquals(11.5, $m->getRepeatedFloat()[2]); + $this->assertEquals(11.6, $m->getRepeatedDouble()[2]); + $this->assertEquals(false, $m->getRepeatedBool()[2]); + $this->assertEquals('aa', $m->getRepeatedString()[2]); + $this->assertEquals('bb', $m->getRepeatedBytes()[2]); + $this->assertEquals(TestEnum::TWO, $m->getRepeatedEnum()[2]); + $this->assertEquals(134, $m->getRepeatedMessage()[2]->GetA()); + + if (PHP_INT_SIZE == 4) { + $this->assertEquals('-163', $m->getMapInt64Int64()['-63']); + $this->assertEquals('163', $m->getMapUint64Uint64()['63']); + $this->assertEquals('-165', $m->getMapSint64Sint64()['-65']); + $this->assertEquals('167', $m->getMapFixed64Fixed64()['67']); + $this->assertEquals('-169', $m->getMapSfixed64Sfixed64()['-69']); + } else { + $this->assertEquals(-163, $m->getMapInt64Int64()[-63]); + $this->assertEquals(163, $m->getMapUint64Uint64()[63]); + $this->assertEquals(-165, $m->getMapSint64Sint64()[-65]); + $this->assertEquals(167, $m->getMapFixed64Fixed64()[67]); + $this->assertEquals(-169, $m->getMapSfixed64Sfixed64()[-69]); + } + $this->assertEquals(-162, $m->getMapInt32Int32()[-62]); + $this->assertEquals(162, $m->getMapUint32Uint32()[62]); + $this->assertEquals(-164, $m->getMapSint32Sint32()[-64]); + $this->assertEquals(166, $m->getMapFixed32Fixed32()[66]); + $this->assertEquals(-168, $m->getMapSfixed32Sfixed32()[-68]); + $this->assertEquals(13.5, $m->getMapInt32Float()[1]); + $this->assertEquals(13.6, $m->getMapInt32Double()[1]); + $this->assertEquals(false , $m->getMapBoolBool()[true]); + $this->assertEquals('ee', $m->getMapStringString()['e']); + $this->assertEquals('ff', $m->getMapInt32Bytes()[1]); + $this->assertEquals(TestEnum::TWO, $m->getMapInt32Enum()[1]); + $this->assertEquals(136, $m->getMapInt32Message()[1]->GetA()); + + if (PHP_INT_SIZE == 4) { + $this->assertEquals('-163', $m->getMapInt64Int64()['-163']); + $this->assertEquals('163', $m->getMapUint64Uint64()['163']); + $this->assertEquals('-165', $m->getMapSint64Sint64()['-165']); + $this->assertEquals('167', $m->getMapFixed64Fixed64()['167']); + $this->assertEquals('-169', $m->getMapSfixed64Sfixed64()['-169']); + } else { + $this->assertEquals(-163, $m->getMapInt64Int64()[-163]); + $this->assertEquals(163, $m->getMapUint64Uint64()[163]); + $this->assertEquals(-165, $m->getMapSint64Sint64()[-165]); + $this->assertEquals(167, $m->getMapFixed64Fixed64()[167]); + $this->assertEquals(-169, $m->getMapSfixed64Sfixed64()[-169]); + } + $this->assertEquals(-162, $m->getMapInt32Int32()[-162]); + $this->assertEquals(162, $m->getMapUint32Uint32()[162]); + $this->assertEquals(-164, $m->getMapSint32Sint32()[-164]); + $this->assertEquals(166, $m->getMapFixed32Fixed32()[166]); + $this->assertEquals(-168, $m->getMapSfixed32Sfixed32()[-168]); + $this->assertEquals(13.5, $m->getMapInt32Float()[2]); + $this->assertEquals(13.6, $m->getMapInt32Double()[2]); + $this->assertEquals(false , $m->getMapBoolBool()[false]); + $this->assertEquals('ee', $m->getMapStringString()['ee']); + $this->assertEquals('ff', $m->getMapInt32Bytes()[2]); + $this->assertEquals(TestEnum::TWO, $m->getMapInt32Enum()[2]); + $this->assertEquals(136, $m->getMapInt32Message()[2]->GetA()); + } + public function expectEmptyFields(TestMessage $m) { $this->assertSame(0, $m->getOptionalInt32()); diff --git a/php/tests/test_util.php b/php/tests/test_util.php index b7db5c1d..61f94aa1 100644 --- a/php/tests/test_util.php +++ b/php/tests/test_util.php @@ -130,6 +130,87 @@ class TestUtil $m->getMapInt32Message()[1]->SetA(36); } + public static function setTestMessage2(TestMessage $m) + { + $sub = new TestMessage_Sub(); + + $m->setOptionalInt32(-142); + $m->setOptionalInt64(-143); + $m->setOptionalUint32(142); + $m->setOptionalUint64(143); + $m->setOptionalSint32(-144); + $m->setOptionalSint64(-145); + $m->setOptionalFixed32(146); + $m->setOptionalFixed64(147); + $m->setOptionalSfixed32(-146); + $m->setOptionalSfixed64(-147); + $m->setOptionalFloat(11.5); + $m->setOptionalDouble(11.6); + $m->setOptionalBool(true); + $m->setOptionalString('aa'); + $m->setOptionalBytes('bb'); + $m->setOptionalEnum(TestEnum::TWO); + $m->setOptionalMessage($sub); + $m->getOptionalMessage()->SetA(133); + + $m->getRepeatedInt32() []= -142; + $m->getRepeatedInt64() []= -143; + $m->getRepeatedUint32() []= 142; + $m->getRepeatedUint64() []= 143; + $m->getRepeatedSint32() []= -144; + $m->getRepeatedSint64() []= -145; + $m->getRepeatedFixed32() []= 146; + $m->getRepeatedFixed64() []= 147; + $m->getRepeatedSfixed32() []= -146; + $m->getRepeatedSfixed64() []= -147; + $m->getRepeatedFloat() []= 11.5; + $m->getRepeatedDouble() []= 11.6; + $m->getRepeatedBool() []= false; + $m->getRepeatedString() []= 'aa'; + $m->getRepeatedBytes() []= 'bb'; + $m->getRepeatedEnum() []= TestEnum::TWO; + $m->getRepeatedMessage() []= new TestMessage_Sub(); + $m->getRepeatedMessage()[0]->setA(134); + + $m->getMapInt32Int32()[-62] = -162; + $m->getMapInt64Int64()[-63] = -163; + $m->getMapUint32Uint32()[62] = 162; + $m->getMapUint64Uint64()[63] = 163; + $m->getMapSint32Sint32()[-64] = -164; + $m->getMapSint64Sint64()[-65] = -165; + $m->getMapFixed32Fixed32()[66] = 166; + $m->getMapFixed64Fixed64()[67] = 167; + $m->getMapSfixed32Sfixed32()[-68] = -168; + $m->getMapSfixed64Sfixed64()[-69] = -169; + $m->getMapInt32Float()[1] = 13.5; + $m->getMapInt32Double()[1] = 13.6; + $m->getMapBoolBool()[true] = false; + $m->getMapStringString()['e'] = 'ee'; + $m->getMapInt32Bytes()[1] = 'ff'; + $m->getMapInt32Enum()[1] = TestEnum::TWO; + $m->getMapInt32Message()[1] = new TestMessage_Sub(); + $m->getMapInt32Message()[1]->SetA(136); + + $m->getMapInt32Int32()[-162] = -162; + $m->getMapInt64Int64()[-163] = -163; + $m->getMapUint32Uint32()[162] = 162; + $m->getMapUint64Uint64()[163] = 163; + $m->getMapSint32Sint32()[-164] = -164; + $m->getMapSint64Sint64()[-165] = -165; + $m->getMapFixed32Fixed32()[166] = 166; + $m->getMapFixed64Fixed64()[167] = 167; + $m->getMapSfixed32Sfixed32()[-168] = -168; + $m->getMapSfixed64Sfixed64()[-169] = -169; + $m->getMapInt32Float()[2] = 13.5; + $m->getMapInt32Double()[2] = 13.6; + $m->getMapBoolBool()[false] = false; + $m->getMapStringString()['ee'] = 'ee'; + $m->getMapInt32Bytes()[2] = 'ff'; + $m->getMapInt32Enum()[2] = TestEnum::TWO; + $m->getMapInt32Message()[2] = new TestMessage_Sub(); + $m->getMapInt32Message()[2]->SetA(136); + } + public static function assertTestMessage(TestMessage $m) { if (PHP_INT_SIZE == 4) { @@ -240,7 +321,7 @@ class TestUtil public static function getGoldenTestMessage() { return hex2bin( - "08D6FFFFFF0F" . + "08D6FFFFFFFFFFFFFFFF01" . "10D5FFFFFFFFFFFFFFFF01" . "182A" . "202B" . @@ -258,8 +339,8 @@ class TestUtil "800101" . "8A01020821" . - "F801D6FFFFFF0F" . - "F801CCFFFFFF0F" . + "F801D6FFFFFFFFFFFFFFFF01" . + "F801CCFFFFFFFFFFFFFFFF01" . "8002D5FFFFFFFFFFFFFFFF01" . "8002CBFFFFFFFFFFFFFFFF01" . "88022A" . @@ -293,7 +374,7 @@ class TestUtil "FA02020822" . "FA02020823" . - "BA040C08C2FFFFFF0F10C2FFFFFF0F" . + "BA041608C2FFFFFFFFFFFFFFFF0110C2FFFFFFFFFFFFFFFF01" . "C2041608C1FFFFFFFFFFFFFFFF0110C1FFFFFFFFFFFFFFFF01" . "CA0404083E103E" . "D20404083F103F" . @@ -408,7 +489,7 @@ class TestUtil public static function getGoldenTestPackedMessage() { return hex2bin( - "D2050AD6FFFFFF0FCCFFFFFF0F" . + "D20514D6FFFFFFFFFFFFFFFF01CCFFFFFFFFFFFFFFFF01" . "DA0514D5FFFFFFFFFFFFFFFF01CBFFFFFFFFFFFFFFFF01" . "E205022A34" . "EA05022B35" . @@ -428,7 +509,7 @@ class TestUtil public static function getGoldenTestUnpackedMessage() { return hex2bin( - "D005D6FFFFFF0FD005CCFFFFFF0F" . + "D005D6FFFFFFFFFFFFFFFF01D005CCFFFFFFFFFFFFFFFF01" . "D805D5FFFFFFFFFFFFFFFF01D805CBFFFFFFFFFFFFFFFF01" . "E0052AE00534" . "E8052BE80535" . diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py index 51c83321..05bafd69 100755 --- a/python/google/protobuf/reflection.py +++ b/python/google/protobuf/reflection.py @@ -61,6 +61,8 @@ else: # Part of the public interface, but normally only used by message factories. GeneratedProtocolMessageType = message_impl.GeneratedProtocolMessageType +MESSAGE_CLASS_CACHE = {} + def ParseMessage(descriptor, byte_str): """Generate a new Message instance from this Descriptor and a byte string. @@ -104,11 +106,16 @@ def MakeClass(descriptor): Returns: The Message class object described by the descriptor. """ + if descriptor in MESSAGE_CLASS_CACHE: + return MESSAGE_CLASS_CACHE[descriptor] + attributes = {} for name, nested_type in descriptor.nested_types_by_name.items(): attributes[name] = MakeClass(nested_type) attributes[GeneratedProtocolMessageType._DESCRIPTOR_KEY] = descriptor - return GeneratedProtocolMessageType(str(descriptor.name), (message.Message,), + result = GeneratedProtocolMessageType(str(descriptor.name), (message.Message,), attributes) + MESSAGE_CLASS_CACHE[descriptor] = result + return result 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/extconf.rb b/ruby/ext/google/protobuf_c/extconf.rb index b368dcc6..0886e607 100644 --- a/ruby/ext/google/protobuf_c/extconf.rb +++ b/ruby/ext/google/protobuf_c/extconf.rb @@ -4,7 +4,14 @@ require 'mkmf' $CFLAGS += " -std=c99 -O3 -DNDEBUG" + +if RUBY_PLATFORM =~ /linux/ + # Instruct the linker to point memcpy calls at our __wrap_memcpy wrapper. + $LDFLAGS += " -Wl,-wrap,memcpy" +end + $objs = ["protobuf.o", "defs.o", "storage.o", "message.o", - "repeated_field.o", "map.o", "encode_decode.o", "upb.o"] + "repeated_field.o", "map.o", "encode_decode.o", "upb.o", + "wrap_memcpy.o"] create_makefile("google/protobuf_c") diff --git a/ruby/ext/google/protobuf_c/wrap_memcpy.c b/ruby/ext/google/protobuf_c/wrap_memcpy.c new file mode 100644 index 00000000..158952a8 --- /dev/null +++ b/ruby/ext/google/protobuf_c/wrap_memcpy.c @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2017 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <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). +// +// This wrapper is enabled by passing the linker flags -Wl,-wrap,memcpy in +// extconf.rb. +#ifdef __linux__ +#ifdef __x86_64__ +__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); +void *__wrap_memcpy(void *dest, const void *src, size_t n) { + return memcpy(dest, src, n); +} +#else +void *__wrap_memcpy(void *dest, const void *src, size_t n) { + return memmove(dest, src, n); +} +#endif +#endif 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/src/Makefile.am b/src/Makefile.am index ab9eb31b..6a91044d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -180,6 +180,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 +225,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 \ @@ -305,6 +313,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 +592,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 = \ @@ -783,6 +798,7 @@ protobuf_test_SOURCES = \ google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc \ google/protobuf/compiler/python/python_plugin_unittest.cc \ 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/field_comparator_test.cc \ google/protobuf/util/field_mask_util_test.cc \ diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 1914fc48..f516477b 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -37,6 +37,12 @@ #include <stdio.h> #include <sys/types.h> +#ifdef major +#undef major +#endif +#ifdef minor +#undef minor +#endif #include <sys/stat.h> #include <fcntl.h> #ifdef _MSC_VER @@ -1446,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" @@ -1493,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" @@ -1509,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/csharp/csharp_bootstrap_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc new file mode 100644 index 00000000..4e44b578 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @@ -0,0 +1,197 @@ +// 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. + +// This test insures that +// csharp/src/Google.Protobuf/Reflection/Descriptor.cs match exactly +// what would be generated by the protocol compiler. The file is not +// generated automatically at build time. +// +// If this test fails, run the script +// "generate_descriptor_proto.sh" and add the changed files under +// csharp/src/ to your changelist. + +#include <map> + +#include <google/protobuf/compiler/csharp/csharp_generator.h> +#include <google/protobuf/compiler/importer.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/stubs/map_util.h> +#include <google/protobuf/stubs/stl_util.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> + +#include <google/protobuf/testing/file.h> +#include <google/protobuf/testing/file.h> +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +namespace { + +class MockErrorCollector : public MultiFileErrorCollector { + public: + MockErrorCollector() {} + ~MockErrorCollector() {} + + string text_; + + // implements ErrorCollector --------------------------------------- + void AddError(const string& filename, int line, int column, + const string& message) { + strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", + filename, line, column, message); + } +}; + +class MockGeneratorContext : public GeneratorContext { + public: + MockGeneratorContext() {} + ~MockGeneratorContext() { + STLDeleteValues(&files_); + } + + void ExpectFileMatches(const string& virtual_filename, + const string& physical_filename) { + string* expected_contents = FindPtrOrNull(files_, virtual_filename); + ASSERT_TRUE(expected_contents != NULL) + << "Generator failed to generate file: " << virtual_filename; + + string actual_contents; + GOOGLE_CHECK_OK( + File::GetContents(TestSourceDir() + "/" + physical_filename, + &actual_contents, true)) + << "Unable to get " << physical_filename; + EXPECT_TRUE(actual_contents == *expected_contents) + << physical_filename << " needs to be regenerated. Please run " + "generate_descriptor_proto.sh. Then add this file " + "to your CL."; + } + + // implements GeneratorContext -------------------------------------- + + virtual io::ZeroCopyOutputStream* Open(const string& filename) { + string** map_slot = &files_[filename]; + delete *map_slot; + *map_slot = new string; + + return new io::StringOutputStream(*map_slot); + } + + private: + std::map<string, string*> files_; +}; + +class GenerateAndTest { + public: + GenerateAndTest() {} + void Run(const FileDescriptor* proto_file, string file1, string file2) { + ASSERT_TRUE(proto_file != NULL) << TestSourceDir(); + ASSERT_TRUE(generator_.Generate(proto_file, parameter_, + &context_, &error_)); + context_.ExpectFileMatches(file1, file2); + } + void SetParameter(string parameter) { + parameter_ = parameter; + } + + private: + Generator generator_; + MockGeneratorContext context_; + string error_; + string parameter_; +}; + +TEST(CsharpBootstrapTest, GeneratedCsharpDescriptorMatches) { + MockErrorCollector error_collector; + DiskSourceTree source_tree; + Importer importer(&source_tree, &error_collector); + GenerateAndTest generate_test; + + generate_test.SetParameter("base_namespace=Google.Protobuf"); + source_tree.MapPath("", TestSourceDir()); + generate_test.Run(importer.Import("google/protobuf/descriptor.proto"), + "Reflection/Descriptor.cs", + "../csharp/src/Google.Protobuf/Reflection/Descriptor.cs"); + generate_test.Run(importer.Import("google/protobuf/any.proto"), + "WellKnownTypes/Any.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Any.cs"); + generate_test.Run(importer.Import("google/protobuf/api.proto"), + "WellKnownTypes/Api.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Api.cs"); + generate_test.Run(importer.Import("google/protobuf/duration.proto"), + "WellKnownTypes/Duration.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs"); + generate_test.Run(importer.Import("google/protobuf/empty.proto"), + "WellKnownTypes/Empty.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs"); + generate_test.Run(importer.Import("google/protobuf/field_mask.proto"), + "WellKnownTypes/FieldMask.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs"); + generate_test.Run(importer.Import("google/protobuf/source_context.proto"), + "WellKnownTypes/SourceContext.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs"); + generate_test.Run(importer.Import("google/protobuf/struct.proto"), + "WellKnownTypes/Struct.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs"); + generate_test.Run(importer.Import("google/protobuf/timestamp.proto"), + "WellKnownTypes/Timestamp.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs"); + generate_test.Run(importer.Import("google/protobuf/type.proto"), + "WellKnownTypes/Type.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Type.cs"); + generate_test.Run(importer.Import("google/protobuf/wrappers.proto"), + "WellKnownTypes/Wrappers.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs"); + + generate_test.SetParameter(""); + source_tree.MapPath("", TestSourceDir() + "/../examples"); + generate_test.Run(importer.Import("addressbook.proto"), + "Addressbook.cs", + "../csharp/src/AddressBook/Addressbook.cs"); + + source_tree.MapPath("", TestSourceDir() + "/../conformance"); + generate_test.Run(importer.Import("conformance.proto"), + "Conformance.cs", + "../csharp/src/Google.Protobuf.Conformance/Conformance.cs"); + + EXPECT_EQ("", error_collector.text_); +} + +} // namespace + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.h b/src/google/protobuf/compiler/csharp/csharp_generator.h index fd41d852..c8b19529 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator.h +++ b/src/google/protobuf/compiler/csharp/csharp_generator.h @@ -48,6 +48,7 @@ namespace csharp { // CodeGenerator with the CommandLineInterface in your main() function. class LIBPROTOC_EXPORT Generator : public google::protobuf::compiler::CodeGenerator { +public: virtual bool Generate( const FileDescriptor* file, const string& parameter, @@ -61,4 +62,3 @@ class LIBPROTOC_EXPORT Generator } // namespace google #endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ - diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index df4db463..3b8d7ab8 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -253,18 +253,22 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.GeneratedMessage$ver$.\n" " ExtendableMessageOrBuilder<$classname$> {\n", + "deprecation", descriptor_->options().deprecated() ? + "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), "idend", "", "ver", GeneratedCodeVersionSuffix()); } else { printer->Print( - "public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.MessageOrBuilder {\n", + "deprecation", descriptor_->options().deprecated() ? + "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), "idend", ""); @@ -304,6 +308,8 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { variables["classname"] = descriptor_->name(); variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); variables["ver"] = GeneratedCodeVersionSuffix(); + variables["deprecation"] = descriptor_->options().deprecated() + ? "@java.lang.Deprecated " : ""; WriteMessageDocComment(printer, descriptor_); MaybePrintGeneratedAnnotation(context_, printer, descriptor_, @@ -312,8 +318,9 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { // The builder_type stores the super type name of the nested Builder class. string builder_type; if (descriptor_->extension_range_count() > 0) { - printer->Print(variables, - "public $static$final class $classname$ extends\n"); + printer->Print( + variables, + "$deprecation$public $static$final class $classname$ extends\n"); printer->Annotate("classname", descriptor_); printer->Print( variables, @@ -326,8 +333,9 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { name_resolver_->GetImmutableClassName(descriptor_), GeneratedCodeVersionSuffix()); } else { - printer->Print(variables, - "public $static$final class $classname$ extends\n"); + printer->Print( + variables, + "$deprecation$public $static$final class $classname$ extends\n"); printer->Annotate("classname", descriptor_); printer->Print(variables, " com.google.protobuf.GeneratedMessage$ver$ implements\n" @@ -1445,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 048d5892..e84321bb 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -124,19 +124,23 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "public interface $classname$OrBuilder$idend$ extends \n" + "$deprecation$public interface $classname$OrBuilder$idend$ extends \n" " $extra_interfaces$\n" " com.google.protobuf.GeneratedMessageLite.\n" " ExtendableMessageOrBuilder<\n" " $classname$, $classname$.Builder> {\n", + "deprecation", descriptor_->options().deprecated() ? + "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), "idend", ""); } else { printer->Print( - "public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.MessageLiteOrBuilder {\n", + "deprecation", descriptor_->options().deprecated() ? + "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), "idend", ""); @@ -174,6 +178,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { variables["static"] = is_own_file ? " " : " static "; variables["classname"] = descriptor_->name(); variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); + variables["deprecation"] = descriptor_->options().deprecated() + ? "@java.lang.Deprecated " : ""; WriteMessageDocComment(printer, descriptor_); MaybePrintGeneratedAnnotation(context_, printer, descriptor_, @@ -184,7 +190,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { string builder_type; if (descriptor_->extension_range_count() > 0) { printer->Print(variables, - "public $static$final class $classname$ extends\n" + "$deprecation$public $static$final class $classname$ extends\n" " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" " $classname$, $classname$.Builder> implements\n" " $extra_interfaces$\n" @@ -194,7 +200,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { name_resolver_->GetImmutableClassName(descriptor_)); } else { printer->Print(variables, - "public $static$final class $classname$ extends\n" + "$deprecation$public $static$final class $classname$ extends\n" " com.google.protobuf.GeneratedMessageLite<\n" " $classname$, $classname$.Builder> implements\n" " $extra_interfaces$\n" @@ -339,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/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index fa1047e8..840252e7 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -523,8 +523,17 @@ void ImmutablePrimitiveOneofFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { printer->Print(variables_, "if ($has_oneof_case_message$) {\n" - " output.write$capitalized_type$(\n" - " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n" + " output.write$capitalized_type$(\n"); + // $type$ and $boxed_type$ is the same for bytes fields so we don't need to + // do redundant casts. + if (GetJavaType(descriptor_) == JAVATYPE_BYTES) { + printer->Print(variables_, + " $number$, ($type$) $oneof_name$_);\n"); + } else { + printer->Print(variables_, + " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"); + } + printer->Print( "}\n"); } @@ -533,8 +542,17 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print(variables_, "if ($has_oneof_case_message$) {\n" " size += com.google.protobuf.CodedOutputStream\n" - " .compute$capitalized_type$Size(\n" - " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n" + " .compute$capitalized_type$Size(\n"); + // $type$ and $boxed_type$ is the same for bytes fields so we don't need to + // do redundant casts. + if (GetJavaType(descriptor_) == JAVATYPE_BYTES) { + printer->Print(variables_, + " $number$, ($type$) $oneof_name$_);\n"); + } else { + printer->Print(variables_, + " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"); + } + printer->Print( "}\n"); } diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index e82e6ae1..a4b522ce 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -40,7 +40,6 @@ #endif #include <vector> -#include <google/protobuf/compiler/plugin.pb.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/testing/file.h> @@ -54,6 +53,14 @@ #include <google/protobuf/stubs/substitute.h> #include <gtest/gtest.h> +#ifdef major +#undef major +#endif +#ifdef minor +#undef minor +#endif +#include <google/protobuf/compiler/plugin.pb.h> + namespace google { namespace protobuf { namespace compiler { diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index ec9a2365..7f35d712 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -439,9 +439,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 +502,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/repeated_field.h b/src/google/protobuf/repeated_field.h index 4e5bcf51..db5893b5 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -1487,7 +1487,6 @@ inline void RepeatedPtrFieldBase::Add( typename TypeHandler::Type* result = TypeHandler::New(arena_, std::move(value)); rep_->elements[current_size_++] = result; - return result; } #endif 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/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/unittest.proto b/src/google/protobuf/unittest.proto index 96289cc5..188a4f47 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto @@ -191,6 +191,10 @@ message TestDeprecatedFields { optional int32 deprecated_int32 = 1 [deprecated=true]; } +message TestDeprecatedMessage { + option deprecated = true; +} + // Define these after TestAllTypes to make sure the compiler can handle // that. message ForeignMessage { 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/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: + *; +}; @@ -402,7 +402,14 @@ use_php_bc() { } build_php5.5() { - use_php 5.5 + PHP=`which php` + PHP_CONFIG=`which php-config` + PHPIZE=`which phpize` + ln -sfn "/usr/local/php-5.5/bin/php" $PHP + ln -sfn "/usr/local/php-5.5/bin/php-config" $PHP_CONFIG + ln -sfn "/usr/local/php-5.5/bin/phpize" $PHPIZE + generate_php_test_proto + pushd php rm -rf vendor cp -r /usr/local/vendor-5.5 vendor @@ -415,7 +422,15 @@ build_php5.5() { } build_php5.5_c() { - use_php 5.5 + PHP=`which php` + PHP_CONFIG=`which php-config` + PHPIZE=`which phpize` + ln -sfn "/usr/local/php-5.5/bin/php" $PHP + ln -sfn "/usr/local/php-5.5/bin/php-config" $PHP_CONFIG + ln -sfn "/usr/local/php-5.5/bin/phpize" $PHPIZE + generate_php_test_proto + wget https://phar.phpunit.de/phpunit-old.phar -O /usr/bin/phpunit + cd php/tests && /bin/bash ./test.sh && cd ../.. pushd conformance make test_php_c |