Merge remote-tracking branch 'origin/3.0.0-beta-4'

pull/1803/head
Feng Xiao 8 years ago
commit 2078f614e4
  1. 81
      CHANGES.txt
  2. 2
      Protobuf.podspec
  3. 2
      configure.ac
  4. 88
      conformance/Makefile.am
  5. 2
      csharp/Google.Protobuf.Tools.nuspec
  6. 6
      csharp/src/Google.Protobuf/Reflection/Descriptor.cs
  7. 2
      java/core/pom.xml
  8. 38
      java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
  9. 8
      java/core/src/main/java/com/google/protobuf/DynamicMessage.java
  10. 8
      java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
  11. 50
      java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
  12. 3
      java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
  13. 2
      java/lite/pom.xml
  14. 4
      java/pom.xml
  15. 2
      java/util/pom.xml
  16. 40
      java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
  17. 22
      java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
  18. 4
      javanano/pom.xml
  19. 46
      js/message_test.js
  20. 2
      js/package.json
  21. 15
      js/proto3_test.js
  22. 1
      js/test.proto
  23. 2
      protoc-artifacts/pom.xml
  24. 2
      python/google/protobuf/__init__.py
  25. 6
      python/google/protobuf/internal/json_format_test.py
  26. 26
      python/google/protobuf/internal/python_message.py
  27. 1
      python/google/protobuf/internal/reflection_test.py
  28. 26
      python/google/protobuf/internal/symbol_database_test.py
  29. 6
      python/google/protobuf/pyext/cpp_message.py
  30. 3
      python/google/protobuf/pyext/map_container.cc
  31. 16
      python/google/protobuf/pyext/message.cc
  32. 4
      python/google/protobuf/pyext/message.h
  33. 4
      python/google/protobuf/pyext/repeated_composite_container.cc
  34. 8
      python/google/protobuf/reflection.py
  35. 82
      python/google/protobuf/symbol_database.py
  36. 2
      ruby/google-protobuf.gemspec
  37. 2
      ruby/pom.xml
  38. 1
      src/Makefile.am
  39. 21
      src/google/protobuf/any.pb.cc
  40. 37
      src/google/protobuf/api.pb.cc
  41. 26
      src/google/protobuf/compiler/cpp/cpp_file.cc
  42. 205
      src/google/protobuf/compiler/cpp/cpp_map_field.cc
  43. 4
      src/google/protobuf/compiler/cpp/cpp_map_field.h
  44. 8
      src/google/protobuf/compiler/cpp/cpp_message.cc
  45. 18
      src/google/protobuf/compiler/java/java_file.cc
  46. 2
      src/google/protobuf/compiler/java/java_generator.cc
  47. 68
      src/google/protobuf/compiler/java/java_message_builder.cc
  48. 24
      src/google/protobuf/compiler/js/js_generator.cc
  49. 37
      src/google/protobuf/compiler/plugin.pb.cc
  50. 60
      src/google/protobuf/compiler/python/python_generator.cc
  51. 48
      src/google/protobuf/compiler/python/python_plugin_unittest.cc
  52. 219
      src/google/protobuf/descriptor.pb.cc
  53. 1
      src/google/protobuf/descriptor.proto
  54. 21
      src/google/protobuf/duration.pb.cc
  55. 21
      src/google/protobuf/empty.pb.cc
  56. 2
      src/google/protobuf/extension_set_heavy.cc
  57. 21
      src/google/protobuf/field_mask.pb.cc
  58. 6
      src/google/protobuf/generated_message_util.cc
  59. 11
      src/google/protobuf/generated_message_util.h
  60. 8
      src/google/protobuf/io/coded_stream.cc
  61. 47
      src/google/protobuf/io/coded_stream.h
  62. 26
      src/google/protobuf/map_entry_lite.h
  63. 20
      src/google/protobuf/map_proto2_unittest.proto
  64. 77
      src/google/protobuf/map_test.cc
  65. 18
      src/google/protobuf/map_type_handler.h
  66. 2
      src/google/protobuf/message.cc
  67. 2
      src/google/protobuf/message.h
  68. 2
      src/google/protobuf/message_lite.cc
  69. 2
      src/google/protobuf/message_lite.h
  70. 21
      src/google/protobuf/source_context.pb.cc
  71. 156
      src/google/protobuf/struct.pb.cc
  72. BIN
      src/google/protobuf/testdata/golden_message_maps
  73. 14
      src/google/protobuf/text_format.cc
  74. 21
      src/google/protobuf/timestamp.pb.cc
  75. 53
      src/google/protobuf/type.pb.cc
  76. 28
      src/google/protobuf/unknown_field_set.cc
  77. 8
      src/google/protobuf/unknown_field_set.h
  78. 29
      src/google/protobuf/util/internal/default_value_objectwriter.cc
  79. 12
      src/google/protobuf/util/internal/default_value_objectwriter.h
  80. 33
      src/google/protobuf/util/internal/default_value_objectwriter_test.cc
  81. 34
      src/google/protobuf/util/internal/proto_writer.cc
  82. 9
      src/google/protobuf/util/internal/proto_writer.h
  83. 60
      src/google/protobuf/util/json_util.cc
  84. 29
      src/google/protobuf/util/json_util.h
  85. 60
      src/google/protobuf/util/json_util_test.cc
  86. 6
      src/google/protobuf/wire_format_lite.cc
  87. 85
      src/google/protobuf/wrappers.pb.cc

@ -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.

@ -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'

@ -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])

@ -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

@ -5,7 +5,7 @@
<title>Google Protocol Buffers tools</title>
<summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
<description>See project site for more info.</description>
<version>3.0.0-beta3</version>
<version>3.0.0-beta4</version>
<authors>Google Inc.</authors>
<owners>protobuf-packages</owners>
<licenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</licenseUrl>

@ -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[] {

@ -6,7 +6,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.0.0-beta-3</version>
<version>3.0.0-beta-4</version>
</parent>
<artifactId>protobuf-java</artifactId>

@ -144,6 +144,44 @@ public abstract class CodedOutputStream extends ByteOutput {
return new NioEncoder(byteBuffer);
}
/**
* Configures serialization to be deterministic.
*
* <p>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:
*
* <ul>
* <li>repeated serialization of a message will return the same bytes
* <li>different processes of the same binary (which may be executing on different machines) will
* serialize equal messages to the same bytes.
* </ul>
*
* <p>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.
*
* <p> Once set, the serializer will: (Note this is an implementation detail and may subject to
* change in the future)
*
* <ul>
* <li> 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.
* </ul>
*/
void useDeterministicSerialization() {
serializationDeterministic = true;
}
boolean isSerializationDeterministic() {
return serializationDeterministic;
}
private boolean serializationDeterministic;
/**
* Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}.
*

@ -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;

@ -1396,7 +1396,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return setExtension((ExtensionLite<MessageType, Type>) extension, value);
}
/** Set the value of an extension. */
public final <Type> BuilderType setExtension(
public <Type> BuilderType setExtension(
final GeneratedExtension<MessageType, Type> extension, final Type value) {
return setExtension((ExtensionLite<MessageType, Type>) extension, value);
}
@ -1407,7 +1407,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value);
}
/** Set the value of one element of a repeated extension. */
public final <Type> BuilderType setExtension(
public <Type> BuilderType setExtension(
final GeneratedExtension<MessageType, List<Type>> extension,
final int index, final Type value) {
return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value);
@ -1418,7 +1418,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value);
}
/** Append a value to a repeated extension. */
public final <Type> BuilderType addExtension(
public <Type> BuilderType addExtension(
final GeneratedExtension<MessageType, List<Type>> extension, final Type value) {
return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value);
}
@ -1428,7 +1428,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return clearExtension((ExtensionLite<MessageType, ?>) extension);
}
/** Clear an extension. */
public final <Type> BuilderType clearExtension(
public <Type> BuilderType clearExtension(
final GeneratedExtension<MessageType, ?> extension) {
return clearExtension((ExtensionLite<MessageType, ?>) extension);
}

@ -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());

@ -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

@ -6,7 +6,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.0.0-beta-3</version>
<version>3.0.0-beta-4</version>
</parent>
<artifactId>protobuf-lite</artifactId>

@ -11,7 +11,7 @@
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.0.0-beta-3</version>
<version>3.0.0-beta-4</version>
<packaging>pom</packaging>
<name>Protocol Buffers [Parent]</name>
@ -182,7 +182,7 @@
<modules>
<module>core</module>
<module>lite</module>
<!-- <module>lite</module> -->
<module>util</module>
</modules>

@ -6,7 +6,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.0.0-beta-3</version>
<version>3.0.0-beta-4</version>
</parent>
<artifactId>protobuf-java-util</artifactId>

@ -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 <a href="https://tools.ietf.org/html/rfc7159">https://tools.ietf.org/html/rfc7159</a>
* 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();

@ -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());
}
}

@ -10,7 +10,7 @@
</parent>
<groupId>com.google.protobuf.nano</groupId>
<artifactId>protobuf-javanano</artifactId>
<version>3.0.0-alpha-6</version>
<version>3.0.0-alpha-7</version>
<packaging>bundle</packaging>
<name>Protocol Buffer JavaNano API</name>
<description>
@ -165,7 +165,7 @@
<instructions>
<Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
<Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
<Export-Package>com.google.protobuf;version=3.0.0-alpha-5</Export-Package>
<Export-Package>com.google.protobuf;version=3.0.0-alpha-7</Export-Package>
</instructions>
</configuration>
</plugin>

@ -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

@ -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": [

@ -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());
});

@ -233,3 +233,4 @@ message TestEndsWithBytes {
optional int32 value = 1;
optional bytes data = 2;
}

@ -10,7 +10,7 @@
</parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
<version>3.0.0-beta-3</version>
<version>3.0.0-beta-4</version>
<packaging>pom</packaging>
<name>Protobuf Compiler</name>
<description>

@ -30,7 +30,7 @@
# Copyright 2007 Google Inc. All Rights Reserved.
__version__ = '3.0.0b3'
__version__ = '3.0.0b4'
if __name__ != '__main__':
try:

@ -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

@ -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):

@ -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()

@ -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(

@ -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
...

@ -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

@ -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<CMessage*>(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);
}
// ---------------------------------------------------------------------

@ -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);

@ -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;

@ -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

@ -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())

@ -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."

@ -86,7 +86,7 @@
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.0.0-alpha-3</version>
<version>3.0.0-beta-3</version>
</dependency>
</dependencies>
</project>

@ -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 \

@ -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<const Any>(
&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_);

@ -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<const Api>(
&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<const Method>(
&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<const Mixin>(
&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_);

@ -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"

@ -251,117 +251,148 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
}
}
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");
static void GenerateSerializationLoop(io::Printer* printer,
const map<string, string>& 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 (SupportsArenas(descriptor_)) {
printer->Print(variables_,
" if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
" entry.release();\n"
" }\n");
if (supports_arenas) {
printer->Print(
"if (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);
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->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");
}
"}\n");
}
printer->Print("}\n");
void MapFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
map<string, string> 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<string, string> 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<string, string>& 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<SortItem> Less;\n");
} else {
printer->Print(variables,
"typedef ::google::protobuf::internal::SortItem< $key_cpp$, ConstPtr > "
"SortItem;\n"
"typedef ::google::protobuf::internal::CompareByFirstField<SortItem> 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<SortItem> 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");
}

@ -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<string, string>& variables) const;
const FieldDescriptor* descriptor_;
const bool dependent_field_;
map<string, string> variables_;

@ -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();

@ -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");
}
// -----------------------------------------------------------------

@ -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") {

@ -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 <Type> 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 <Type> Builder setExtension(\n"
" com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
" $classname$, java.util.List<Type>> extension,\n"
" int index, Type value) {\n"
" return (Builder) super.setExtension(extension, index, value);\n"
"}\n"
"public <Type> Builder addExtension(\n"
" com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
" $classname$, java.util.List<Type>> extension,\n"
" Type value) {\n"
" return (Builder) super.addExtension(extension, value);\n"
"}\n"
"public <Type> 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_)) {

@ -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));
}
}
}

@ -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<const CodeGeneratorRequest>(
&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<const CodeGeneratorResponse_File>(
&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<const CodeGeneratorResponse>(
&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()) {

@ -44,6 +44,7 @@
// performance-minded Python code leverage the fast C++ implementation
// directly.
#include <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <limits>
#include <map>
@ -107,20 +108,25 @@ string ModuleAlias(const string& filename) {
return module_name;
}
// Returns an import statement of form "from X.Y.Z import T" for the given
// .proto filename.
string ModuleImportStatement(const string& filename) {
string module_name = ModuleName(filename);
int last_dot_pos = module_name.rfind('.');
if (last_dot_pos == string::npos) {
// NOTE(petya): this is not tested as it would require a protocol buffer
// outside of any package, and I don't think that is easily achievable.
return "import " + module_name;
} else {
return "from " + module_name.substr(0, last_dot_pos) + " import " +
module_name.substr(last_dot_pos + 1);
// Keywords reserved by the Python language.
const char* const kKeywords[] = {
"False", "None", "True", "and", "as", "assert", "break",
"class", "continue", "def", "del", "elif", "else", "except",
"finally", "for", "from", "global", "if", "import", "in",
"is", "lambda", "nonlocal", "not", "or", "pass", "raise",
"return", "try", "while", "with", "yield",
};
const char* const* kKeywordsEnd =
kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0]));
bool ContainsPythonKeyword(const string& module_name) {
vector<string> tokens = Split(module_name, ".");
for (int i = 0; i < tokens.size(); ++i) {
if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) {
return true;
}
}
return false;
}
@ -359,10 +365,32 @@ bool Generator::Generate(const FileDescriptor* file,
void Generator::PrintImports() const {
for (int i = 0; i < file_->dependency_count(); ++i) {
const string& filename = file_->dependency(i)->name();
string import_statement = ModuleImportStatement(filename);
string module_name = ModuleName(filename);
string module_alias = ModuleAlias(filename);
printer_->Print("$statement$ as $alias$\n", "statement",
import_statement, "alias", module_alias);
if (ContainsPythonKeyword(module_name)) {
// If the module path contains a Python keyword, we have to quote the
// module name and import it using importlib. Otherwise the usual kind of
// import statement would result in a syntax error from the presence of
// the keyword.
printer_->Print("import importlib\n");
printer_->Print("$alias$ = importlib.import_module('$name$')\n", "alias",
module_alias, "name", module_name);
} else {
int last_dot_pos = module_name.rfind('.');
string import_statement;
if (last_dot_pos == string::npos) {
// NOTE(petya): this is not tested as it would require a protocol buffer
// outside of any package, and I don't think that is easily achievable.
import_statement = "import " + module_name;
} else {
import_statement = "from " + module_name.substr(0, last_dot_pos) +
" import " + module_name.substr(last_dot_pos + 1);
}
printer_->Print("$statement$ as $alias$\n", "statement", import_statement,
"alias", module_alias);
}
CopyPublicDependenciesAliases(module_alias, file_->dependency(i));
}
printer_->Print("\n");

@ -46,6 +46,7 @@
#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@ -115,6 +116,53 @@ TEST(PythonPluginTest, PluginTest) {
EXPECT_EQ(0, cli.Run(5, argv));
}
// This test verifies that the generated Python output uses regular imports (as
// opposed to importlib) in the usual case where the .proto file paths do not
// not contain any Python keywords.
TEST(PythonPluginTest, ImportTest) {
// Create files test1.proto and test2.proto with the former importing the
// latter.
GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test1.proto",
"syntax = \"proto3\";\n"
"package foo;\n"
"import \"test2.proto\";"
"message Message1 {\n"
" Message2 message_2 = 1;\n"
"}\n",
true));
GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test2.proto",
"syntax = \"proto3\";\n"
"package foo;\n"
"message Message2 {}\n",
true));
google::protobuf::compiler::CommandLineInterface cli;
cli.SetInputsAreProtoPathRelative(true);
python::Generator python_generator;
cli.RegisterGenerator("--python_out", &python_generator, "");
string proto_path = "-I" + TestTempDir();
string python_out = "--python_out=" + TestTempDir();
const char* argv[] = {"protoc", proto_path.c_str(), "-I.", python_out.c_str(),
"test1.proto"};
ASSERT_EQ(0, cli.Run(5, argv));
// Loop over the lines of the generated code and verify that we find an
// ordinary Python import but do not find the string "importlib".
string output;
GOOGLE_CHECK_OK(File::GetContents(TestTempDir() + "/test1_pb2.py", &output,
true));
std::vector<string> lines = Split(output, "\n");
string expected_import = "import test2_pb2";
bool found_expected_import = false;
for (int i = 0; i < lines.size(); ++i) {
if (lines[i].find(expected_import) != string::npos) {
found_expected_import = true;
}
EXPECT_EQ(string::npos, lines[i].find("importlib"));
}
EXPECT_TRUE(found_expected_import);
}
} // namespace
} // namespace python
} // namespace compiler

@ -106,6 +106,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
const ::google::protobuf::FileDescriptor* file =
@ -588,6 +589,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@ -697,6 +699,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
delete GeneratedCodeInfo_Annotation_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
static bool already_here = false;
if (already_here) return;
@ -834,9 +837,9 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
".protobuf.GeneratedCodeInfo.Annotation\032O"
"\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source"
"_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B"
"X\n\023com.google.protobufB\020DescriptorProtos"
"H\001Z\ndescriptor\242\002\003GPB\252\002\032Google.Protobuf.R"
"eflection", 5289);
"[\n\023com.google.protobufB\020DescriptorProtos"
"H\001Z\ndescriptor\240\001\001\242\002\003GPB\252\002\032Google.Protobu"
"f.Reflection", 5292);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
FileDescriptorSet::default_instance_ = new FileDescriptorSet();
@ -899,16 +902,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_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
@ -1088,7 +1081,9 @@ int FileDescriptorSet::ByteSize() const {
void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileDescriptorSet)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const FileDescriptorSet* source =
::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorSet>(
&from);
@ -1103,7 +1098,9 @@ void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet)
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._internal_metadata_.have_unknown_fields()) {
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@ -1856,7 +1853,9 @@ int FileDescriptorProto::ByteSize() const {
void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const FileDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorProto>(
&from);
@ -1871,7 +1870,9 @@ void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
dependency_.MergeFrom(from.dependency_);
public_dependency_.MergeFrom(from.public_dependency_);
weak_dependency_.MergeFrom(from.weak_dependency_);
@ -2682,7 +2683,9 @@ int DescriptorProto_ExtensionRange::ByteSize() const {
void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const DescriptorProto_ExtensionRange* source =
::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ExtensionRange>(
&from);
@ -2697,7 +2700,9 @@ void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message
void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
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_start()) {
set_start(from.start());
@ -2981,7 +2986,9 @@ int DescriptorProto_ReservedRange::ByteSize() const {
void DescriptorProto_ReservedRange::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const DescriptorProto_ReservedRange* source =
::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ReservedRange>(
&from);
@ -2996,7 +3003,9 @@ void DescriptorProto_ReservedRange::MergeFrom(const ::google::protobuf::Message&
void DescriptorProto_ReservedRange::MergeFrom(const DescriptorProto_ReservedRange& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
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_start()) {
set_start(from.start());
@ -3608,7 +3617,9 @@ int DescriptorProto::ByteSize() const {
void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const DescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto>(
&from);
@ -3623,7 +3634,9 @@ void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void DescriptorProto::MergeFrom(const DescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
field_.MergeFrom(from.field_);
extension_.MergeFrom(from.extension_);
nested_type_.MergeFrom(from.nested_type_);
@ -4844,7 +4857,9 @@ int FieldDescriptorProto::ByteSize() const {
void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const FieldDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldDescriptorProto>(
&from);
@ -4859,7 +4874,9 @@ void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto)
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();
@ -5606,7 +5623,9 @@ int OneofDescriptorProto::ByteSize() const {
void OneofDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.OneofDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const OneofDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const OneofDescriptorProto>(
&from);
@ -5621,7 +5640,9 @@ void OneofDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto)
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();
@ -6056,7 +6077,9 @@ int EnumDescriptorProto::ByteSize() const {
void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const EnumDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumDescriptorProto>(
&from);
@ -6071,7 +6094,9 @@ void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
value_.MergeFrom(from.value_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
@ -6534,7 +6559,9 @@ int EnumValueDescriptorProto::ByteSize() const {
void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValueDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const EnumValueDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumValueDescriptorProto>(
&from);
@ -6549,7 +6576,9 @@ void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from
void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto)
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();
@ -7012,7 +7041,9 @@ int ServiceDescriptorProto::ByteSize() const {
void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ServiceDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const ServiceDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const ServiceDescriptorProto>(
&from);
@ -7027,7 +7058,9 @@ void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from)
void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
method_.MergeFrom(from.method_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
@ -7642,7 +7675,9 @@ int MethodDescriptorProto::ByteSize() const {
void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MethodDescriptorProto)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const MethodDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const MethodDescriptorProto>(
&from);
@ -7657,7 +7692,9 @@ void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto)
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();
@ -8792,7 +8829,9 @@ int FileOptions::ByteSize() const {
void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const FileOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const FileOptions>(
&from);
@ -8807,7 +8846,9 @@ void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
void FileOptions::MergeFrom(const FileOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_java_package()) {
@ -9789,7 +9830,9 @@ int MessageOptions::ByteSize() const {
void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MessageOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const MessageOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const MessageOptions>(
&from);
@ -9804,7 +9847,9 @@ void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
void MessageOptions::MergeFrom(const MessageOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_message_set_wire_format()) {
@ -10477,7 +10522,9 @@ int FieldOptions::ByteSize() const {
void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const FieldOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldOptions>(
&from);
@ -10492,7 +10539,9 @@ void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
void FieldOptions::MergeFrom(const FieldOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_ctype()) {
@ -10943,7 +10992,9 @@ int OneofOptions::ByteSize() const {
void OneofOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.OneofOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const OneofOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const OneofOptions>(
&from);
@ -10958,7 +11009,9 @@ void OneofOptions::MergeFrom(const ::google::protobuf::Message& from) {
void OneofOptions::MergeFrom(const OneofOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
_extensions_.MergeFrom(from._extensions_);
if (from._internal_metadata_.have_unknown_fields()) {
@ -11324,7 +11377,9 @@ int EnumOptions::ByteSize() const {
void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const EnumOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumOptions>(
&from);
@ -11339,7 +11394,9 @@ void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
void EnumOptions::MergeFrom(const EnumOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_allow_alias()) {
@ -11709,7 +11766,9 @@ int EnumValueOptions::ByteSize() const {
void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValueOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const EnumValueOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumValueOptions>(
&from);
@ -11724,7 +11783,9 @@ void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_deprecated()) {
@ -12066,7 +12127,9 @@ int ServiceOptions::ByteSize() const {
void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ServiceOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const ServiceOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const ServiceOptions>(
&from);
@ -12081,7 +12144,9 @@ void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
void ServiceOptions::MergeFrom(const ServiceOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_deprecated()) {
@ -12423,7 +12488,9 @@ int MethodOptions::ByteSize() const {
void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MethodOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const MethodOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const MethodOptions>(
&from);
@ -12438,7 +12505,9 @@ void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
void MethodOptions::MergeFrom(const MethodOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_deprecated()) {
@ -12796,7 +12865,9 @@ int UninterpretedOption_NamePart::ByteSize() const {
void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const UninterpretedOption_NamePart* source =
::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption_NamePart>(
&from);
@ -12811,7 +12882,9 @@ void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message&
void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
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_part()) {
set_has_name_part();
@ -13313,7 +13386,9 @@ int UninterpretedOption::ByteSize() const {
void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UninterpretedOption)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const UninterpretedOption* source =
::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption>(
&from);
@ -13328,7 +13403,9 @@ void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) {
void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
name_.MergeFrom(from.name_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
if (from.has_identifier_value()) {
@ -14170,7 +14247,9 @@ int SourceCodeInfo_Location::ByteSize() const {
void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceCodeInfo.Location)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const SourceCodeInfo_Location* source =
::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo_Location>(
&from);
@ -14185,7 +14264,9 @@ void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from)
void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
path_.MergeFrom(from.path_);
span_.MergeFrom(from.span_);
leading_detached_comments_.MergeFrom(from.leading_detached_comments_);
@ -14426,7 +14507,9 @@ int SourceCodeInfo::ByteSize() const {
void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceCodeInfo)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const SourceCodeInfo* source =
::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo>(
&from);
@ -14441,7 +14524,9 @@ void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
location_.MergeFrom(from.location_);
if (from._internal_metadata_.have_unknown_fields()) {
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@ -15093,7 +15178,9 @@ int GeneratedCodeInfo_Annotation::ByteSize() const {
void GeneratedCodeInfo_Annotation::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const GeneratedCodeInfo_Annotation* source =
::google::protobuf::internal::DynamicCastToGenerated<const GeneratedCodeInfo_Annotation>(
&from);
@ -15108,7 +15195,9 @@ void GeneratedCodeInfo_Annotation::MergeFrom(const ::google::protobuf::Message&
void GeneratedCodeInfo_Annotation::MergeFrom(const GeneratedCodeInfo_Annotation& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
path_.MergeFrom(from.path_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
if (from.has_source_file()) {
@ -15348,7 +15437,9 @@ int GeneratedCodeInfo::ByteSize() const {
void GeneratedCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.GeneratedCodeInfo)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const GeneratedCodeInfo* source =
::google::protobuf::internal::DynamicCastToGenerated<const GeneratedCodeInfo>(
&from);
@ -15363,7 +15454,9 @@ void GeneratedCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
void GeneratedCodeInfo::MergeFrom(const GeneratedCodeInfo& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
annotation_.MergeFrom(from.annotation_);
if (from._internal_metadata_.have_unknown_fields()) {
mutable_unknown_fields()->MergeFrom(from.unknown_fields());

@ -45,6 +45,7 @@ option java_package = "com.google.protobuf";
option java_outer_classname = "DescriptorProtos";
option csharp_namespace = "Google.Protobuf.Reflection";
option objc_class_prefix = "GPB";
option java_generate_equals_and_hash = true;
// descriptor.proto must be optimized for speed because reflection-based
// algorithms don't work during bootstrapping.

@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto();
const ::google::protobuf::FileDescriptor* file =
@ -61,6 +62,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fduration_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_2fduration_2eproto() {
delete Duration_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto() {
static bool already_here = false;
if (already_here) return;
@ -101,16 +104,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fduration_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fduration_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
@ -322,7 +315,9 @@ int Duration::ByteSize() const {
void Duration::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Duration)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Duration* source =
::google::protobuf::internal::DynamicCastToGenerated<const Duration>(
&from);
@ -337,7 +332,9 @@ void Duration::MergeFrom(const ::google::protobuf::Message& from) {
void Duration::MergeFrom(const Duration& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.seconds() != 0) {
set_seconds(from.seconds());
}

@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto();
const ::google::protobuf::FileDescriptor* file =
@ -59,6 +60,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@ -72,6 +74,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto() {
delete Empty_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() {
static bool already_here = false;
if (already_here) return;
@ -98,16 +101,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fempty_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fempty_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
@ -240,7 +233,9 @@ int Empty::ByteSize() const {
void Empty::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Empty)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Empty* source =
::google::protobuf::internal::DynamicCastToGenerated<const Empty>(
&from);
@ -255,7 +250,9 @@ void Empty::MergeFrom(const ::google::protobuf::Message& from) {
void Empty::MergeFrom(const Empty& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Empty)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
}
void Empty::CopyFrom(const ::google::protobuf::Message& from) {

@ -341,7 +341,7 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
int ExtensionSet::SpaceUsedExcludingSelf() const {
int total_size =
extensions_.size() * sizeof(map<int, Extension>::value_type);
extensions_.size() * sizeof(ExtensionMap::value_type);
for (ExtensionMap::const_iterator iter = extensions_.begin(),
end = extensions_.end();
iter != end;

@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto();
const ::google::protobuf::FileDescriptor* file =
@ -60,6 +61,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@ -73,6 +75,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2ffield_5fmask_2eproto() {
delete FieldMask_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto() {
static bool already_here = false;
if (already_here) return;
@ -99,16 +102,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2ffield_5fmask_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2ffield_5fmask_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
@ -281,7 +274,9 @@ int FieldMask::ByteSize() const {
void FieldMask::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldMask)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const FieldMask* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldMask>(
&from);
@ -296,7 +291,9 @@ void FieldMask::MergeFrom(const ::google::protobuf::Message& from) {
void FieldMask::MergeFrom(const FieldMask& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
paths_.MergeFrom(from.paths_);
}

@ -73,6 +73,12 @@ int StringSpaceUsedExcludingSelf(const string& str) {
void MergeFromFail(const char* file, int line) {
GOOGLE_CHECK(false) << file << ":" << line;
// Open-source GOOGLE_CHECK(false) is not NORETURN.
exit(1);
}
} // namespace internal
} // namespace protobuf
} // namespace google

@ -41,8 +41,8 @@
#include <assert.h>
#include <string>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
namespace google {
@ -112,8 +112,13 @@ class ArenaString;
// pointer to a copy of the string that resides in *arena. Requires both
// args to be non-NULL. If something goes wrong while reading the data
// then NULL is returned (e.g., input does not start with a valid varint).
ArenaString* ReadArenaString(::google::protobuf::io::CodedInputStream* input,
::google::protobuf::Arena* arena);
LIBPROTOBUF_EXPORT ArenaString* ReadArenaString(
::google::protobuf::io::CodedInputStream* input,
::google::protobuf::Arena* arena);
// Helper function to crash on merge failure.
// Moved out of generated code to reduce binary size.
LIBPROTOBUF_EXPORT void MergeFromFail(const char* file, int line) GOOGLE_ATTRIBUTE_NORETURN;
} // namespace internal
} // namespace protobuf

@ -649,13 +649,16 @@ bool CodedInputStream::Refresh() {
// CodedOutputStream =================================================
bool CodedOutputStream::default_serialization_deterministic_ = false;
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
: output_(output),
buffer_(NULL),
buffer_size_(0),
total_bytes_(0),
had_error_(false),
aliasing_enabled_(false) {
aliasing_enabled_(false),
serialization_deterministic_is_overridden_(false) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
// The Refresh() may have failed. If the client doesn't write any data,
@ -671,7 +674,8 @@ CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output,
buffer_size_(0),
total_bytes_(0),
had_error_(false),
aliasing_enabled_(false) {
aliasing_enabled_(false),
serialization_deterministic_is_overridden_(false) {
if (do_eager_refresh) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();

@ -813,6 +813,44 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// created.
bool HadError() const { return had_error_; }
// Deterministic serialization, if requested, guarantees that for a given
// binary, equal 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.
//
// If determinisitc serialization is requested, the serializer will
// sort map entries by keys in lexicographical order or numerical order.
// (This is an implementation detail and may subject to change.)
//
// There are two ways to determine whether serialization should be
// deterministic for this CodedOutputStream. If SetSerializationDeterministic
// has not yet been called, then the default comes from the global default,
// which is false, until SetDefaultSerializationDeterministic has been called.
// Otherwise, SetSerializationDeterministic has been called, and the last
// value passed to it is all that matters.
void SetSerializationDeterministic(bool value) {
serialization_deterministic_is_overridden_ = true;
serialization_deterministic_override_ = value;
}
// See above. Also, note that users of this CodedOutputStream may need to
// call IsSerializationDeterminstic() to serialize in the intended way. This
// CodedOutputStream cannot enforce a desire for deterministic serialization
// by itself.
bool IsSerializationDeterminstic() const {
return serialization_deterministic_is_overridden_ ?
serialization_deterministic_override_ :
default_serialization_deterministic_;
}
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream);
@ -822,6 +860,10 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
int total_bytes_; // Sum of sizes of all buffers seen so far.
bool had_error_; // Whether an error occurred during output.
bool aliasing_enabled_; // See EnableAliasing().
// See SetSerializationDeterministic() regarding these three fields.
bool serialization_deterministic_is_overridden_;
bool serialization_deterministic_override_;
static bool default_serialization_deterministic_;
// Advance the buffer by a given number of bytes.
void Advance(int amount);
@ -849,6 +891,11 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
uint64 value, uint8* target);
static int VarintSize32Fallback(uint32 value);
// See above. Other projects may use "friend" to allow them to call this.
static void SetDefaultSerializationDeterministic() {
default_serialization_deterministic_ = true;
}
};
// inline methods ====================================================

@ -535,6 +535,32 @@ class MapEntryLite : public MessageLite {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
};
// Helpers for deterministic serialization =============================
// This struct can be used with any generic sorting algorithm. If the Key
// type is relatively small and easy to copy then copying Keys into an
// array of SortItems can be beneficial. Then all the data the sorting
// algorithm needs to touch is in that one array.
template <typename Key, typename PtrToKeyValuePair> struct SortItem {
SortItem() {}
explicit SortItem(PtrToKeyValuePair p) : first(p->first), second(p) {}
Key first;
PtrToKeyValuePair second;
};
template <typename T> struct CompareByFirstField {
bool operator()(const T& a, const T& b) const {
return a.first < b.first;
}
};
template <typename T> struct CompareByDerefFirst {
bool operator()(const T& a, const T& b) const {
return a->first < b->first;
}
};
} // namespace internal
} // namespace protobuf

@ -64,3 +64,23 @@ message TestEnumMapPlusExtra {
message TestImportEnumMap {
map<int32, protobuf_unittest_import.ImportEnumForMap> import_enum_amp = 1;
}
message TestIntIntMap {
map<int32, int32> m = 1;
}
// Test all key types: string, plus the non-floating-point scalars.
message TestMaps {
map<int32, TestIntIntMap> m_int32 = 1;
map<int64, TestIntIntMap> m_int64 = 2;
map<uint32, TestIntIntMap> m_uint32 = 3;
map<uint64, TestIntIntMap> m_uint64 = 4;
map<sint32, TestIntIntMap> m_sint32 = 5;
map<sint64, TestIntIntMap> m_sint64 = 6;
map<fixed32, TestIntIntMap> m_fixed32 = 7;
map<fixed64, TestIntIntMap> m_fixed64 = 8;
map<sfixed32, TestIntIntMap> m_sfixed32 = 9;
map<sfixed64, TestIntIntMap> m_sfixed64 = 10;
map<bool, TestIntIntMap> m_bool = 11;
map<string, TestIntIntMap> m_string = 12;
}

@ -74,6 +74,7 @@
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/util/time_util.h>
#include <google/protobuf/util/message_differencer.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <gmock/gmock.h>
@ -2869,6 +2870,82 @@ TEST(WireFormatForMapFieldTest, MapParseHelpers) {
}
}
// Deterministic Serialization Test ==========================================
template <typename T>
static string DeterministicSerialization(const T& t) {
const int size = t.ByteSize();
string result(size, '\0');
io::ArrayOutputStream array_stream(string_as_array(&result), size);
io::CodedOutputStream output_stream(&array_stream);
output_stream.SetSerializationDeterministic(true);
t.SerializeWithCachedSizes(&output_stream);
EXPECT_FALSE(output_stream.HadError());
EXPECT_EQ(size, output_stream.ByteCount());
return result;
}
// Helper to test the serialization of the first arg against a golden file.
static void TestDeterministicSerialization(const protobuf_unittest::TestMaps& t,
const string& filename) {
string expected;
GOOGLE_CHECK_OK(File::GetContents(
TestSourceDir() + "/google/protobuf/testdata/" + filename,
&expected, true));
const string actual = DeterministicSerialization(t);
EXPECT_EQ(expected, actual);
protobuf_unittest::TestMaps u;
EXPECT_TRUE(u.ParseFromString(actual));
EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(u, t));
}
// Helper for MapSerializationTest. Return a 7-bit ASCII string.
static string ConstructKey(uint64 n) {
string s(n % static_cast<uint64>(9), '\0');
if (s.empty()) {
return StrCat(n);
} else {
while (n != 0) {
s[n % s.size()] = (n >> 10) & 0x7f;
n /= 888;
}
return s;
}
}
TEST(MapSerializationTest, Deterministic) {
const int kIters = 25;
protobuf_unittest::TestMaps t;
protobuf_unittest::TestIntIntMap inner;
(*inner.mutable_m())[0] = (*inner.mutable_m())[10] =
(*inner.mutable_m())[-200] = 0;
uint64 frog = 9;
const uint64 multiplier = 0xa29cd16f;
for (int i = 0; i < kIters; i++) {
const int32 i32 = static_cast<int32>(frog & 0xffffffff);
const uint32 u32 = static_cast<uint32>(i32) * 91919;
const int64 i64 = static_cast<int64>(frog);
const uint64 u64 = frog * static_cast<uint64>(187321);
const bool b = i32 > 0;
const string s = ConstructKey(frog);
(*inner.mutable_m())[i] = i32;
(*t.mutable_m_int32())[i32] = (*t.mutable_m_sint32())[i32] =
(*t.mutable_m_sfixed32())[i32] = inner;
(*t.mutable_m_uint32())[u32] = (*t.mutable_m_fixed32())[u32] = inner;
(*t.mutable_m_int64())[i64] = (*t.mutable_m_sint64())[i64] =
(*t.mutable_m_sfixed64())[i64] = inner;
(*t.mutable_m_uint64())[u64] = (*t.mutable_m_fixed64())[u64] = inner;
(*t.mutable_m_bool())[b] = inner;
(*t.mutable_m_string())[s] = inner;
(*t.mutable_m_string())[s + string(1 << (u32 % static_cast<uint32>(9)),
b)] = inner;
inner.mutable_m()->erase(i);
frog = frog * multiplier + i;
frog ^= (frog >> 41);
}
TestDeterministicSerialization(t, "golden_message_maps");
}
// Text Format Test =================================================
TEST(TextFormatMapTest, SerializeAndParse) {

@ -166,10 +166,10 @@ class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
io::CodedOutputStream* output);
static inline uint8* InternalWriteToArray(int field,
const MapEntryAccessorType& value,
bool deterministic, uint8* output);
bool deterministic, uint8* target);
static inline uint8* WriteToArray(int field,
const MapEntryAccessorType& value,
uint8* output);
uint8* target);
// Functions to manipulate data on memory. ========================
static inline const Type& GetExternalReference(const Type* value);
@ -227,11 +227,11 @@ class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
int field, \
const MapEntryAccessorType& value, \
bool deterministic, \
uint8* output); \
uint8* target); \
static inline uint8* WriteToArray(int field, \
const MapEntryAccessorType& value, \
uint8* output) { \
return InternalWriteToArray(field, value, false, output); \
uint8* target) { \
return InternalWriteToArray(field, value, false, target); \
} \
static inline const MapEntryAccessorType& GetExternalReference( \
const TypeOnMemory& value); \
@ -374,9 +374,9 @@ template <typename Type>
inline uint8*
MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::InternalWriteToArray(
int field, const MapEntryAccessorType& value, bool deterministic,
uint8* output) {
uint8* target) {
return WireFormatLite::InternalWriteMessageToArray(field, value,
deterministic, output);
deterministic, target);
}
#define WRITE_METHOD(FieldType, DeclaredType) \
@ -390,8 +390,8 @@ MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::InternalWriteToArray(
inline uint8* \
MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
Type>::InternalWriteToArray( \
int field, const MapEntryAccessorType& value, bool, uint8* output) { \
return WireFormatLite::Write##DeclaredType##ToArray(field, value, output); \
int field, const MapEntryAccessorType& value, bool, uint8* target) { \
return WireFormatLite::Write##DeclaredType##ToArray(field, value, target); \
}
WRITE_METHOD(STRING , String)

@ -62,8 +62,6 @@ namespace protobuf {
using internal::WireFormat;
using internal::ReflectionOps;
Message::~Message() {}
void Message::MergeFrom(const Message& from) {
const Descriptor* descriptor = GetDescriptor();
GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)

@ -179,7 +179,7 @@ struct Metadata {
class LIBPROTOBUF_EXPORT Message : public MessageLite {
public:
inline Message() {}
virtual ~Message();
virtual ~Message() {}
// Basic Operations ------------------------------------------------

@ -46,8 +46,6 @@
namespace google {
namespace protobuf {
MessageLite::~MessageLite() {}
string MessageLite::InitializationErrorString() const {
return "(cannot determine missing fields for lite message)";
}

@ -81,7 +81,7 @@ namespace internal {
class LIBPROTOBUF_EXPORT MessageLite {
public:
inline MessageLite() {}
virtual ~MessageLite();
virtual ~MessageLite() {}
// Basic Operations ------------------------------------------------

@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto();
const ::google::protobuf::FileDescriptor* file =
@ -60,6 +61,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@ -73,6 +75,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fsource_5fcontext_2eproto() {
delete SourceContext_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() {
static bool already_here = false;
if (already_here) return;
@ -99,16 +102,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fsource_5fcontext_2eproto
}
} static_descriptor_initializer_google_2fprotobuf_2fsource_5fcontext_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
@ -281,7 +274,9 @@ int SourceContext::ByteSize() const {
void SourceContext::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceContext)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const SourceContext* source =
::google::protobuf::internal::DynamicCastToGenerated<const SourceContext>(
&from);
@ -296,7 +291,9 @@ void SourceContext::MergeFrom(const ::google::protobuf::Message& from) {
void SourceContext::MergeFrom(const SourceContext& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.file_name().size() > 0) {
file_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.file_name_);

@ -45,6 +45,7 @@ const ::google::protobuf::EnumDescriptor* NullValue_descriptor_ = NULL;
} // namespace
void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto();
const ::google::protobuf::FileDescriptor* file =
@ -116,6 +117,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@ -147,6 +149,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto() {
delete ListValue_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto() {
static bool already_here = false;
if (already_here) return;
@ -203,16 +206,6 @@ bool NullValue_IsValid(int value) {
}
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
@ -348,18 +341,51 @@ void Struct::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// @@protoc_insertion_point(serialize_start:google.protobuf.Struct)
// map<string, .google.protobuf.Value> fields = 1;
{
::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
it = this->fields().begin();
it != this->fields().end(); ++it) {
entry.reset(fields_.NewEntryWrapper(it->first, it->second));
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
1, *entry, output);
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
it->first.data(), it->first.length(),
::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Struct.FieldsEntry.key");
if (!this->fields().empty()) {
typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
ConstPtr;
typedef ConstPtr SortItem;
typedef ::google::protobuf::internal::CompareByDerefFirst<SortItem> Less;
struct Utf8Check {
static void Check(ConstPtr p) {
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
p->first.data(), p->first.length(),
::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Struct.FieldsEntry.key");
}
};
if (output->IsSerializationDeterminstic() &&
this->fields().size() > 1) {
::google::protobuf::scoped_array<SortItem> items(
new SortItem[this->fields().size()]);
typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::size_type size_type;
size_type n = 0;
for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
it = this->fields().begin();
it != this->fields().end(); ++it, ++n) {
items[n] = SortItem(&*it);
}
::std::sort(&items[0], &items[n], Less());
::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
for (size_type i = 0; i < n; i++) {
entry.reset(fields_.NewEntryWrapper(
items[i]->first, items[i]->second));
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
1, *entry, output);
Utf8Check::Check(items[i]);
}
} else {
::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
it = this->fields().begin();
it != this->fields().end(); ++it) {
entry.reset(fields_.NewEntryWrapper(
it->first, it->second));
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
1, *entry, output);
Utf8Check::Check(&*it);
}
}
}
@ -370,19 +396,55 @@ void Struct::SerializeWithCachedSizes(
bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct)
// map<string, .google.protobuf.Value> fields = 1;
{
::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
it = this->fields().begin();
it != this->fields().end(); ++it) {
entry.reset(fields_.NewEntryWrapper(it->first, it->second));
target = ::google::protobuf::internal::WireFormatLite::
InternalWriteMessageNoVirtualToArray(
1, *entry, false, target);
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
it->first.data(), it->first.length(),
::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Struct.FieldsEntry.key");
if (!this->fields().empty()) {
typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
ConstPtr;
typedef ConstPtr SortItem;
typedef ::google::protobuf::internal::CompareByDerefFirst<SortItem> Less;
struct Utf8Check {
static void Check(ConstPtr p) {
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
p->first.data(), p->first.length(),
::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Struct.FieldsEntry.key");
}
};
if (deterministic &&
this->fields().size() > 1) {
::google::protobuf::scoped_array<SortItem> items(
new SortItem[this->fields().size()]);
typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::size_type size_type;
size_type n = 0;
for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
it = this->fields().begin();
it != this->fields().end(); ++it, ++n) {
items[n] = SortItem(&*it);
}
::std::sort(&items[0], &items[n], Less());
::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
for (size_type i = 0; i < n; i++) {
entry.reset(fields_.NewEntryWrapper(
items[i]->first, items[i]->second));
target = ::google::protobuf::internal::WireFormatLite::
InternalWriteMessageNoVirtualToArray(
1, *entry, deterministic, target);
;
Utf8Check::Check(items[i]);
}
} else {
::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
it = this->fields().begin();
it != this->fields().end(); ++it) {
entry.reset(fields_.NewEntryWrapper(
it->first, it->second));
target = ::google::protobuf::internal::WireFormatLite::
InternalWriteMessageNoVirtualToArray(
1, *entry, deterministic, target);
;
Utf8Check::Check(&*it);
}
}
}
@ -415,7 +477,9 @@ int Struct::ByteSize() const {
void Struct::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Struct)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Struct* source =
::google::protobuf::internal::DynamicCastToGenerated<const Struct>(
&from);
@ -430,7 +494,9 @@ void Struct::MergeFrom(const ::google::protobuf::Message& from) {
void Struct::MergeFrom(const Struct& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
fields_.MergeFrom(from.fields_);
}
@ -881,7 +947,9 @@ int Value::ByteSize() const {
void Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const Value>(
&from);
@ -896,7 +964,9 @@ void Value::MergeFrom(const ::google::protobuf::Message& from) {
void Value::MergeFrom(const Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
switch (from.kind_case()) {
case kNullValue: {
set_null_value(from.null_value());
@ -1406,7 +1476,9 @@ int ListValue::ByteSize() const {
void ListValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ListValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const ListValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const ListValue>(
&from);
@ -1421,7 +1493,9 @@ void ListValue::MergeFrom(const ::google::protobuf::Message& from) {
void ListValue::MergeFrom(const ListValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
values_.MergeFrom(from.values_);
}

@ -759,6 +759,20 @@ class TextFormat::Parser::ParserImpl {
}
return true;
}
if (TryConsume("[")) {
while (true) {
if (!LookingAt("{") && !LookingAt("<")) {
DO(SkipFieldValue());
} else {
DO(SkipFieldMessage());
}
if (TryConsume("]")) {
break;
}
DO(Consume(","));
}
return true;
}
// Possible field values other than string:
// 12345 => TYPE_INTEGER
// -12345 => TYPE_SYMBOL + TYPE_INTEGER

@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto();
const ::google::protobuf::FileDescriptor* file =
@ -61,6 +62,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_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_2ftimestamp_2eproto() {
delete Timestamp_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto() {
static bool already_here = false;
if (already_here) return;
@ -101,16 +104,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2ftimestamp_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2ftimestamp_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
@ -336,7 +329,9 @@ int Timestamp::ByteSize() const {
void Timestamp::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Timestamp)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Timestamp* source =
::google::protobuf::internal::DynamicCastToGenerated<const Timestamp>(
&from);
@ -351,7 +346,9 @@ void Timestamp::MergeFrom(const ::google::protobuf::Message& from) {
void Timestamp::MergeFrom(const Timestamp& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.seconds() != 0) {
set_seconds(from.seconds());
}

@ -44,6 +44,7 @@ const ::google::protobuf::EnumDescriptor* Syntax_descriptor_ = NULL;
} // namespace
void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
const ::google::protobuf::FileDescriptor* file =
@ -159,6 +160,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@ -188,6 +190,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto() {
delete Option_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() {
static bool already_here = false;
if (already_here) return;
@ -272,16 +275,6 @@ bool Syntax_IsValid(int value) {
}
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
@ -658,7 +651,9 @@ int Type::ByteSize() const {
void Type::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Type)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Type* source =
::google::protobuf::internal::DynamicCastToGenerated<const Type>(
&from);
@ -673,7 +668,9 @@ void Type::MergeFrom(const ::google::protobuf::Message& from) {
void Type::MergeFrom(const Type& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
fields_.MergeFrom(from.fields_);
oneofs_.MergeFrom(from.oneofs_);
options_.MergeFrom(from.options_);
@ -1581,7 +1578,9 @@ int Field::ByteSize() const {
void Field::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Field)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Field* source =
::google::protobuf::internal::DynamicCastToGenerated<const Field>(
&from);
@ -1596,7 +1595,9 @@ void Field::MergeFrom(const ::google::protobuf::Message& from) {
void Field::MergeFrom(const Field& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field)
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.kind() != 0) {
set_kind(from.kind());
@ -2285,7 +2286,9 @@ int Enum::ByteSize() const {
void Enum::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Enum)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Enum* source =
::google::protobuf::internal::DynamicCastToGenerated<const Enum>(
&from);
@ -2300,7 +2303,9 @@ void Enum::MergeFrom(const ::google::protobuf::Message& from) {
void Enum::MergeFrom(const Enum& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
enumvalue_.MergeFrom(from.enumvalue_);
options_.MergeFrom(from.options_);
if (from.name().size() > 0) {
@ -2764,7 +2769,9 @@ int EnumValue::ByteSize() const {
void EnumValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const EnumValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumValue>(
&from);
@ -2779,7 +2786,9 @@ void EnumValue::MergeFrom(const ::google::protobuf::Message& from) {
void EnumValue::MergeFrom(const EnumValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue)
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) {
@ -3133,7 +3142,9 @@ int Option::ByteSize() const {
void Option::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Option)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Option* source =
::google::protobuf::internal::DynamicCastToGenerated<const Option>(
&from);
@ -3148,7 +3159,9 @@ void Option::MergeFrom(const ::google::protobuf::Message& from) {
void Option::MergeFrom(const Option& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option)
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_);

@ -69,28 +69,14 @@ const UnknownFieldSet* UnknownFieldSet::default_instance() {
return default_unknown_field_set_instance_;
}
UnknownFieldSet::UnknownFieldSet()
: fields_(NULL) {}
UnknownFieldSet::~UnknownFieldSet() {
Clear();
delete fields_;
}
void UnknownFieldSet::ClearFallback() {
if (fields_ != NULL) {
for (int i = 0; i < fields_->size(); i++) {
(*fields_)[i].Delete();
}
delete fields_;
fields_ = NULL;
}
}
void UnknownFieldSet::ClearAndFreeMemory() {
if (fields_ != NULL) {
Clear();
}
GOOGLE_DCHECK(fields_ != NULL && fields_->size() > 0);
int n = fields_->size();
do {
(*fields_)[--n].Delete();
} while (n > 0);
delete fields_;
fields_ = NULL;
}
void UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) {

@ -241,8 +241,14 @@ class LIBPROTOBUF_EXPORT UnknownField {
// ===================================================================
// inline implementations
inline UnknownFieldSet::UnknownFieldSet() : fields_(NULL) {}
inline UnknownFieldSet::~UnknownFieldSet() { Clear(); }
inline void UnknownFieldSet::ClearAndFreeMemory() { Clear(); }
inline void UnknownFieldSet::Clear() {
if (fields_) {
if (fields_ != NULL) {
ClearFallback();
}
}

@ -64,6 +64,7 @@ DefaultValueObjectWriter::DefaultValueObjectWriter(
type_(type),
current_(NULL),
root_(NULL),
suppress_empty_list_(false),
field_scrub_callback_(NULL),
ow_(ow) {}
@ -184,12 +185,10 @@ void DefaultValueObjectWriter::RegisterFieldScrubCallBack(
field_scrub_callback_.reset(field_scrub_callback.release());
}
DefaultValueObjectWriter::Node::Node(const string& name,
const google::protobuf::Type* type,
NodeKind kind, const DataPiece& data,
bool is_placeholder,
const vector<string>& path,
FieldScrubCallBack* field_scrub_callback)
DefaultValueObjectWriter::Node::Node(
const string& name, const google::protobuf::Type* type, NodeKind kind,
const DataPiece& data, bool is_placeholder, const vector<string>& path,
bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback)
: name_(name),
type_(type),
kind_(kind),
@ -197,6 +196,7 @@ DefaultValueObjectWriter::Node::Node(const string& name,
data_(data),
is_placeholder_(is_placeholder),
path_(path),
suppress_empty_list_(suppress_empty_list),
field_scrub_callback_(field_scrub_callback) {}
DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild(
@ -230,6 +230,9 @@ void DefaultValueObjectWriter::Node::WriteTo(ObjectWriter* ow) {
// Write out lists. If we didn't have any list in response, write out empty
// list.
if (kind_ == LIST) {
// Suppress empty lists if requested.
if (suppress_empty_list_ && is_placeholder_) return;
ow->StartList(name_);
WriteChildren(ow);
ow->EndList();
@ -366,7 +369,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren(
field.json_name(), field_type, kind,
kind == PRIMITIVE ? CreateDefaultDataPieceForField(field, typeinfo)
: DataPiece::NullData(),
true, path, field_scrub_callback_));
true, path, suppress_empty_list_, field_scrub_callback_));
new_children.push_back(child.release());
}
// Adds all leftover nodes in children_ to the beginning of new_child.
@ -462,7 +465,8 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
if (current_ == NULL) {
vector<string> path;
root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(),
false, path, field_scrub_callback_.get()));
false, path, suppress_empty_list_,
field_scrub_callback_.get()));
root_->PopulateChildren(typeinfo_);
current_ = root_.get();
return this;
@ -478,7 +482,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
: NULL),
OBJECT, DataPiece::NullData(), false,
child == NULL ? current_->path() : child->path(),
field_scrub_callback_.get()));
suppress_empty_list_, field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
}
@ -509,7 +513,8 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList(
if (current_ == NULL) {
vector<string> path;
root_.reset(new Node(name.ToString(), &type_, LIST, DataPiece::NullData(),
false, path, field_scrub_callback_.get()));
false, path, suppress_empty_list_,
field_scrub_callback_.get()));
current_ = root_.get();
return this;
}
@ -519,7 +524,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList(
google::protobuf::scoped_ptr<Node> node(
new Node(name.ToString(), NULL, LIST, DataPiece::NullData(), false,
child == NULL ? current_->path() : child->path(),
field_scrub_callback_.get()));
suppress_empty_list_, field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
}
@ -577,7 +582,7 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name,
google::protobuf::scoped_ptr<Node> node(
new Node(name.ToString(), NULL, PRIMITIVE, data, false,
child == NULL ? current_->path() : child->path(),
field_scrub_callback_.get()));
suppress_empty_list_, field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
} else {

@ -122,6 +122,10 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// field_scrub_callback pointer is also transferred to this class
void RegisterFieldScrubCallBack(FieldScrubCallBackPtr field_scrub_callback);
// If set to true, empty lists are suppressed from output when default values
// are written.
void set_suppress_empty_list(bool value) { suppress_empty_list_ = value; }
private:
enum NodeKind {
PRIMITIVE = 0,
@ -136,7 +140,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
public:
Node(const string& name, const google::protobuf::Type* type, NodeKind kind,
const DataPiece& data, bool is_placeholder, const vector<string>& path,
FieldScrubCallBack* field_scrub_callback);
bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback);
virtual ~Node() {
for (int i = 0; i < children_.size(); ++i) {
delete children_[i];
@ -212,6 +216,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Path of the field of this node
std::vector<string> path_;
// Whether to suppress empty list output.
bool suppress_empty_list_;
// Pointer to function for determining whether a field needs to be scrubbed
// or not. This callback is owned by the creator of this node.
FieldScrubCallBack* field_scrub_callback_;
@ -257,6 +264,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// The stack to hold the path of Nodes from current_ to root_;
std::stack<Node*> stack_;
// Whether to suppress output of empty lists.
bool suppress_empty_list_;
// Unique Pointer to function for determining whether a field needs to be
// scrubbed or not.
FieldScrubCallBackPtr field_scrub_callback_;

@ -149,6 +149,39 @@ TEST_P(DefaultValueObjectWriterTest, ShouldRetainUnknownField) {
}
class DefaultValueObjectWriterSuppressListTest
: public BaseDefaultValueObjectWriterTest {
protected:
DefaultValueObjectWriterSuppressListTest()
: BaseDefaultValueObjectWriterTest(DefaultValueTest::descriptor()) {
testing_->set_suppress_empty_list(true);
}
~DefaultValueObjectWriterSuppressListTest() {}
};
INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
DefaultValueObjectWriterSuppressListTest,
::testing::Values(
testing::USE_TYPE_RESOLVER));
TEST_P(DefaultValueObjectWriterSuppressListTest, Empty) {
// Set expectation. Emtpy lists should be suppressed.
expects_.StartObject("")
->RenderDouble("doubleValue", 0.0)
->RenderFloat("floatValue", 0.0)
->RenderInt64("int64Value", 0)
->RenderUint64("uint64Value", 0)
->RenderInt32("int32Value", 0)
->RenderUint32("uint32Value", 0)
->RenderBool("boolValue", false)
->RenderString("stringValue", "")
->RenderBytes("bytesValue", "")
->RenderString("enumValue", "ENUM_FIRST")
->EndObject();
// Actual testing
testing_->StartObject("")->EndObject();
}
} // namespace testing
} // namespace converter
} // namespace util

@ -298,7 +298,9 @@ ProtoWriter::ProtoElement::ProtoElement(const TypeInfo* typeinfo,
proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
type_(type),
size_index_(-1),
array_index_(-1) {
array_index_(-1),
// oneof_indices_ values are 1-indexed (0 means not present).
oneof_indices_(type.oneofs_size() + 1) {
if (!proto3_) {
required_fields_ = GetRequiredFields(type_);
}
@ -312,13 +314,15 @@ ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent,
ow_(this->parent()->ow_),
parent_field_(field),
typeinfo_(this->parent()->typeinfo_),
proto3_(this->parent()->proto3_),
proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
type_(type),
size_index_(
!is_list && field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE
? ow_->size_insert_.size()
: -1),
array_index_(is_list ? 0 : -1) {
array_index_(is_list ? 0 : -1),
// oneof_indices_ values are 1-indexed (0 means not present).
oneof_indices_(type_.oneofs_size() + 1) {
if (!is_list) {
if (ow_->IsRepeated(*field)) {
// Update array_index_ if it is an explicit list.
@ -411,11 +415,11 @@ string ProtoWriter::ProtoElement::ToString() const {
}
bool ProtoWriter::ProtoElement::IsOneofIndexTaken(int32 index) {
return ContainsKey(oneof_indices_, index);
return oneof_indices_[index];
}
void ProtoWriter::ProtoElement::TakeOneofIndex(int32 index) {
InsertIfNotPresent(&oneof_indices_, index);
oneof_indices_[index] = true;
}
void ProtoWriter::InvalidName(StringPiece unknown_name, StringPiece message) {
@ -573,10 +577,19 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField(
// Pushing a ProtoElement and then pop it off at the end for 2 purposes:
// error location reporting and required field accounting.
element_.reset(new ProtoElement(element_.release(), &field, type, false));
//
// For proto3, since there is no required field tracking, we only need to push
// ProtoElement for error cases.
if (!element_->proto3()) {
element_.reset(new ProtoElement(element_.release(), &field, type, false));
}
if (field.kind() == google::protobuf::Field_Kind_TYPE_UNKNOWN ||
field.kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) {
// Push a ProtoElement for location reporting purposes.
if (element_->proto3()) {
element_.reset(new ProtoElement(element_.release(), &field, type, false));
}
InvalidValue(field.type_url().empty()
? google::protobuf::Field_Kind_Name(field.kind())
: field.type_url(),
@ -657,11 +670,18 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField(
}
if (!status.ok()) {
// Push a ProtoElement for location reporting purposes.
if (element_->proto3()) {
element_.reset(new ProtoElement(element_.release(), &field, type, false));
}
InvalidValue(google::protobuf::Field_Kind_Name(field.kind()),
status.error_message());
element_.reset(element()->pop());
return this;
}
element_.reset(element()->pop());
if (!element_->proto3()) element_.reset(element()->pop());
return this;
}

@ -32,8 +32,8 @@
#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
#include <deque>
#include <google/protobuf/stubs/hash.h>
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
@ -45,6 +45,7 @@
#include <google/protobuf/util/internal/structured_objectwriter.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/stubs/bytestream.h>
#include <google/protobuf/stubs/hash.h>
namespace google {
namespace protobuf {
@ -191,6 +192,8 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter {
// generate an error.
void TakeOneofIndex(int32 index);
bool proto3() { return proto3_; }
private:
// Used for access to variables of the enclosing instance of
// ProtoWriter.
@ -203,7 +206,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter {
// TypeInfo to lookup types.
const TypeInfo* typeinfo_;
// Whether the root type is a proto3 or not.
// Whether the type_ is proto3 or not.
bool proto3_;
// Additional variables if this element is a message:
@ -221,7 +224,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter {
// Set of oneof indices already seen for the type_. Used to validate
// incoming messages so no more than one oneof is set.
hash_set<int32> oneof_indices_;
std::vector<bool> oneof_indices_;
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement);
};

@ -177,6 +177,66 @@ util::Status JsonToBinaryString(TypeResolver* resolver,
resolver, type_url, &input_stream, &output_stream, options);
}
namespace {
const char* kTypeUrlPrefix = "type.googleapis.com";
TypeResolver* generated_type_resolver_ = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(generated_type_resolver_init_);
string GetTypeUrl(const Message& message) {
return string(kTypeUrlPrefix) + "/" + message.GetDescriptor()->full_name();
}
void DeleteGeneratedTypeResolver() { delete generated_type_resolver_; }
void InitGeneratedTypeResolver() {
generated_type_resolver_ = NewTypeResolverForDescriptorPool(
kTypeUrlPrefix, DescriptorPool::generated_pool());
::google::protobuf::internal::OnShutdown(&DeleteGeneratedTypeResolver);
}
TypeResolver* GetGeneratedTypeResolver() {
::google::protobuf::GoogleOnceInit(&generated_type_resolver_init_, &InitGeneratedTypeResolver);
return generated_type_resolver_;
}
} // namespace
util::Status MessageToJsonString(const Message& message, string* output,
const JsonOptions& options) {
const DescriptorPool* pool = message.GetDescriptor()->file()->pool();
TypeResolver* resolver =
pool == DescriptorPool::generated_pool()
? GetGeneratedTypeResolver()
: NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool);
util::Status result =
BinaryToJsonString(resolver, GetTypeUrl(message),
message.SerializeAsString(), output, options);
if (pool != DescriptorPool::generated_pool()) {
delete resolver;
}
return result;
}
util::Status JsonStringToMessage(const string& input, Message* message,
const JsonParseOptions& options) {
const DescriptorPool* pool = message->GetDescriptor()->file()->pool();
TypeResolver* resolver =
pool == DescriptorPool::generated_pool()
? GetGeneratedTypeResolver()
: NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool);
string binary;
util::Status result = JsonToBinaryString(
resolver, GetTypeUrl(*message), input, &binary, options);
if (result.ok() && !message->ParseFromString(binary)) {
result =
util::Status(util::error::INVALID_ARGUMENT,
"JSON transcoder produced invalid protobuf output.");
}
if (pool != DescriptorPool::generated_pool()) {
delete resolver;
}
return result;
}
} // namespace util
} // namespace protobuf
} // namespace google

@ -33,6 +33,7 @@
#ifndef GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
#define GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
#include <google/protobuf/message.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/stubs/bytestream.h>
@ -69,13 +70,37 @@ struct JsonPrintOptions {
// DEPRECATED. Use JsonPrintOptions instead.
typedef JsonPrintOptions JsonOptions;
// Converts from protobuf message to JSON. This is a simple wrapper of
// BinaryToJsonString(). It will use the DescriptorPool of the passed-in
// message to resolve Any types.
LIBPROTOBUF_EXPORT util::Status MessageToJsonString(const Message& message,
string* output,
const JsonOptions& options);
inline util::Status MessageToJsonString(const Message& message,
string* output) {
return MessageToJsonString(message, output, JsonOptions());
}
// Converts from JSON to protobuf message. This is a simple wrapper of
// JsonStringToBinary(). It will use the DescriptorPool of the passed-in
// message to resolve Any types.
LIBPROTOBUF_EXPORT util::Status JsonStringToMessage(const string& input,
Message* message,
const JsonParseOptions& options);
inline util::Status JsonStringToMessage(const string& input,
Message* message) {
return JsonStringToMessage(input, message, JsonParseOptions());
}
// Converts protobuf binary data to JSON.
// The conversion will fail if:
// 1. TypeResolver fails to resolve a type.
// 2. input is not valid protobuf wire format, or conflicts with the type
// information returned by TypeResolver.
// Note that unknown fields will be discarded silently.
util::Status BinaryToJsonStream(
LIBPROTOBUF_EXPORT util::Status BinaryToJsonStream(
TypeResolver* resolver,
const string& type_url,
io::ZeroCopyInputStream* binary_input,
@ -110,7 +135,7 @@ inline util::Status BinaryToJsonString(TypeResolver* resolver,
// 1. TypeResolver fails to resolve a type.
// 2. input is not valid JSON format, or conflicts with the type
// information returned by TypeResolver.
util::Status JsonToBinaryStream(
LIBPROTOBUF_EXPORT util::Status JsonToBinaryStream(
TypeResolver* resolver,
const string& type_url,
io::ZeroCopyInputStream* json_input,

@ -34,6 +34,8 @@
#include <string>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor_database.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/util/json_format_proto3.pb.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/util/type_resolver_util.h>
@ -63,28 +65,21 @@ static string GetTypeUrl(const Descriptor* message) {
class JsonUtilTest : public testing::Test {
protected:
JsonUtilTest() {
resolver_.reset(NewTypeResolverForDescriptorPool(
kTypeUrlPrefix, DescriptorPool::generated_pool()));
}
string ToJson(const Message& message, const JsonPrintOptions& options) {
string result;
GOOGLE_CHECK_OK(BinaryToJsonString(resolver_.get(),
GetTypeUrl(message.GetDescriptor()),
message.SerializeAsString(), &result, options));
GOOGLE_CHECK_OK(MessageToJsonString(message, &result, options));
return result;
}
bool FromJson(const string& json, Message* message,
const JsonParseOptions& options) {
string binary;
if (!JsonToBinaryString(resolver_.get(),
GetTypeUrl(message->GetDescriptor()), json, &binary,
options)
.ok()) {
return false;
}
return message->ParseFromString(binary);
return JsonStringToMessage(json, message, options).ok();
}
bool FromJson(const string& json, Message* message) {
return FromJson(json, message, JsonParseOptions());
}
google::protobuf::scoped_ptr<TypeResolver> resolver_;
@ -189,6 +184,45 @@ TEST_F(JsonUtilTest, TestParseErrors) {
EXPECT_FALSE(FromJson("{\"int32Value\":2147483648}", &m, options));
}
TEST_F(JsonUtilTest, TestDynamicMessage) {
// Some random message but good enough to test the wrapper functions.
string input =
"{\n"
" \"int32Value\": 1024,\n"
" \"repeatedInt32Value\": [1, 2],\n"
" \"messageValue\": {\n"
" \"value\": 2048\n"
" },\n"
" \"repeatedMessageValue\": [\n"
" {\"value\": 40}, {\"value\": 96}\n"
" ]\n"
"}\n";
// Create a new DescriptorPool with the same protos as the generated one.
DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
DescriptorPool pool(&database);
// A dynamic version of the test proto.
DynamicMessageFactory factory;
google::protobuf::scoped_ptr<Message> message(factory.GetPrototype(
pool.FindMessageTypeByName("proto3.TestMessage"))->New());
EXPECT_TRUE(FromJson(input, message.get()));
// Convert to generated message for easy inspection.
TestMessage generated;
EXPECT_TRUE(generated.ParseFromString(message->SerializeAsString()));
EXPECT_EQ(1024, generated.int32_value());
ASSERT_EQ(2, generated.repeated_int32_value_size());
EXPECT_EQ(1, generated.repeated_int32_value(0));
EXPECT_EQ(2, generated.repeated_int32_value(1));
EXPECT_EQ(2048, generated.message_value().value());
ASSERT_EQ(2, generated.repeated_message_value_size());
EXPECT_EQ(40, generated.repeated_message_value(0).value());
EXPECT_EQ(96, generated.repeated_message_value(1).value());
JsonOptions options;
EXPECT_EQ(ToJson(generated, options), ToJson(*message, options));
}
typedef pair<char*, int> Segment;
// A ZeroCopyOutputStream that writes to multiple buffers.
class SegmentedZeroCopyOutputStream : public io::ZeroCopyOutputStream {

@ -466,7 +466,8 @@ void WireFormatLite::WriteGroupMaybeToArray(int field_number,
const int size = value.GetCachedSize();
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
uint8* end = value.SerializeWithCachedSizesToArray(target);
uint8* end = value.InternalSerializeWithCachedSizesToArray(
output->IsSerializationDeterminstic(), target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);
@ -482,7 +483,8 @@ void WireFormatLite::WriteMessageMaybeToArray(int field_number,
output->WriteVarint32(size);
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
uint8* end = value.SerializeWithCachedSizesToArray(target);
uint8* end = value.InternalSerializeWithCachedSizesToArray(
output->IsSerializationDeterminstic(), target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);

@ -53,6 +53,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto();
const ::google::protobuf::FileDescriptor* file =
@ -204,6 +205,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto);
}
void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@ -249,6 +251,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto() {
delete BytesValue_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() {
static bool already_here = false;
if (already_here) return;
@ -298,16 +301,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fwrappers_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fwrappers_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
@ -477,7 +470,9 @@ int DoubleValue::ByteSize() const {
void DoubleValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DoubleValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const DoubleValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const DoubleValue>(
&from);
@ -492,7 +487,9 @@ void DoubleValue::MergeFrom(const ::google::protobuf::Message& from) {
void DoubleValue::MergeFrom(const DoubleValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DoubleValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.value() != 0) {
set_value(from.value());
}
@ -735,7 +732,9 @@ int FloatValue::ByteSize() const {
void FloatValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FloatValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const FloatValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const FloatValue>(
&from);
@ -750,7 +749,9 @@ void FloatValue::MergeFrom(const ::google::protobuf::Message& from) {
void FloatValue::MergeFrom(const FloatValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FloatValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.value() != 0) {
set_value(from.value());
}
@ -995,7 +996,9 @@ int Int64Value::ByteSize() const {
void Int64Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Int64Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Int64Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const Int64Value>(
&from);
@ -1010,7 +1013,9 @@ void Int64Value::MergeFrom(const ::google::protobuf::Message& from) {
void Int64Value::MergeFrom(const Int64Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int64Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.value() != 0) {
set_value(from.value());
}
@ -1255,7 +1260,9 @@ int UInt64Value::ByteSize() const {
void UInt64Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UInt64Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const UInt64Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const UInt64Value>(
&from);
@ -1270,7 +1277,9 @@ void UInt64Value::MergeFrom(const ::google::protobuf::Message& from) {
void UInt64Value::MergeFrom(const UInt64Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt64Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.value() != 0) {
set_value(from.value());
}
@ -1515,7 +1524,9 @@ int Int32Value::ByteSize() const {
void Int32Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Int32Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const Int32Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const Int32Value>(
&from);
@ -1530,7 +1541,9 @@ void Int32Value::MergeFrom(const ::google::protobuf::Message& from) {
void Int32Value::MergeFrom(const Int32Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int32Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.value() != 0) {
set_value(from.value());
}
@ -1775,7 +1788,9 @@ int UInt32Value::ByteSize() const {
void UInt32Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UInt32Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const UInt32Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const UInt32Value>(
&from);
@ -1790,7 +1805,9 @@ void UInt32Value::MergeFrom(const ::google::protobuf::Message& from) {
void UInt32Value::MergeFrom(const UInt32Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt32Value)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.value() != 0) {
set_value(from.value());
}
@ -2033,7 +2050,9 @@ int BoolValue::ByteSize() const {
void BoolValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.BoolValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const BoolValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const BoolValue>(
&from);
@ -2048,7 +2067,9 @@ void BoolValue::MergeFrom(const ::google::protobuf::Message& from) {
void BoolValue::MergeFrom(const BoolValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BoolValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.value() != 0) {
set_value(from.value());
}
@ -2308,7 +2329,9 @@ int StringValue::ByteSize() const {
void StringValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.StringValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const StringValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const StringValue>(
&from);
@ -2323,7 +2346,9 @@ void StringValue::MergeFrom(const ::google::protobuf::Message& from) {
void StringValue::MergeFrom(const StringValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.StringValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.value().size() > 0) {
set_value(from.value());
}
@ -2623,7 +2648,9 @@ int BytesValue::ByteSize() const {
void BytesValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.BytesValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
const BytesValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const BytesValue>(
&from);
@ -2638,7 +2665,9 @@ void BytesValue::MergeFrom(const ::google::protobuf::Message& from) {
void BytesValue::MergeFrom(const BytesValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BytesValue)
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (GOOGLE_PREDICT_FALSE(&from == this)) {
::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
}
if (from.value().size() > 0) {
set_value(from.value());
}

Loading…
Cancel
Save