diff --git a/CHANGES.txt b/CHANGES.txt
index 3459cccf..04fa418e 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,84 @@
+2016-07-15 version 3.0.0-beta-4 (C++/Java/Python/Ruby/Objective-C/C#/JavaScript)
+ General
+ * Added a deterministic serialization API for C++. The deterministic
+ serialization guarantees that given a binary, equal messages will be
+ serialized to the same bytes. This allows applications like MapReduce to
+ group equal messages based on the serialized bytes. The deterministic
+ serialization is, however, NOT canonical across languages; it is also
+ unstable across different builds with schema changes due to unknown fields.
+ Users who need canonical serialization, e.g. persistent storage in a
+ canonical form, fingerprinting, etc, should define their own
+ canonicalization specification and implement the serializer using reflection
+ APIs rather than relying on this API.
+ * Added OneofOptions. You can now define custom options for oneof groups.
+ import "google/protobuf/descriptor.proto";
+ extend google.protobuf.OneofOptions {
+ optional int32 my_oneof_extension = 12345;
+ }
+ message Foo {
+ oneof oneof_group {
+ (my_oneof_extension) = 54321;
+ ...
+ }
+ }
+
+ C++ (beta)
+ * Introduced a deterministic serialization API in
+ CodedOutputStream::SetSerializationDeterministic(bool). See the notes about
+ deterministic serialization in the General section.
+ * Added google::protobuf::Map::swap() to swap two map fields.
+ * Fixed a memory leak when calling Reflection::ReleaseMessage() on a message
+ allocated on arena.
+ * Improved error reporting when parsing text format protos.
+ * JSON
+ - Added a new parser option to ignore unknown fields when parsing JSON.
+ - Added convenient methods for message to/from JSON conversion.
+ * Various performance optimizations.
+
+ Java (beta)
+ * File option "java_generate_equals_and_hash" is now deprecated. equals() and
+ hashCode() methods are generated by default.
+ * Added a new JSON printer option "omittingInsignificantWhitespace" to produce
+ a more compact JSON output. The printer will pretty-print by default.
+ * Updated Java runtime to be compatible with 2.5.0/2.6.1 generated protos.
+
+ Python (beta)
+ * Added support to pretty print Any messages in text format.
+ * Added a flag to ignore unknown fields when parsing JSON.
+ * Bugfix: "@type" field of a JSON Any message is now correctly put before
+ other fields.
+
+ Objective-C (beta)
+ * Updated the code to support compiling with more compiler warnings
+ enabled. (Issue 1616)
+ * Exposing more detailed errors for parsing failures. (PR 1623)
+ * Small (breaking) change to the naming of some methods on the support classes
+ for map<>. There were collisions with the system provided KVO support, so
+ the names were changed to avoid those issues. (PR 1699)
+ * Fixed for proper Swift bridging of error handling during parsing. (PR 1712)
+ * Complete support for generating sources that will go into a Framework and
+ depend on generated sources from other Frameworks. (Issue 1457)
+
+ C# (beta)
+ * RepeatedField optimizations.
+ * Support for .NET Core.
+ * Minor bug fixes.
+ * Ability to format a single value in JsonFormatter (advanced usage only).
+ * Modifications to attributes applied to generated code.
+
+ Javascript (alpha)
+ * Maps now have a real map API instead of being treated as repeated fields.
+ * Well-known types are now provided in the google-protobuf package, and the
+ code generator knows to require() them from that package.
+ * Bugfix: non-canonical varints are correctly decoded.
+
+ Ruby (alpha)
+ * Accessors for oneof fields now return default values instead of nil.
+
+ Java Lite
+ * Java lite support is removed from protocol compiler. It will be supported
+ as a protocol compiler plugin in a separate code branch.
+
2016-05-16 version 3.0.0-beta-3 (C++/Java/Python/Ruby/Nano/Objective-C/C#/JavaScript)
General
* Supported Proto3 lite-runtime in C++/Java for mobile platforms.
diff --git a/Protobuf.podspec b/Protobuf.podspec
index 2523076a..ac27f03e 100644
--- a/Protobuf.podspec
+++ b/Protobuf.podspec
@@ -5,7 +5,7 @@
# dependent projects use the :git notation to refer to the library.
Pod::Spec.new do |s|
s.name = 'Protobuf'
- s.version = '3.0.0-beta-3'
+ s.version = '3.0.0-beta-4'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/google/protobuf'
s.license = 'New BSD'
diff --git a/cmake/examples.cmake b/cmake/examples.cmake
index 0a651051..e5cad63f 100644
--- a/cmake/examples.cmake
+++ b/cmake/examples.cmake
@@ -1,57 +1,57 @@
-if(protobuf_VERBOSE)
- message(STATUS "Protocol Buffers Examples Configuring...")
-endif()
-
-get_filename_component(examples_dir "../examples" ABSOLUTE)
-
-if(protobuf_VERBOSE)
- message(STATUS "Protocol Buffers Examples Configuring done")
-endif()
-include(ExternalProject)
-
-# Internal utility function: Create a custom target representing a build of examples with custom options.
-function(add_examples_build NAME)
-
- ExternalProject_Add(${NAME}
- PREFIX ${NAME}
- SOURCE_DIR "${examples_dir}"
- BINARY_DIR ${NAME}
- STAMP_DIR ${NAME}/logs
- INSTALL_COMMAND "" #Skip
- LOG_CONFIGURE 1
- CMAKE_CACHE_ARGS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
- "-Dprotobuf_VERBOSE:BOOL=${protobuf_VERBOSE}"
- ${ARGN}
- )
- set_property(TARGET ${NAME} PROPERTY FOLDER "Examples")
- set_property(TARGET ${NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
-endfunction()
-
-# Add examples as an external project.
-# sub_directory cannot be used because the find_package(protobuf) call would cause failures with redefined targets.
-add_examples_build(examples "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}")
-add_dependencies(examples libprotobuf protoc)
-
-option(protobuf_BUILD_EXAMPLES_MULTITEST "Build Examples in multiple configurations. Useful for testing." OFF)
-mark_as_advanced(protobuf_BUILD_EXAMPLES_MULTITEST)
-if(protobuf_BUILD_EXAMPLES_MULTITEST)
- set_property(GLOBAL PROPERTY USE_FOLDERS ON)
-
- #Build using the legacy compatibility module.
- add_examples_build(examples-legacy
- "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}"
- "-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
- )
- add_dependencies(examples-legacy libprotobuf protoc)
-
- #Build using the installed library.
- add_examples_build(examples-installed
- "-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
- )
-
- #Build using the installed library in legacy compatibility mode.
- add_examples_build(examples-installed-legacy
- "-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
- "-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
- )
-endif()
+if(protobuf_VERBOSE)
+ message(STATUS "Protocol Buffers Examples Configuring...")
+endif()
+
+get_filename_component(examples_dir "../examples" ABSOLUTE)
+
+if(protobuf_VERBOSE)
+ message(STATUS "Protocol Buffers Examples Configuring done")
+endif()
+include(ExternalProject)
+
+# Internal utility function: Create a custom target representing a build of examples with custom options.
+function(add_examples_build NAME)
+
+ ExternalProject_Add(${NAME}
+ PREFIX ${NAME}
+ SOURCE_DIR "${examples_dir}"
+ BINARY_DIR ${NAME}
+ STAMP_DIR ${NAME}/logs
+ INSTALL_COMMAND "" #Skip
+ LOG_CONFIGURE 1
+ CMAKE_CACHE_ARGS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
+ "-Dprotobuf_VERBOSE:BOOL=${protobuf_VERBOSE}"
+ ${ARGN}
+ )
+ set_property(TARGET ${NAME} PROPERTY FOLDER "Examples")
+ set_property(TARGET ${NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
+endfunction()
+
+# Add examples as an external project.
+# sub_directory cannot be used because the find_package(protobuf) call would cause failures with redefined targets.
+add_examples_build(examples "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}")
+add_dependencies(examples libprotobuf protoc)
+
+option(protobuf_BUILD_EXAMPLES_MULTITEST "Build Examples in multiple configurations. Useful for testing." OFF)
+mark_as_advanced(protobuf_BUILD_EXAMPLES_MULTITEST)
+if(protobuf_BUILD_EXAMPLES_MULTITEST)
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+ #Build using the legacy compatibility module.
+ add_examples_build(examples-legacy
+ "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}"
+ "-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
+ )
+ add_dependencies(examples-legacy libprotobuf protoc)
+
+ #Build using the installed library.
+ add_examples_build(examples-installed
+ "-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
+ )
+
+ #Build using the installed library in legacy compatibility mode.
+ add_examples_build(examples-installed-legacy
+ "-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
+ "-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
+ )
+endif()
diff --git a/cmake/protobuf-options.cmake b/cmake/protobuf-options.cmake
index 99c85ebe..47fb1582 100644
--- a/cmake/protobuf-options.cmake
+++ b/cmake/protobuf-options.cmake
@@ -1,7 +1,7 @@
-# Verbose output
-option(protobuf_VERBOSE "Enable for verbose output" OFF)
-mark_as_advanced(protobuf_VERBOSE)
-
-# FindProtobuf module compatibel
-option(protobuf_MODULE_COMPATIBLE "CMake build-in FindProtobuf.cmake module compatible" OFF)
-mark_as_advanced(protobuf_MODULE_COMPATIBLE)
+# Verbose output
+option(protobuf_VERBOSE "Enable for verbose output" OFF)
+mark_as_advanced(protobuf_VERBOSE)
+
+# FindProtobuf module compatibel
+option(protobuf_MODULE_COMPATIBLE "CMake build-in FindProtobuf.cmake module compatible" OFF)
+mark_as_advanced(protobuf_MODULE_COMPATIBLE)
diff --git a/configure.ac b/configure.ac
index d858e177..7ae4a88b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,7 +17,7 @@ AC_PREREQ(2.59)
# In the SVN trunk, the version should always be the next anticipated release
# version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed
# the size of one file name in the dist tarfile over the 99-char limit.)
-AC_INIT([Protocol Buffers],[3.0.0-beta-3],[protobuf@googlegroups.com],[protobuf])
+AC_INIT([Protocol Buffers],[3.0.0-beta-4],[protobuf@googlegroups.com],[protobuf])
AM_MAINTAINER_MODE([enable])
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index 78be9c8a..b76407ee 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -84,47 +84,47 @@ other_language_protoc_outputs = \
google/protobuf/wrappers.pb.cc \
google/protobuf/wrappers.pb.h \
google/protobuf/wrappers.rb \
- google/protobuf/wrappers_pb2.py \
- lite/com/google/protobuf/Any.java \
- lite/com/google/protobuf/AnyOrBuilder.java \
- lite/com/google/protobuf/AnyProto.java \
- lite/com/google/protobuf/BoolValue.java \
- lite/com/google/protobuf/BoolValueOrBuilder.java \
- lite/com/google/protobuf/BytesValue.java \
- lite/com/google/protobuf/BytesValueOrBuilder.java \
- lite/com/google/protobuf/conformance/Conformance.java \
- lite/com/google/protobuf/DoubleValue.java \
- lite/com/google/protobuf/DoubleValueOrBuilder.java \
- lite/com/google/protobuf/Duration.java \
- lite/com/google/protobuf/DurationOrBuilder.java \
- lite/com/google/protobuf/DurationProto.java \
- lite/com/google/protobuf/FieldMask.java \
- lite/com/google/protobuf/FieldMaskOrBuilder.java \
- lite/com/google/protobuf/FieldMaskProto.java \
- lite/com/google/protobuf/FloatValue.java \
- lite/com/google/protobuf/FloatValueOrBuilder.java \
- lite/com/google/protobuf/Int32Value.java \
- lite/com/google/protobuf/Int32ValueOrBuilder.java \
- lite/com/google/protobuf/Int64Value.java \
- lite/com/google/protobuf/Int64ValueOrBuilder.java \
- lite/com/google/protobuf/ListValue.java \
- lite/com/google/protobuf/ListValueOrBuilder.java \
- lite/com/google/protobuf/NullValue.java \
- lite/com/google/protobuf/StringValue.java \
- lite/com/google/protobuf/StringValueOrBuilder.java \
- lite/com/google/protobuf/Struct.java \
- lite/com/google/protobuf/StructOrBuilder.java \
- lite/com/google/protobuf/StructProto.java \
- lite/com/google/protobuf/Timestamp.java \
- lite/com/google/protobuf/TimestampOrBuilder.java \
- lite/com/google/protobuf/TimestampProto.java \
- lite/com/google/protobuf/UInt32Value.java \
- lite/com/google/protobuf/UInt32ValueOrBuilder.java \
- lite/com/google/protobuf/UInt64Value.java \
- lite/com/google/protobuf/UInt64ValueOrBuilder.java \
- lite/com/google/protobuf/Value.java \
- lite/com/google/protobuf/ValueOrBuilder.java \
- lite/com/google/protobuf/WrappersProto.java
+ google/protobuf/wrappers_pb2.py
+ # lite/com/google/protobuf/Any.java \
+ # lite/com/google/protobuf/AnyOrBuilder.java \
+ # lite/com/google/protobuf/AnyProto.java \
+ # lite/com/google/protobuf/BoolValue.java \
+ # lite/com/google/protobuf/BoolValueOrBuilder.java \
+ # lite/com/google/protobuf/BytesValue.java \
+ # lite/com/google/protobuf/BytesValueOrBuilder.java \
+ # lite/com/google/protobuf/conformance/Conformance.java \
+ # lite/com/google/protobuf/DoubleValue.java \
+ # lite/com/google/protobuf/DoubleValueOrBuilder.java \
+ # lite/com/google/protobuf/Duration.java \
+ # lite/com/google/protobuf/DurationOrBuilder.java \
+ # lite/com/google/protobuf/DurationProto.java \
+ # lite/com/google/protobuf/FieldMask.java \
+ # lite/com/google/protobuf/FieldMaskOrBuilder.java \
+ # lite/com/google/protobuf/FieldMaskProto.java \
+ # lite/com/google/protobuf/FloatValue.java \
+ # lite/com/google/protobuf/FloatValueOrBuilder.java \
+ # lite/com/google/protobuf/Int32Value.java \
+ # lite/com/google/protobuf/Int32ValueOrBuilder.java \
+ # lite/com/google/protobuf/Int64Value.java \
+ # lite/com/google/protobuf/Int64ValueOrBuilder.java \
+ # lite/com/google/protobuf/ListValue.java \
+ # lite/com/google/protobuf/ListValueOrBuilder.java \
+ # lite/com/google/protobuf/NullValue.java \
+ # lite/com/google/protobuf/StringValue.java \
+ # lite/com/google/protobuf/StringValueOrBuilder.java \
+ # lite/com/google/protobuf/Struct.java \
+ # lite/com/google/protobuf/StructOrBuilder.java \
+ # lite/com/google/protobuf/StructProto.java \
+ # lite/com/google/protobuf/Timestamp.java \
+ # lite/com/google/protobuf/TimestampOrBuilder.java \
+ # lite/com/google/protobuf/TimestampProto.java \
+ # lite/com/google/protobuf/UInt32Value.java \
+ # lite/com/google/protobuf/UInt32ValueOrBuilder.java \
+ # lite/com/google/protobuf/UInt64Value.java \
+ # lite/com/google/protobuf/UInt64ValueOrBuilder.java \
+ # lite/com/google/protobuf/Value.java \
+ # lite/com/google/protobuf/ValueOrBuilder.java \
+ # lite/com/google/protobuf/WrappersProto.java
bin_PROGRAMS = conformance-test-runner conformance-cpp
@@ -192,7 +192,7 @@ if USE_EXTERNAL_PROTOC
protoc_middleman: $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. $(conformance_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. $(well_known_type_protoc_inputs)
- $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
+ ## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
touch protoc_middleman
else
@@ -203,8 +203,8 @@ else
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(conformance_protoc_inputs) )
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd $(well_known_type_protoc_inputs) )
- @mkdir -p lite
- oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) )
+ ## @mkdir -p lite
+ ## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) )
touch protoc_middleman
endif
diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec
index e4240dae..659b2e77 100644
--- a/csharp/Google.Protobuf.Tools.nuspec
+++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -5,7 +5,7 @@
Google Protocol Buffers tools
Tools for Protocol Buffers - Google's data interchange format.
See project site for more info.
- 3.0.0-beta3
+ 3.0.0-beta4
Google Inc.
protobuf-packages
https://github.com/google/protobuf/blob/master/LICENSE
diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
index 7ce75739..83e7928a 100644
--- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
@@ -137,9 +137,9 @@ namespace Google.Protobuf.Reflection {
"dGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdvb2dsZS5wcm90",
"b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFubm90YXRp",
"b24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkSDQoF",
- "YmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQlgKE2NvbS5nb29nbGUucHJvdG9i",
- "dWZCEERlc2NyaXB0b3JQcm90b3NIAVoKZGVzY3JpcHRvcqICA0dQQqoCGkdv",
- "b2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9u"));
+ "YmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQlsKE2NvbS5nb29nbGUucHJvdG9i",
+ "dWZCEERlc2NyaXB0b3JQcm90b3NIAVoKZGVzY3JpcHRvcqABAaICA0dQQqoC",
+ "Gkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9u"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index c9d46885..2cd2acc0 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,63 +1,63 @@
-# Minimum CMake required
-cmake_minimum_required(VERSION 2.8.12)
-
-# Project
-project(protobuf-examples)
-
-# Find required protobuf package
-find_package(protobuf CONFIG REQUIRED)
-
-if(protobuf_VERBOSE)
- message(STATUS "Using Protocol Buffers ${Protobuf_VERSION}")
-endif()
-
-set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
-
-# http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
-if(MSVC AND protobuf_MSVC_STATIC_RUNTIME)
- foreach(flag_var
- CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
- CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
- if(${flag_var} MATCHES "/MD")
- string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
- endif(${flag_var} MATCHES "/MD")
- endforeach()
-endif()
-
-foreach(example add_person list_people)
- set(${example}_SRCS ${example}.cc)
- set(${example}_PROTOS addressbook.proto)
-
- #Code Generation
- if(protobuf_MODULE_COMPATIBLE) #Legacy Support
- protobuf_generate_cpp(${example}_PROTO_SRCS ${example}_PROTO_HDRS ${${example}_PROTOS})
- list(APPEND ${example}_SRCS ${${example}_PROTO_SRCS} ${${example}_PROTO_HDRS})
- else()
-
- foreach(proto_file ${${example}_PROTOS})
- get_filename_component(proto_file_abs ${proto_file} ABSOLUTE)
- get_filename_component(basename ${proto_file} NAME_WE)
- set(generated_files ${basename}.pb.cc ${basename}.pb.h)
- list(APPEND ${example}_SRCS ${generated_files})
-
- add_custom_command(
- OUTPUT ${generated_files}
- COMMAND protobuf::protoc
- ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I ${CMAKE_CURRENT_SOURCE_DIR} ${proto_file_abs}
- COMMENT "Generating ${generated_files} from ${proto_file}"
- VERBATIM
- )
- endforeach()
- endif()
-
- #Executable setup
- set(executable_name ${example}_cpp)
- add_executable(${executable_name} ${${example}_SRCS} ${${example}_PROTOS})
- if(protobuf_MODULE_COMPATIBLE) #Legacy mode
- target_include_directories(${executable_name} PUBLIC ${PROTOBUF_INCLUDE_DIRS})
- target_link_libraries(${executable_name} ${PROTOBUF_LIBRARIES})
- else()
- target_link_libraries(${executable_name} protobuf::libprotobuf)
- endif()
-
-endforeach()
+# Minimum CMake required
+cmake_minimum_required(VERSION 2.8.12)
+
+# Project
+project(protobuf-examples)
+
+# Find required protobuf package
+find_package(protobuf CONFIG REQUIRED)
+
+if(protobuf_VERBOSE)
+ message(STATUS "Using Protocol Buffers ${Protobuf_VERSION}")
+endif()
+
+set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
+
+# http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
+if(MSVC AND protobuf_MSVC_STATIC_RUNTIME)
+ foreach(flag_var
+ CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
+ CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+ if(${flag_var} MATCHES "/MD")
+ string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
+ endif(${flag_var} MATCHES "/MD")
+ endforeach()
+endif()
+
+foreach(example add_person list_people)
+ set(${example}_SRCS ${example}.cc)
+ set(${example}_PROTOS addressbook.proto)
+
+ #Code Generation
+ if(protobuf_MODULE_COMPATIBLE) #Legacy Support
+ protobuf_generate_cpp(${example}_PROTO_SRCS ${example}_PROTO_HDRS ${${example}_PROTOS})
+ list(APPEND ${example}_SRCS ${${example}_PROTO_SRCS} ${${example}_PROTO_HDRS})
+ else()
+
+ foreach(proto_file ${${example}_PROTOS})
+ get_filename_component(proto_file_abs ${proto_file} ABSOLUTE)
+ get_filename_component(basename ${proto_file} NAME_WE)
+ set(generated_files ${basename}.pb.cc ${basename}.pb.h)
+ list(APPEND ${example}_SRCS ${generated_files})
+
+ add_custom_command(
+ OUTPUT ${generated_files}
+ COMMAND protobuf::protoc
+ ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I ${CMAKE_CURRENT_SOURCE_DIR} ${proto_file_abs}
+ COMMENT "Generating ${generated_files} from ${proto_file}"
+ VERBATIM
+ )
+ endforeach()
+ endif()
+
+ #Executable setup
+ set(executable_name ${example}_cpp)
+ add_executable(${executable_name} ${${example}_SRCS} ${${example}_PROTOS})
+ if(protobuf_MODULE_COMPATIBLE) #Legacy mode
+ target_include_directories(${executable_name} PUBLIC ${PROTOBUF_INCLUDE_DIRS})
+ target_link_libraries(${executable_name} ${PROTOBUF_LIBRARIES})
+ else()
+ target_link_libraries(${executable_name} protobuf::libprotobuf)
+ endif()
+
+endforeach()
diff --git a/java/core/pom.xml b/java/core/pom.xml
index 0d4c5c75..422bde82 100644
--- a/java/core/pom.xml
+++ b/java/core/pom.xml
@@ -6,7 +6,7 @@
com.google.protobuf
protobuf-parent
- 3.0.0-beta-3
+ 3.0.0-beta-4
protobuf-java
diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
index 576a350f..e5515285 100644
--- a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
+++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
@@ -144,6 +144,44 @@ public abstract class CodedOutputStream extends ByteOutput {
return new NioEncoder(byteBuffer);
}
+ /**
+ * Configures serialization to be deterministic.
+ *
+ * The deterministic serialization guarantees that for a given binary, equal (defined by the
+ * {@code equals()} methods in protos) messages will always be serialized to the same bytes. This
+ * implies:
+ *
+ *
+ * - repeated serialization of a message will return the same bytes
+ *
- different processes of the same binary (which may be executing on different machines) will
+ * serialize equal messages to the same bytes.
+ *
+ *
+ * Note the deterministic serialization is NOT canonical across languages; it is also unstable
+ * across different builds with schema changes due to unknown fields. Users who need canonical
+ * serialization, e.g. persistent storage in a canonical form, fingerprinting, etc, should define
+ * their own canonicalization specification and implement the serializer using reflection APIs
+ * rather than relying on this API.
+ *
+ *
Once set, the serializer will: (Note this is an implementation detail and may subject to
+ * change in the future)
+ *
+ *
+ * - sort map entries by keys in lexicographical order or numerical order. Note: For string
+ * keys, the order is based on comparing the Unicode value of each character in the strings.
+ * The order may be different from the deterministic serialization in other languages where
+ * maps are sorted on the lexicographical order of the UTF8 encoded keys.
+ *
+ */
+ void useDeterministicSerialization() {
+ serializationDeterministic = true;
+ }
+
+ boolean isSerializationDeterministic() {
+ return serializationDeterministic;
+ }
+ private boolean serializationDeterministic;
+
/**
* Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}.
*
diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
index 859a9e8f..c54da67f 100644
--- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -526,6 +526,14 @@ public final class DynamicMessage extends AbstractMessage {
fields.clearField(oldField);
}
oneofCases[index] = field;
+ } else if (field.getFile().getSyntax() == Descriptors.FileDescriptor.Syntax.PROTO3) {
+ if (!field.isRepeated()
+ && field.getJavaType() != FieldDescriptor.JavaType.MESSAGE
+ && value.equals(field.getDefaultValue())) {
+ // In proto3, setting a field to its default value is equivalent to clearing the field.
+ fields.clearField(field);
+ return this;
+ }
}
fields.setField(field, value);
return this;
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 2c87302b..cea05794 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -1396,7 +1396,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return setExtension((ExtensionLite) extension, value);
}
/** Set the value of an extension. */
- public final BuilderType setExtension(
+ public BuilderType setExtension(
final GeneratedExtension extension, final Type value) {
return setExtension((ExtensionLite) extension, value);
}
@@ -1407,7 +1407,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return setExtension((ExtensionLite>) extension, index, value);
}
/** Set the value of one element of a repeated extension. */
- public final BuilderType setExtension(
+ public BuilderType setExtension(
final GeneratedExtension> extension,
final int index, final Type value) {
return setExtension((ExtensionLite>) extension, index, value);
@@ -1418,7 +1418,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return addExtension((ExtensionLite>) extension, value);
}
/** Append a value to a repeated extension. */
- public final BuilderType addExtension(
+ public BuilderType addExtension(
final GeneratedExtension> extension, final Type value) {
return addExtension((ExtensionLite>) extension, value);
}
@@ -1428,7 +1428,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return clearExtension((ExtensionLite) extension);
}
/** Clear an extension. */
- public final BuilderType clearExtension(
+ public BuilderType clearExtension(
final GeneratedExtension extension) {
return clearExtension((ExtensionLite) extension);
}
diff --git a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
index 82f4216b..4a42c897 100644
--- a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
+++ b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
@@ -31,6 +31,8 @@
package com.google.protobuf;
import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.FieldPresenceTestProto.TestAllTypes;
import com.google.protobuf.FieldPresenceTestProto.TestOptionalFieldsOnly;
@@ -253,6 +255,54 @@ public class FieldPresenceTest extends TestCase {
assertEquals(4, message.getAllFields().size());
}
+ public void testFieldPresenceDynamicMessage() {
+ Descriptor descriptor = TestAllTypes.getDescriptor();
+ FieldDescriptor optionalInt32Field = descriptor.findFieldByName("optional_int32");
+ FieldDescriptor optionalStringField = descriptor.findFieldByName("optional_string");
+ FieldDescriptor optionalBytesField = descriptor.findFieldByName("optional_bytes");
+ FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum");
+ EnumDescriptor enumDescriptor = optionalNestedEnumField.getEnumType();
+ EnumValueDescriptor defaultEnumValueDescriptor = enumDescriptor.getValues().get(0);
+ EnumValueDescriptor nonDefaultEnumValueDescriptor = enumDescriptor.getValues().get(1);
+
+ DynamicMessage defaultInstance = DynamicMessage.getDefaultInstance(descriptor);
+ // Field not present.
+ DynamicMessage message = defaultInstance.newBuilderForType().build();
+ assertFalse(message.hasField(optionalInt32Field));
+ assertFalse(message.hasField(optionalStringField));
+ assertFalse(message.hasField(optionalBytesField));
+ assertFalse(message.hasField(optionalNestedEnumField));
+ assertEquals(0, message.getAllFields().size());
+
+ // Field set to non-default value is seen as present.
+ message =
+ defaultInstance
+ .newBuilderForType()
+ .setField(optionalInt32Field, 1)
+ .setField(optionalStringField, "x")
+ .setField(optionalBytesField, ByteString.copyFromUtf8("y"))
+ .setField(optionalNestedEnumField, nonDefaultEnumValueDescriptor)
+ .build();
+ assertTrue(message.hasField(optionalInt32Field));
+ assertTrue(message.hasField(optionalStringField));
+ assertTrue(message.hasField(optionalBytesField));
+ assertTrue(message.hasField(optionalNestedEnumField));
+ assertEquals(4, message.getAllFields().size());
+
+ // Field set to default value is seen as not present.
+ message = message.toBuilder()
+ .setField(optionalInt32Field, 0)
+ .setField(optionalStringField, "")
+ .setField(optionalBytesField, ByteString.EMPTY)
+ .setField(optionalNestedEnumField, defaultEnumValueDescriptor)
+ .build();
+ assertFalse(message.hasField(optionalInt32Field));
+ assertFalse(message.hasField(optionalStringField));
+ assertFalse(message.hasField(optionalBytesField));
+ assertFalse(message.hasField(optionalNestedEnumField));
+ assertEquals(0, message.getAllFields().size());
+ }
+
public void testMessageField() {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
assertFalse(builder.hasOptionalNestedMessage());
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 0f42ac50..497c4df2 100644
--- a/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
@@ -35,6 +35,7 @@ import static java.util.Arrays.asList;
import junit.framework.TestCase;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
@@ -233,7 +234,7 @@ public class LazyStringArrayListTest extends TestCase {
}
try {
- list.addAllByteArray(asList(BYTE_STRING_A.toByteArray()));
+ list.addAllByteArray(Collections.singletonList(BYTE_STRING_A.toByteArray()));
fail();
} catch (UnsupportedOperationException e) {
// expected
diff --git a/java/lite/pom.xml b/java/lite/pom.xml
index c403dc09..87a5c44d 100644
--- a/java/lite/pom.xml
+++ b/java/lite/pom.xml
@@ -6,7 +6,7 @@
com.google.protobuf
protobuf-parent
- 3.0.0-beta-3
+ 3.0.0-beta-4
protobuf-lite
diff --git a/java/pom.xml b/java/pom.xml
index 7a1a91f8..2d7161b2 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -11,7 +11,7 @@
com.google.protobuf
protobuf-parent
- 3.0.0-beta-3
+ 3.0.0-beta-4
pom
Protocol Buffers [Parent]
@@ -182,7 +182,7 @@
core
- lite
+
util
diff --git a/java/util/pom.xml b/java/util/pom.xml
index 9236f907..d8f64eb1 100644
--- a/java/util/pom.xml
+++ b/java/util/pom.xml
@@ -6,7 +6,7 @@
com.google.protobuf
protobuf-parent
- 3.0.0-beta-3
+ 3.0.0-beta-4
protobuf-java-util
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 297545e5..ad50cc0e 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
@@ -116,7 +116,8 @@ public class JsonFormat {
private Printer(
TypeRegistry registry,
boolean includingDefaultValueFields,
- boolean preservingProtoFieldNames, boolean omittingInsignificantWhitespace) {
+ boolean preservingProtoFieldNames,
+ boolean omittingInsignificantWhitespace) {
this.registry = registry;
this.includingDefaultValueFields = includingDefaultValueFields;
this.preservingProtoFieldNames = preservingProtoFieldNames;
@@ -133,7 +134,11 @@ public class JsonFormat {
if (this.registry != TypeRegistry.getEmptyTypeRegistry()) {
throw new IllegalArgumentException("Only one registry is allowed.");
}
- return new Printer(registry, includingDefaultValueFields, preservingProtoFieldNames, omittingInsignificantWhitespace);
+ return new Printer(
+ registry,
+ includingDefaultValueFields,
+ preservingProtoFieldNames,
+ omittingInsignificantWhitespace);
}
/**
@@ -143,7 +148,8 @@ public class JsonFormat {
* {@link Printer}.
*/
public Printer includingDefaultValueFields() {
- return new Printer(registry, true, preservingProtoFieldNames, omittingInsignificantWhitespace);
+ return new Printer(
+ registry, true, preservingProtoFieldNames, omittingInsignificantWhitespace);
}
/**
@@ -153,7 +159,8 @@ public class JsonFormat {
* current {@link Printer}.
*/
public Printer preservingProtoFieldNames() {
- return new Printer(registry, includingDefaultValueFields, true, omittingInsignificantWhitespace);
+ return new Printer(
+ registry, includingDefaultValueFields, true, omittingInsignificantWhitespace);
}
@@ -172,7 +179,7 @@ public class JsonFormat {
* See https://tools.ietf.org/html/rfc7159
* current {@link Printer}.
*/
- public Printer omittingInsignificantWhitespace(){
+ public Printer omittingInsignificantWhitespace() {
return new Printer(registry, includingDefaultValueFields, preservingProtoFieldNames, true);
}
@@ -186,7 +193,12 @@ public class JsonFormat {
public void appendTo(MessageOrBuilder message, Appendable output) throws IOException {
// TODO(xiaofeng): Investigate the allocation overhead and optimize for
// mobile.
- new PrinterImpl(registry, includingDefaultValueFields, preservingProtoFieldNames, output, omittingInsignificantWhitespace)
+ new PrinterImpl(
+ registry,
+ includingDefaultValueFields,
+ preservingProtoFieldNames,
+ output,
+ omittingInsignificantWhitespace)
.print(message);
}
@@ -379,18 +391,18 @@ public class JsonFormat {
*/
interface TextGenerator {
void indent();
+
void outdent();
+
void print(final CharSequence text) throws IOException;
}
-
/**
* Format the json without indentation
*/
- private static final class CompactTextGenerator implements TextGenerator{
+ private static final class CompactTextGenerator implements TextGenerator {
private final Appendable output;
-
private CompactTextGenerator(final Appendable output) {
this.output = output;
}
@@ -411,12 +423,11 @@ public class JsonFormat {
public void print(final CharSequence text) throws IOException {
output.append(text);
}
-
}
/**
* A TextGenerator adds indentation when writing formatted text.
*/
- private static final class PrettyTextGenerator implements TextGenerator{
+ private static final class PrettyTextGenerator implements TextGenerator {
private final Appendable output;
private final StringBuilder indent = new StringBuilder();
private boolean atStartOfLine = true;
@@ -496,7 +507,8 @@ public class JsonFormat {
TypeRegistry registry,
boolean includingDefaultValueFields,
boolean preservingProtoFieldNames,
- Appendable jsonOutput, boolean omittingInsignificantWhitespace) {
+ Appendable jsonOutput,
+ boolean omittingInsignificantWhitespace) {
this.registry = registry;
this.includingDefaultValueFields = includingDefaultValueFields;
this.preservingProtoFieldNames = preservingProtoFieldNames;
@@ -734,9 +746,7 @@ public class JsonFormat {
}
/** Prints a regular message with an optional type URL. */
-
- private void print(MessageOrBuilder message, String typeUrl)
- throws IOException {
+ private void print(MessageOrBuilder message, String typeUrl) throws IOException {
generator.print("{" + blankOrNewLine);
generator.indent();
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 e68c7be1..6fc784ef 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
@@ -140,7 +140,7 @@ public class JsonFormatTest extends TestCase {
private String toJsonString(Message message) throws IOException {
return JsonFormat.printer().print(message);
}
- private String toCompactJsonString(Message message) throws IOException{
+ private String toCompactJsonString(Message message) throws IOException {
return JsonFormat.printer().omittingInsignificantWhitespace().print(message);
}
@@ -1172,7 +1172,9 @@ public class JsonFormatTest extends TestCase {
public void testOmittingInsignificantWhiteSpace() throws Exception {
TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build();
- assertEquals("{" + "\"optionalInt32\":12345" + "}", JsonFormat.printer().omittingInsignificantWhitespace().print(message));
+ assertEquals(
+ "{" + "\"optionalInt32\":12345" + "}",
+ JsonFormat.printer().omittingInsignificantWhitespace().print(message));
TestAllTypes message1 = TestAllTypes.getDefaultInstance();
assertEquals("{}", JsonFormat.printer().omittingInsignificantWhitespace().print(message1));
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
@@ -1224,4 +1226,20 @@ public class JsonFormatTest extends TestCase {
toCompactJsonString(message2));
}
+ // Regression test for b/29892357
+ public void testEmptyWrapperTypesInAny() throws Exception {
+ JsonFormat.TypeRegistry registry =
+ JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build();
+ JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(registry);
+
+ Any.Builder builder = Any.newBuilder();
+ parser.merge(
+ "{\n"
+ + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n"
+ + " \"value\": false\n"
+ + "}\n",
+ builder);
+ Any any = builder.build();
+ assertEquals(0, any.getValue().size());
+ }
}
diff --git a/javanano/pom.xml b/javanano/pom.xml
index a2eca09d..e6a03d15 100644
--- a/javanano/pom.xml
+++ b/javanano/pom.xml
@@ -10,7 +10,7 @@
com.google.protobuf.nano
protobuf-javanano
- 3.0.0-alpha-6
+ 3.0.0-alpha-7
bundle
Protocol Buffer JavaNano API
@@ -165,7 +165,7 @@
https://developers.google.com/protocol-buffers/
com.google.protobuf
- com.google.protobuf;version=3.0.0-alpha-5
+ com.google.protobuf;version=3.0.0-alpha-7
diff --git a/js/message_test.js b/js/message_test.js
index 0b0c0172..11792423 100644
--- a/js/message_test.js
+++ b/js/message_test.js
@@ -215,6 +215,10 @@ describe('Message test suite', function() {
assertEquals(true, response.getBoolField());
assertEquals(11, response.getIntField());
assertEquals(13, response.getEnumField());
+ assertFalse(response.hasStringField());
+ assertFalse(response.hasBoolField());
+ assertFalse(response.hasIntField());
+ assertFalse(response.hasEnumField());
// Test with null values, as would be returned by a JSON serializer.
response = makeDefault([null, null, null, null]);
@@ -222,6 +226,10 @@ describe('Message test suite', function() {
assertEquals(true, response.getBoolField());
assertEquals(11, response.getIntField());
assertEquals(13, response.getEnumField());
+ assertFalse(response.hasStringField());
+ assertFalse(response.hasBoolField());
+ assertFalse(response.hasIntField());
+ assertFalse(response.hasEnumField());
// Test with false-like values.
response = makeDefault(['', false, 0, 0]);
@@ -229,6 +237,10 @@ describe('Message test suite', function() {
assertEquals(false, response.getBoolField());
assertEquals(true, response.getIntField() == 0);
assertEquals(true, response.getEnumField() == 0);
+ assertTrue(response.hasStringField());
+ assertTrue(response.hasBoolField());
+ assertTrue(response.hasIntField());
+ assertTrue(response.hasEnumField());
// Test that clearing the values reverts them to the default state.
response = makeDefault(['blah', false, 111, 77]);
@@ -238,6 +250,10 @@ describe('Message test suite', function() {
assertEquals(true, response.getBoolField());
assertEquals(11, response.getIntField());
assertEquals(13, response.getEnumField());
+ assertFalse(response.hasStringField());
+ assertFalse(response.hasBoolField());
+ assertFalse(response.hasIntField());
+ assertFalse(response.hasEnumField());
// Test that setFoo(null) clears the values.
response = makeDefault(['blah', false, 111, 77]);
@@ -247,6 +263,10 @@ describe('Message test suite', function() {
assertEquals(true, response.getBoolField());
assertEquals(11, response.getIntField());
assertEquals(13, response.getEnumField());
+ assertFalse(response.hasStringField());
+ assertFalse(response.hasBoolField());
+ assertFalse(response.hasIntField());
+ assertFalse(response.hasEnumField());
});
it('testMessageRegistration', function() {
@@ -269,6 +289,8 @@ describe('Message test suite', function() {
assertUndefined(foo.getAString());
assertUndefined(foo.getABool());
assertUndefined(foo.getANestedMessage());
+ assertFalse(foo.hasAString());
+ assertFalse(foo.hasABool());
assertObjectEquals([], foo.getARepeatedMessageList());
assertObjectEquals([], foo.getARepeatedStringList());
// NOTE: We want the missing fields in 'expected' to be undefined,
@@ -291,6 +313,8 @@ describe('Message test suite', function() {
assertNull(foo.getAString());
assertNull(foo.getABool());
assertNull(foo.getANestedMessage());
+ assertFalse(foo.hasAString());
+ assertFalse(foo.hasABool());
assertObjectEquals([], foo.getARepeatedMessageList());
assertObjectEquals([], foo.getARepeatedStringList());
assertObjectEquals([null, null, null, [], []], foo.toArray());
@@ -307,6 +331,8 @@ describe('Message test suite', function() {
assertUndefined(foo.getAString());
assertUndefined(foo.getABool());
assertUndefined(foo.getANestedMessage());
+ assertFalse(foo.hasAString());
+ assertFalse(foo.hasABool());
assertObjectEquals([], foo.getARepeatedMessageList());
assertObjectEquals([], foo.getARepeatedStringList());
expected = [,,, [], []];
@@ -800,14 +826,20 @@ describe('Message test suite', function() {
var message = new proto.jspb.test.TestMessageWithOneof;
assertUndefined(message.getPone());
assertUndefined(message.getPthree());
+ assertFalse(message.hasPone());
+ assertFalse(message.hasPthree());
message.setPone('hi');
assertEquals('hi', message.getPone());
assertUndefined(message.getPthree());
+ assertTrue(message.hasPone());
+ assertFalse(message.hasPthree());
message.setPthree('bye');
assertUndefined(message.getPone());
assertEquals('bye', message.getPthree());
+ assertFalse(message.hasPone());
+ assertTrue(message.hasPthree());
});
it('testSettingOneofFieldDoesNotClearFieldsFromOtherUnions', function() {
@@ -816,17 +848,23 @@ describe('Message test suite', function() {
assertUndefined(message.getPone());
assertUndefined(message.getPthree());
assertUndefined(message.getRone());
+ assertFalse(message.hasPone());
+ assertFalse(message.hasPthree());
message.setPone('hi');
message.setRone(other);
assertEquals('hi', message.getPone());
assertUndefined(message.getPthree());
assertEquals(other, message.getRone());
+ assertTrue(message.hasPone());
+ assertFalse(message.hasPthree());
message.setPthree('bye');
assertUndefined(message.getPone());
assertEquals('bye', message.getPthree());
assertEquals(other, message.getRone());
+ assertFalse(message.hasPone());
+ assertTrue(message.hasPthree());
});
it('testUnsetsOneofCaseWhenFieldIsCleared', function() {
@@ -884,6 +922,8 @@ describe('Message test suite', function() {
var message = new proto.jspb.test.TestMessageWithOneof;
assertUndefined(message.getBone());
assertEquals(1234, message.getBtwo());
+ assertFalse(message.hasBone());
+ assertFalse(message.hasBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase
.DEFAULT_ONEOF_B_NOT_SET,
@@ -892,12 +932,16 @@ describe('Message test suite', function() {
message.setBone(2);
assertEquals(2, message.getBone());
assertEquals(1234, message.getBtwo());
+ assertTrue(message.hasBone());
+ assertFalse(message.hasBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
message.getDefaultOneofBCase());
message.setBtwo(3);
assertUndefined(message.getBone());
+ assertFalse(message.hasBone());
+ assertTrue(message.hasBtwo());
assertEquals(3, message.getBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
@@ -905,6 +949,8 @@ describe('Message test suite', function() {
message.clearBtwo();
assertUndefined(message.getBone());
+ assertFalse(message.hasBone());
+ assertFalse(message.hasBtwo());
assertEquals(1234, message.getBtwo());
assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase
diff --git a/js/package.json b/js/package.json
index 657b08bd..76ce0c1d 100644
--- a/js/package.json
+++ b/js/package.json
@@ -1,6 +1,6 @@
{
"name": "google-protobuf",
- "version": "3.0.0-alpha.6.2",
+ "version": "3.0.0-alpha.7",
"description": "Protocol Buffers for JavaScript",
"main": "google-protobuf.js",
"files": [
diff --git a/js/proto3_test.js b/js/proto3_test.js
index 4dd7790f..7f76006a 100644
--- a/js/proto3_test.js
+++ b/js/proto3_test.js
@@ -225,12 +225,18 @@ describe('proto3Test', function() {
assertEquals(msg.getOneofForeignMessage(), undefined);
assertEquals(msg.getOneofString(), undefined);
assertEquals(msg.getOneofBytes(), undefined);
+ assertFalse(msg.hasOneofUint32());
+ assertFalse(msg.hasOneofString());
+ assertFalse(msg.hasOneofBytes());
msg.setOneofUint32(42);
assertEquals(msg.getOneofUint32(), 42);
assertEquals(msg.getOneofForeignMessage(), undefined);
assertEquals(msg.getOneofString(), undefined);
assertEquals(msg.getOneofBytes(), undefined);
+ assertTrue(msg.hasOneofUint32());
+ assertFalse(msg.hasOneofString());
+ assertFalse(msg.hasOneofBytes());
var submsg = new proto.jspb.test.ForeignMessage();
@@ -239,12 +245,18 @@ describe('proto3Test', function() {
assertEquals(msg.getOneofForeignMessage(), submsg);
assertEquals(msg.getOneofString(), undefined);
assertEquals(msg.getOneofBytes(), undefined);
+ assertFalse(msg.hasOneofUint32());
+ assertFalse(msg.hasOneofString());
+ assertFalse(msg.hasOneofBytes());
msg.setOneofString('hello');
assertEquals(msg.getOneofUint32(), undefined);
assertEquals(msg.getOneofForeignMessage(), undefined);
assertEquals(msg.getOneofString(), 'hello');
assertEquals(msg.getOneofBytes(), undefined);
+ assertFalse(msg.hasOneofUint32());
+ assertTrue(msg.hasOneofString());
+ assertFalse(msg.hasOneofBytes());
msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
assertEquals(msg.getOneofUint32(), undefined);
@@ -252,6 +264,9 @@ describe('proto3Test', function() {
assertEquals(msg.getOneofString(), undefined);
assertEquals(msg.getOneofBytes_asB64(),
goog.crypt.base64.encodeString('\u00FF\u00FF'));
+ assertFalse(msg.hasOneofUint32());
+ assertFalse(msg.hasOneofString());
+ assertTrue(msg.hasOneofBytes());
});
diff --git a/js/test.proto b/js/test.proto
index cf2eafef..937ffb89 100644
--- a/js/test.proto
+++ b/js/test.proto
@@ -233,3 +233,4 @@ message TestEndsWithBytes {
optional int32 value = 1;
optional bytes data = 2;
}
+
diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml
index 50866041..8fad896a 100644
--- a/protoc-artifacts/pom.xml
+++ b/protoc-artifacts/pom.xml
@@ -10,7 +10,7 @@
com.google.protobuf
protoc
- 3.0.0-beta-3
+ 3.0.0-beta-4
pom
Protobuf Compiler
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
index 2a3c6771..7213496e 100755
--- a/python/google/protobuf/__init__.py
+++ b/python/google/protobuf/__init__.py
@@ -30,7 +30,7 @@
# Copyright 2007 Google Inc. All Rights Reserved.
-__version__ = '3.0.0b3'
+__version__ = '3.0.0b4'
if __name__ != '__main__':
try:
diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py
index 6df12bea..a5ee8ace 100644
--- a/python/google/protobuf/internal/json_format_test.py
+++ b/python/google/protobuf/internal/json_format_test.py
@@ -252,10 +252,7 @@ class JsonFormatTest(JsonFormatBase):
message = json_format_proto3_pb2.TestMessage()
json_format.Parse('{"stringValue": "\\uD83D\\uDE01"}', message)
self.assertEqual(message.string_value,
- b'\xF0\x9F\x98\x81'.decode("utf-8", "strict"))
-
- # TODO: add test that UTF-8 encoded surrogate code points are rejected.
- # UTF-8 does not allow them.
+ b'\xF0\x9F\x98\x81'.decode('utf-8', 'strict'))
# Error case: unpaired high surrogate.
self.CheckError(
@@ -267,7 +264,6 @@ class JsonFormatTest(JsonFormatBase):
'{"stringValue": "\\uDE01"}',
r'Invalid \\uXXXX escape|Unpaired.*surrogate')
-
def testTimestampMessage(self):
message = json_format_proto3_pb2.TestTimestamp()
message.value.seconds = 0
diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py
index f8f73dd2..c0d0ad45 100755
--- a/python/google/protobuf/internal/python_message.py
+++ b/python/google/protobuf/internal/python_message.py
@@ -76,7 +76,6 @@ from google.protobuf.internal import well_known_types
from google.protobuf.internal import wire_format
from google.protobuf import descriptor as descriptor_mod
from google.protobuf import message as message_mod
-from google.protobuf import symbol_database
from google.protobuf import text_format
_FieldDescriptor = descriptor_mod.FieldDescriptor
@@ -98,16 +97,12 @@ class GeneratedProtocolMessageType(type):
classes at runtime, as in this example:
mydescriptor = Descriptor(.....)
- class MyProtoClass(Message):
- __metaclass__ = GeneratedProtocolMessageType
- DESCRIPTOR = mydescriptor
+ factory = symbol_database.Default()
+ factory.pool.AddDescriptor(mydescriptor)
+ MyProtoClass = factory.GetPrototype(mydescriptor)
myproto_instance = MyProtoClass()
myproto.foo_field = 23
...
-
- The above example will not work for nested types. If you wish to include them,
- use reflection.MakeClass() instead of manually instantiating the class in
- order to create the appropriate class structure.
"""
# Must be consistent with the protocol-compiler code in
@@ -926,26 +921,33 @@ def _InternalUnpackAny(msg):
Returns:
The unpacked message.
"""
+ # TODO(amauryfa): Don't use the factory of generated messages.
+ # To make Any work with custom factories, use the message factory of the
+ # parent message.
+ # pylint: disable=g-import-not-at-top
+ from google.protobuf import symbol_database
+ factory = symbol_database.Default()
+
type_url = msg.type_url
- db = symbol_database.Default()
if not type_url:
return None
# TODO(haberman): For now we just strip the hostname. Better logic will be
# required.
- type_name = type_url.split("/")[-1]
- descriptor = db.pool.FindMessageTypeByName(type_name)
+ type_name = type_url.split('/')[-1]
+ descriptor = factory.pool.FindMessageTypeByName(type_name)
if descriptor is None:
return None
- message_class = db.GetPrototype(descriptor)
+ message_class = factory.GetPrototype(descriptor)
message = message_class()
message.ParseFromString(msg.value)
return message
+
def _AddEqualsMethod(message_descriptor, cls):
"""Helper for _AddMessageMethods()."""
def __eq__(self, other):
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 6dc2fffe..20e5d245 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -972,6 +972,7 @@ class ReflectionTest(unittest.TestCase):
proto.repeated_nested_message.add(bb=23)
self.assertEqual(1, len(proto.repeated_nested_message))
self.assertEqual(23, proto.repeated_nested_message[0].bb)
+ self.assertRaises(TypeError, proto.repeated_nested_message.add, 23)
def testRepeatedCompositeRemove(self):
proto = unittest_pb2.TestAllTypes()
diff --git a/python/google/protobuf/internal/symbol_database_test.py b/python/google/protobuf/internal/symbol_database_test.py
index c99b426d..4f5173b2 100644
--- a/python/google/protobuf/internal/symbol_database_test.py
+++ b/python/google/protobuf/internal/symbol_database_test.py
@@ -39,26 +39,28 @@ except ImportError:
from google.protobuf import unittest_pb2
from google.protobuf import descriptor
+from google.protobuf import descriptor_pool
from google.protobuf import symbol_database
+
class SymbolDatabaseTest(unittest.TestCase):
def _Database(self):
- # TODO(b/17734095): Remove this difference when the C++ implementation
- # supports multiple databases.
if descriptor._USE_C_DESCRIPTORS:
- return symbol_database.Default()
+ # The C++ implementation does not allow mixing descriptors from
+ # different pools.
+ db = symbol_database.SymbolDatabase(pool=descriptor_pool.Default())
else:
db = symbol_database.SymbolDatabase()
- # Register representative types from unittest_pb2.
- db.RegisterFileDescriptor(unittest_pb2.DESCRIPTOR)
- db.RegisterMessage(unittest_pb2.TestAllTypes)
- db.RegisterMessage(unittest_pb2.TestAllTypes.NestedMessage)
- db.RegisterMessage(unittest_pb2.TestAllTypes.OptionalGroup)
- db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup)
- db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
- db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
- return db
+ # Register representative types from unittest_pb2.
+ db.RegisterFileDescriptor(unittest_pb2.DESCRIPTOR)
+ db.RegisterMessage(unittest_pb2.TestAllTypes)
+ db.RegisterMessage(unittest_pb2.TestAllTypes.NestedMessage)
+ db.RegisterMessage(unittest_pb2.TestAllTypes.OptionalGroup)
+ db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup)
+ db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
+ db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
+ return db
def testGetPrototype(self):
instance = self._Database().GetPrototype(
diff --git a/python/google/protobuf/pyext/cpp_message.py b/python/google/protobuf/pyext/cpp_message.py
index b215211e..fc8eb32d 100644
--- a/python/google/protobuf/pyext/cpp_message.py
+++ b/python/google/protobuf/pyext/cpp_message.py
@@ -48,9 +48,9 @@ class GeneratedProtocolMessageType(_message.MessageMeta):
classes at runtime, as in this example:
mydescriptor = Descriptor(.....)
- class MyProtoClass(Message):
- __metaclass__ = GeneratedProtocolMessageType
- DESCRIPTOR = mydescriptor
+ factory = symbol_database.Default()
+ factory.pool.AddDescriptor(mydescriptor)
+ MyProtoClass = factory.GetPrototype(mydescriptor)
myproto_instance = MyProtoClass()
myproto.foo_field = 23
...
diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc
index 90438df1..0987b898 100644
--- a/python/google/protobuf/pyext/map_container.cc
+++ b/python/google/protobuf/pyext/map_container.cc
@@ -348,9 +348,10 @@ PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) {
}
// Initializes the underlying Message object of "to" so it becomes a new parent
-// repeated scalar, and copies all the values from "from" to it. A child scalar
+// map container, and copies all the values from "from" to it. A child map
// container can be released by passing it as both from and to (e.g. making it
// the recipient of the new parent message and copying the values from itself).
+// In fact, this is the only supported use at the moment.
static int InitializeAndCopyToParentContainer(MapContainer* from,
MapContainer* to) {
// For now we require from == to, re-evaluate if we want to support deep copy
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index a9261f20..5535338d 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -1041,7 +1041,12 @@ int InternalDeleteRepeatedField(
}
// Initializes fields of a message. Used in constructors.
-int InitAttributes(CMessage* self, PyObject* kwargs) {
+int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) {
+ if (args != NULL && PyTuple_Size(args) != 0) {
+ PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
+ return -1;
+ }
+
if (kwargs == NULL) {
return 0;
}
@@ -1167,7 +1172,7 @@ int InitAttributes(CMessage* self, PyObject* kwargs) {
}
CMessage* cmessage = reinterpret_cast(message.get());
if (PyDict_Check(value)) {
- if (InitAttributes(cmessage, value) < 0) {
+ if (InitAttributes(cmessage, NULL, value) < 0) {
return -1;
}
} else {
@@ -1245,12 +1250,7 @@ static PyObject* New(PyTypeObject* cls,
// The __init__ method of Message classes.
// It initializes fields from keywords passed to the constructor.
static int Init(CMessage* self, PyObject* args, PyObject* kwargs) {
- if (PyTuple_Size(args) != 0) {
- PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
- return -1;
- }
-
- return InitAttributes(self, kwargs);
+ return InitAttributes(self, args, kwargs);
}
// ---------------------------------------------------------------------
diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h
index 8b399e05..c44a2ae2 100644
--- a/python/google/protobuf/pyext/message.h
+++ b/python/google/protobuf/pyext/message.h
@@ -237,7 +237,9 @@ PyObject* HasFieldByDescriptor(
PyObject* HasField(CMessage* self, PyObject* arg);
// Initializes values of fields on a newly constructed message.
-int InitAttributes(CMessage* self, PyObject* kwargs);
+// Note that positional arguments are disallowed: 'args' must be NULL or the
+// empty tuple.
+int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs);
PyObject* MergeFrom(CMessage* self, PyObject* arg);
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
index 4f339e77..bb2f6db2 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -146,7 +146,7 @@ static PyObject* AddToAttached(RepeatedCompositeContainer* self,
cmsg->owner = self->owner;
cmsg->message = sub_message;
cmsg->parent = self->parent;
- if (cmessage::InitAttributes(cmsg, kwargs) < 0) {
+ if (cmessage::InitAttributes(cmsg, args, kwargs) < 0) {
Py_DECREF(cmsg);
return NULL;
}
@@ -166,7 +166,7 @@ static PyObject* AddToReleased(RepeatedCompositeContainer* self,
// Create a new Message detached from the rest.
PyObject* py_cmsg = PyEval_CallObjectWithKeywords(
- self->child_message_class->AsPyObject(), NULL, kwargs);
+ self->child_message_class->AsPyObject(), args, kwargs);
if (py_cmsg == NULL)
return NULL;
diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py
index 0c757264..51c83321 100755
--- a/python/google/protobuf/reflection.py
+++ b/python/google/protobuf/reflection.py
@@ -58,13 +58,7 @@ else:
from google.protobuf.internal import python_message as message_impl
# The type of all Message classes.
-# Part of the public interface.
-#
-# Used by generated files, but clients can also use it at runtime:
-# mydescriptor = pool.FindDescriptor(.....)
-# class MyProtoClass(Message):
-# __metaclass__ = GeneratedProtocolMessageType
-# DESCRIPTOR = mydescriptor
+# Part of the public interface, but normally only used by message factories.
GeneratedProtocolMessageType = message_impl.GeneratedProtocolMessageType
diff --git a/python/google/protobuf/symbol_database.py b/python/google/protobuf/symbol_database.py
index 87760f26..aa466abd 100644
--- a/python/google/protobuf/symbol_database.py
+++ b/python/google/protobuf/symbol_database.py
@@ -30,11 +30,9 @@
"""A database of Python protocol buffer generated symbols.
-SymbolDatabase makes it easy to create new instances of a registered type, given
-only the type's protocol buffer symbol name. Once all symbols are registered,
-they can be accessed using either the MessageFactory interface which
-SymbolDatabase exposes, or the DescriptorPool interface of the underlying
-pool.
+SymbolDatabase is the MessageFactory for messages generated at compile time,
+and makes it easy to create new instances of a registered type, given only the
+type's protocol buffer symbol name.
Example usage:
@@ -61,27 +59,17 @@ Example usage:
from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
-class SymbolDatabase(object):
- """A database of Python generated symbols.
-
- SymbolDatabase also models message_factory.MessageFactory.
-
- The symbol database can be used to keep a global registry of all protocol
- buffer types used within a program.
- """
-
- def __init__(self, pool=None):
- """Constructor."""
-
- self._symbols = {}
- self._symbols_by_file = {}
- self.pool = pool or descriptor_pool.Default()
+class SymbolDatabase(message_factory.MessageFactory):
+ """A database of Python generated symbols."""
def RegisterMessage(self, message):
"""Registers the given message type in the local database.
+ Calls to GetSymbol() and GetMessages() will return messages registered here.
+
Args:
message: a message.Message, to be registered.
@@ -90,10 +78,7 @@ class SymbolDatabase(object):
"""
desc = message.DESCRIPTOR
- self._symbols[desc.full_name] = message
- if desc.file.name not in self._symbols_by_file:
- self._symbols_by_file[desc.file.name] = {}
- self._symbols_by_file[desc.file.name][desc.full_name] = message
+ self._classes[desc.full_name] = message
self.pool.AddDescriptor(desc)
return message
@@ -136,47 +121,46 @@ class SymbolDatabase(object):
KeyError: if the symbol could not be found.
"""
- return self._symbols[symbol]
-
- def GetPrototype(self, descriptor):
- """Builds a proto2 message class based on the passed in descriptor.
-
- Passing a descriptor with a fully qualified name matching a previous
- invocation will cause the same class to be returned.
-
- Args:
- descriptor: The descriptor to build from.
-
- Returns:
- A class describing the passed in descriptor.
- """
-
- return self.GetSymbol(descriptor.full_name)
+ return self._classes[symbol]
def GetMessages(self, files):
- """Gets all the messages from a specified file.
-
- This will find and resolve dependencies, failing if they are not registered
- in the symbol database.
+ # TODO(amauryfa): Fix the differences with MessageFactory.
+ """Gets all registered messages from a specified file.
+ Only messages already created and registered will be returned; (this is the
+ case for imported _pb2 modules)
+ But unlike MessageFactory, this version also returns nested messages.
Args:
files: The file names to extract messages from.
Returns:
- A dictionary mapping proto names to the message classes. This will include
- any dependent messages as well as any messages defined in the same file as
- a specified message.
+ A dictionary mapping proto names to the message classes.
Raises:
KeyError: if a file could not be found.
"""
+ def _GetAllMessageNames(desc):
+ """Walk a message Descriptor and recursively yields all message names."""
+ yield desc.full_name
+ for msg_desc in desc.nested_types:
+ for full_name in _GetAllMessageNames(msg_desc):
+ yield full_name
+
result = {}
- for f in files:
- result.update(self._symbols_by_file[f])
+ for file_name in files:
+ file_desc = self.pool.FindFileByName(file_name)
+ for msg_desc in file_desc.message_types_by_name.values():
+ for full_name in _GetAllMessageNames(msg_desc):
+ try:
+ result[full_name] = self._classes[full_name]
+ except KeyError:
+ # This descriptor has no registered class, skip it.
+ pass
return result
+
_DEFAULT = SymbolDatabase(pool=descriptor_pool.Default())
diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec
index c542abf6..8cf40e3f 100644
--- a/ruby/google-protobuf.gemspec
+++ b/ruby/google-protobuf.gemspec
@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = "google-protobuf"
- s.version = "3.0.0.alpha.6.0.0"
+ s.version = "3.0.0.alpha.7.0.0"
s.licenses = ["BSD"]
s.summary = "Protocol Buffers"
s.description = "Protocol Buffers are Google's data interchange format."
diff --git a/ruby/pom.xml b/ruby/pom.xml
index 4cbd6d30..62845815 100644
--- a/ruby/pom.xml
+++ b/ruby/pom.xml
@@ -86,7 +86,7 @@
com.google.protobuf
protobuf-java
- 3.0.0-alpha-3
+ 3.0.0-beta-3
diff --git a/src/Makefile.am b/src/Makefile.am
index b75b6f74..81ebc954 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -530,6 +530,7 @@ EXTRA_DIST = \
google/protobuf/io/gzip_stream.h \
google/protobuf/io/gzip_stream_unittest.sh \
google/protobuf/testdata/golden_message \
+ google/protobuf/testdata/golden_message_maps \
google/protobuf/testdata/golden_message_oneof_implemented \
google/protobuf/testdata/golden_message_proto3 \
google/protobuf/testdata/golden_packed_fields_message \
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index c91faa08..ccccc9c1 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fany_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -61,6 +62,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -74,6 +76,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto() {
delete Any_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fany_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fany_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -101,16 +104,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fany_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fany_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
void Any::PackFrom(const ::google::protobuf::Message& message) {
@@ -334,7 +327,9 @@ int Any::ByteSize() const {
void Any::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Any)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Any* source =
::google::protobuf::internal::DynamicCastToGenerated(
&from);
@@ -349,7 +344,9 @@ void Any::MergeFrom(const ::google::protobuf::Message& from) {
void Any::MergeFrom(const Any& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.type_url().size() > 0) {
type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index d5dd8923..cfb30786 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -35,6 +35,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -109,6 +110,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -130,6 +132,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto() {
delete Mixin_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -175,16 +178,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fapi_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fapi_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -601,7 +594,9 @@ int Api::ByteSize() const {
void Api::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Api)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Api* source =
::google::protobuf::internal::DynamicCastToGenerated(
&from);
@@ -616,7 +611,9 @@ void Api::MergeFrom(const ::google::protobuf::Message& from) {
void Api::MergeFrom(const Api& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
methods_.MergeFrom(from.methods_);
options_.MergeFrom(from.options_);
mixins_.MergeFrom(from.mixins_);
@@ -1345,7 +1342,9 @@ int Method::ByteSize() const {
void Method::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Method)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Method* source =
::google::protobuf::internal::DynamicCastToGenerated(
&from);
@@ -1360,7 +1359,9 @@ void Method::MergeFrom(const ::google::protobuf::Message& from) {
void Method::MergeFrom(const Method& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
options_.MergeFrom(from.options_);
if (from.name().size() > 0) {
@@ -1858,7 +1859,9 @@ int Mixin::ByteSize() const {
void Mixin::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Mixin)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Mixin* source =
::google::protobuf::internal::DynamicCastToGenerated(
&from);
@@ -1873,7 +1876,9 @@ void Mixin::MergeFrom(const ::google::protobuf::Message& from) {
void Mixin::MergeFrom(const Mixin& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.name().size() > 0) {
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 385b973e..b3eca660 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -336,19 +336,6 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
// Generate classes.
for (int i = 0; i < file_->message_type_count(); i++) {
- if (i == 0 && HasGeneratedMethods(file_, options_)) {
- printer->Print(
- "\n"
- "namespace {\n"
- "\n"
- "static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;\n"
- "static void MergeFromFail(int line) {\n"
- " GOOGLE_CHECK(false) << __FILE__ << \":\" << line;\n"
- "}\n"
- "\n"
- "} // namespace\n"
- "\n");
- }
printer->Print("\n");
printer->Print(kThickSeparator);
printer->Print("\n");
@@ -464,9 +451,10 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// and we only use AddDescriptors() to allocate default instances.
if (HasDescriptorMethods(file_, options_)) {
printer->Print(
- "\n"
- "void $assigndescriptorsname$() {\n",
- "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+ "\n"
+ "void $assigndescriptorsname$() GOOGLE_ATTRIBUTE_COLD;\n"
+ "void $assigndescriptorsname$() {\n",
+ "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
printer->Indent();
// Make sure the file has found its way into the pool. If a descriptor
@@ -525,8 +513,9 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// protobuf_RegisterTypes(): Calls
// MessageFactory::InternalRegisterGeneratedType() for each message type.
printer->Print(
- "void protobuf_RegisterTypes(const ::std::string&) {\n"
- " protobuf_AssignDescriptorsOnce();\n");
+ "void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;\n"
+ "void protobuf_RegisterTypes(const ::std::string&) {\n"
+ " protobuf_AssignDescriptorsOnce();\n");
printer->Indent();
for (int i = 0; i < file_->message_type_count(); i++) {
@@ -566,6 +555,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// Note that we don't need any special synchronization in the following
// code
// because it is called at static init time before any threads exist.
+ "void $adddescriptorsname$() GOOGLE_ATTRIBUTE_COLD;\n"
"void $adddescriptorsname$() {\n"
" static bool already_here = false;\n"
" if (already_here) return;\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index dd9f1887..0588e34e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -251,117 +251,148 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
}
}
+static void GenerateSerializationLoop(io::Printer* printer,
+ const map& variables,
+ bool supports_arenas,
+ const string& utf8_check,
+ const string& loop_header,
+ const string& ptr,
+ bool loop_via_iterators) {
+ printer->Print(variables,
+ StrCat("::google::protobuf::scoped_ptr<$map_classname$> entry;\n",
+ loop_header, " {\n").c_str());
+ printer->Indent();
+
+ printer->Print(variables, StrCat(
+ "entry.reset($name$_.New$wrapper$(\n"
+ " ", ptr, "->first, ", ptr, "->second));\n"
+ "$write_entry$;\n").c_str());
+
+ // If entry is allocated by arena, its desctructor should be avoided.
+ if (supports_arenas) {
+ printer->Print(
+ "if (entry->GetArena() != NULL) {\n"
+ " entry.release();\n"
+ "}\n");
+ }
+
+ if (!utf8_check.empty()) {
+ // If loop_via_iterators is true then ptr is actually an iterator, and we
+ // create a pointer by prefixing it with "&*".
+ printer->Print(
+ StrCat(utf8_check, "(", (loop_via_iterators ? "&*" : ""), ptr, ");\n")
+ .c_str());
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+}
+
void MapFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
- printer->Print(variables_,
- "{\n"
- " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
- " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
- " it = this->$name$().begin();\n"
- " it != this->$name$().end(); ++it) {\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
-
- printer->Print(variables_,
- " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
- " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
- " $number$, *entry, output);\n");
-
- printer->Indent();
- printer->Indent();
-
- const FieldDescriptor* key_field =
- descriptor_->message_type()->FindFieldByName("key");
- const FieldDescriptor* value_field =
- descriptor_->message_type()->FindFieldByName("value");
- if (key_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(key_field, options_, false, variables_,
- "it->first.data(), it->first.length(),\n",
- printer);
- }
- if (value_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(value_field, options_, false, variables_,
- "it->second.data(), it->second.length(),\n",
- printer);
- }
-
- printer->Outdent();
- printer->Outdent();
-
- printer->Print(
- " }\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
-
- printer->Print("}\n");
+ map variables(variables_);
+ variables["write_entry"] = "::google::protobuf::internal::WireFormatLite::Write" +
+ variables["stream_writer"] + "(\n " +
+ variables["number"] + ", *entry, output)";
+ variables["deterministic"] = "output->IsSerializationDeterminstic()";
+ GenerateSerializeWithCachedSizes(printer, variables);
}
void MapFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
- printer->Print(variables_,
- "{\n"
- " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
- " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
- " it = this->$name$().begin();\n"
- " it != this->$name$().end(); ++it) {\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
-
- printer->Print(variables_,
- " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
- " target = ::google::protobuf::internal::WireFormatLite::\n"
- " InternalWrite$declared_type$NoVirtualToArray(\n"
- " $number$, *entry, false, target);\n");
+ map variables(variables_);
+ variables["write_entry"] =
+ "target = ::google::protobuf::internal::WireFormatLite::\n"
+ " InternalWrite" + variables["declared_type"] +
+ "NoVirtualToArray(\n " + variables["number"] +
+ ", *entry, deterministic, target);\n";
+ variables["deterministic"] = "deterministic";
+ GenerateSerializeWithCachedSizes(printer, variables);
+}
+void MapFieldGenerator::GenerateSerializeWithCachedSizes(
+ io::Printer* printer, const map& variables) const {
+ printer->Print(variables,
+ "if (!this->$name$().empty()) {\n");
printer->Indent();
- printer->Indent();
-
const FieldDescriptor* key_field =
descriptor_->message_type()->FindFieldByName("key");
const FieldDescriptor* value_field =
descriptor_->message_type()->FindFieldByName("value");
- if (key_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(key_field, options_, false, variables_,
- "it->first.data(), it->first.length(),\n",
- printer);
+ const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
+ const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;
+
+ printer->Print(variables,
+ "typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
+ " ConstPtr;\n");
+ if (string_key) {
+ printer->Print(variables,
+ "typedef ConstPtr SortItem;\n"
+ "typedef ::google::protobuf::internal::"
+ "CompareByDerefFirst Less;\n");
+ } else {
+ printer->Print(variables,
+ "typedef ::google::protobuf::internal::SortItem< $key_cpp$, ConstPtr > "
+ "SortItem;\n"
+ "typedef ::google::protobuf::internal::CompareByFirstField Less;\n");
}
- if (value_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(value_field, options_, false, variables_,
- "it->second.data(), it->second.length(),\n",
- printer);
+ string utf8_check;
+ if (string_key || string_value) {
+ printer->Print(
+ "struct Utf8Check {\n"
+ " static void Check(ConstPtr p) {\n");
+ printer->Indent();
+ printer->Indent();
+ if (string_key) {
+ GenerateUtf8CheckCodeForString(key_field, options_, false, variables,
+ "p->first.data(), p->first.length(),\n",
+ printer);
+ }
+ if (string_value) {
+ GenerateUtf8CheckCodeForString(value_field, options_, false, variables,
+ "p->second.data(), p->second.length(),\n",
+ printer);
+ }
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "};\n");
+ utf8_check = "Utf8Check::Check";
}
- printer->Outdent();
+ printer->Print(variables,
+ "\n"
+ "if ($deterministic$ &&\n"
+ " this->$name$().size() > 1) {\n"
+ " ::google::protobuf::scoped_array items(\n"
+ " new SortItem[this->$name$().size()]);\n"
+ " typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size_type;\n"
+ " size_type n = 0;\n"
+ " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->$name$().begin();\n"
+ " it != this->$name$().end(); ++it, ++n) {\n"
+ " items[n] = SortItem(&*it);\n"
+ " }\n"
+ " ::std::sort(&items[0], &items[n], Less());\n");
+ printer->Indent();
+ GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_),
+ utf8_check, "for (size_type i = 0; i < n; i++)",
+ string_key ? "items[i]" : "items[i].second", false);
printer->Outdent();
printer->Print(
- " }\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
-
+ "} else {\n");
+ printer->Indent();
+ GenerateSerializationLoop(
+ printer, variables, SupportsArenas(descriptor_), utf8_check,
+ "for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->$name$().begin();\n"
+ " it != this->$name$().end(); ++it)",
+ "it", true);
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Outdent();
printer->Print("}\n");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h
index 087dcde0..2930fe59 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h
@@ -61,6 +61,10 @@ class MapFieldGenerator : public FieldGenerator {
void GenerateByteSize(io::Printer* printer) const;
private:
+ // A helper for GenerateSerializeWithCachedSizes{,ToArray}.
+ void GenerateSerializeWithCachedSizes(
+ io::Printer* printer, const map& variables) const;
+
const FieldDescriptor* descriptor_;
const bool dependent_field_;
map variables_;
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 32f63152..405a5fed 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -2715,7 +2715,9 @@ GenerateMergeFrom(io::Printer* printer) {
"void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
"// @@protoc_insertion_point(generalized_merge_from_start:"
"$full_name$)\n"
- " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
+ " if (GOOGLE_PREDICT_FALSE(&from == this)) {\n"
+ " ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);\n"
+ " }\n",
"classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
@@ -2756,7 +2758,9 @@ GenerateMergeFrom(io::Printer* printer) {
"void $classname$::MergeFrom(const $classname$& from) {\n"
"// @@protoc_insertion_point(class_specific_merge_from_start:"
"$full_name$)\n"
- " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
+ " if (GOOGLE_PREDICT_FALSE(&from == this)) {\n"
+ " ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);\n"
+ " }\n",
"classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
index a06c5f6d..5e387285 100644
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -266,9 +266,7 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Print(
"public static void registerAllExtensions(\n"
- " com.google.protobuf.ExtensionRegistry$lite$ registry) {\n",
- "lite",
- HasDescriptorMethods(file_, context_->EnforceLite()) ? "" : "Lite");
+ " com.google.protobuf.ExtensionRegistryLite registry) {\n");
printer->Indent();
@@ -283,6 +281,20 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Outdent();
printer->Print(
"}\n");
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
+ // Overload registerAllExtensions for the non-lite usage to
+ // redundantly maintain the original signature (this is
+ // redundant because ExtensionRegistryLite now invokes
+ // ExtensionRegistry in the non-lite usage). Intent is
+ // to remove this in the future.
+ printer->Print(
+ "\n"
+ "public static void registerAllExtensions(\n"
+ " com.google.protobuf.ExtensionRegistry registry) {\n"
+ " registerAllExtensions(\n"
+ " (com.google.protobuf.ExtensionRegistryLite) registry);\n"
+ "}\n");
+ }
// -----------------------------------------------------------------
diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc
index 3c545e15..b1ab4043 100644
--- a/src/google/protobuf/compiler/java/java_generator.cc
+++ b/src/google/protobuf/compiler/java/java_generator.cc
@@ -79,8 +79,6 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
file_options.generate_mutable_code = true;
} else if (options[i].first == "shared") {
file_options.generate_shared_code = true;
- } else if (options[i].first == "lite") {
- file_options.enforce_lite = true;
} else if (options[i].first == "annotate_code") {
file_options.annotate_code = true;
} else if (options[i].first == "annotation_list_file") {
diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc
index b3e9e986..81a70a1f 100644
--- a/src/google/protobuf/compiler/java/java_message_builder.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder.cc
@@ -181,6 +181,18 @@ Generate(io::Printer* printer) {
" return this;\n"
"}\n"
"\n");
+ } else {
+ printer->Print(
+ "public final Builder setUnknownFields(\n"
+ " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
+ " return super.setUnknownFields(unknownFields);\n"
+ "}\n"
+ "\n"
+ "public final Builder mergeUnknownFields(\n"
+ " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
+ " return super.mergeUnknownFields(unknownFields);\n"
+ "}\n"
+ "\n");
}
printer->Print(
@@ -438,6 +450,62 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
+ printer->Print(
+ "public Builder clone() {\n"
+ " return (Builder) super.clone();\n"
+ "}\n"
+ "public Builder setField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " Object value) {\n"
+ " return (Builder) super.setField(field, value);\n"
+ "}\n"
+ "public Builder clearField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field) {\n"
+ " return (Builder) super.clearField(field);\n"
+ "}\n"
+ "public Builder clearOneof(\n"
+ " com.google.protobuf.Descriptors.OneofDescriptor oneof) {\n"
+ " return (Builder) super.clearOneof(oneof);\n"
+ "}\n"
+ "public Builder setRepeatedField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " int index, Object value) {\n"
+ " return (Builder) super.setRepeatedField(field, index, value);\n"
+ "}\n"
+ "public Builder addRepeatedField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " Object value) {\n"
+ " return (Builder) super.addRepeatedField(field, value);\n"
+ "}\n");
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "public Builder setExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, Type> extension,\n"
+ " Type value) {\n"
+ " return (Builder) super.setExtension(extension, value);\n"
+ "}\n"
+ "public Builder setExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, java.util.List> extension,\n"
+ " int index, Type value) {\n"
+ " return (Builder) super.setExtension(extension, index, value);\n"
+ "}\n"
+ "public Builder addExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, java.util.List> extension,\n"
+ " Type value) {\n"
+ " return (Builder) super.addExtension(extension, value);\n"
+ "}\n"
+ "public Builder clearExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, ?> extension) {\n"
+ " return (Builder) super.clearExtension(extension);\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ }
+
// -----------------------------------------------------------------
if (context_->HasGeneratedMethods(descriptor_)) {
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 8a2633d7..ad8cb166 100755
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -2031,9 +2031,8 @@ void Generator::GenerateClassFieldToObject(const GeneratorOptions& options,
"getter", JSGetterName(options, field, BYTES_B64));
} else {
if (field->has_default_value()) {
- printer->Print("jspb.Message.getField(msg, $index$) == null ? "
- "$defaultValue$ : ",
- "index", JSFieldIndex(field),
+ printer->Print("!msg.has$name$() ? $defaultValue$ : ",
+ "name", JSGetterName(options, field),
"defaultValue", JSFieldDefault(field));
}
if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT ||
@@ -2408,9 +2407,8 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"default", Proto3PrimitiveFieldDefault(field));
} else {
if (field->has_default_value()) {
- printer->Print("jspb.Message.getField(this, $index$) == null ? "
- "$defaultValue$ : ",
- "index", JSFieldIndex(field),
+ printer->Print("!this.has$name$() ? $defaultValue$ : ",
+ "name", JSGetterName(options, field),
"defaultValue", JSFieldDefault(field));
}
if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT ||
@@ -2515,6 +2513,20 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"\n",
"clearedvalue", (field->is_repeated() ? "[]" : "undefined"),
"returnvalue", JSReturnClause(field));
+
+ printer->Print(
+ "/**\n"
+ " * Returns whether this field is set.\n"
+ " * @return{!boolean}\n"
+ " */\n"
+ "$class$.prototype.has$name$ = function() {\n"
+ " return jspb.Message.getField(this, $index$) != null;\n"
+ "};\n"
+ "\n"
+ "\n",
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field),
+ "index", JSFieldIndex(field));
}
}
}
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index c4d48fc6..9064c382 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -36,6 +36,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -102,6 +103,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -123,6 +125,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
delete CodeGeneratorResponse_File_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -161,16 +164,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto
}
} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -451,7 +444,9 @@ int CodeGeneratorRequest::ByteSize() const {
void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const CodeGeneratorRequest* source =
::google::protobuf::internal::DynamicCastToGenerated(
&from);
@@ -466,7 +461,9 @@ void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) {
void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
file_to_generate_.MergeFrom(from.file_to_generate_);
proto_file_.MergeFrom(from.proto_file_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
@@ -962,7 +959,9 @@ int CodeGeneratorResponse_File::ByteSize() const {
void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const CodeGeneratorResponse_File* source =
::google::protobuf::internal::DynamicCastToGenerated(
&from);
@@ -977,7 +976,9 @@ void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& fr
void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -1269,7 +1270,9 @@ int CodeGeneratorResponse::ByteSize() const {
void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const CodeGeneratorResponse* source =
::google::protobuf::internal::DynamicCastToGenerated(
&from);
@@ -1284,7 +1287,9 @@ void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) {
void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
file_.MergeFrom(from.file_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_error()) {
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index cc54a8ab..d5468a0c 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -44,6 +44,7 @@
// performance-minded Python code leverage the fast C++ implementation
// directly.
+#include
#include
#include
#include