Merge pull request #6245 from haon4/201906111559

Down Integrate to GitHub
pull/6284/head
Hao Nguyen 6 years ago committed by GitHub
commit 61301f0155
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      java/core/src/main/java/com/google/protobuf/AbstractMessage.java
  2. 16
      java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
  3. 2
      java/core/src/main/java/com/google/protobuf/Message.java
  4. 408
      java/core/src/main/java/com/google/protobuf/TextFormat.java
  5. 4
      java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
  6. 2
      java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
  7. 2
      java/core/src/test/java/com/google/protobuf/MapTest.java
  8. 101
      java/core/src/test/java/com/google/protobuf/TextFormatTest.java
  9. 2
      java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java
  10. 22
      js/message.js
  11. 1
      protobuf.pc.in
  12. 84
      python/google/protobuf/internal/descriptor_pool_test.py
  13. 17
      python/google/protobuf/internal/json_format_test.py
  14. 16
      python/google/protobuf/json_format.py
  15. 130
      python/google/protobuf/pyext/descriptor_pool.cc
  16. 4
      python/google/protobuf/pyext/descriptor_pool.h
  17. 1
      python/setup.py
  18. 9
      src/google/protobuf/any.pb.cc
  19. 11
      src/google/protobuf/any.pb.h
  20. 37
      src/google/protobuf/api.pb.cc
  21. 53
      src/google/protobuf/api.pb.h
  22. 2
      src/google/protobuf/arena.h
  23. 4
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  24. 6
      src/google/protobuf/compiler/cpp/cpp_helpers.cc
  25. 91
      src/google/protobuf/compiler/cpp/cpp_message.cc
  26. 18
      src/google/protobuf/compiler/js/js_generator.cc
  27. 2
      src/google/protobuf/compiler/js/js_generator.h
  28. 41
      src/google/protobuf/compiler/plugin.pb.cc
  29. 54
      src/google/protobuf/compiler/plugin.pb.h
  30. 5
      src/google/protobuf/compiler/subprocess.cc
  31. 718
      src/google/protobuf/descriptor.pb.cc
  32. 707
      src/google/protobuf/descriptor.pb.h
  33. 24
      src/google/protobuf/duration.pb.cc
  34. 21
      src/google/protobuf/duration.pb.h
  35. 22
      src/google/protobuf/empty.pb.cc
  36. 15
      src/google/protobuf/empty.pb.h
  37. 3
      src/google/protobuf/extension_set_inl.h
  38. 23
      src/google/protobuf/field_mask.pb.cc
  39. 19
      src/google/protobuf/field_mask.pb.h
  40. 9
      src/google/protobuf/generated_message_util.cc
  41. 1
      src/google/protobuf/generated_message_util.h
  42. 9
      src/google/protobuf/message.cc
  43. 2
      src/google/protobuf/message.h
  44. 14
      src/google/protobuf/parse_context.cc
  45. 6
      src/google/protobuf/parse_context.h
  46. 84
      src/google/protobuf/repeated_field.h
  47. 8
      src/google/protobuf/source_context.pb.cc
  48. 9
      src/google/protobuf/source_context.pb.h
  49. 74
      src/google/protobuf/struct.pb.cc
  50. 67
      src/google/protobuf/struct.pb.h
  51. 3
      src/google/protobuf/stubs/mathutil.h
  52. 24
      src/google/protobuf/timestamp.pb.cc
  53. 21
      src/google/protobuf/timestamp.pb.h
  54. 136
      src/google/protobuf/type.pb.cc
  55. 137
      src/google/protobuf/type.pb.h
  56. 14
      src/google/protobuf/unknown_field_set.cc
  57. 7
      src/google/protobuf/unknown_field_set.h
  58. 14
      src/google/protobuf/util/field_comparator_test.cc
  59. 11
      src/google/protobuf/util/json_format.proto
  60. 12
      src/google/protobuf/util/message_differencer.cc
  61. 59
      src/google/protobuf/util/message_differencer_unittest.cc
  62. 6
      src/google/protobuf/wire_format_lite.h
  63. 207
      src/google/protobuf/wrappers.pb.cc
  64. 171
      src/google/protobuf/wrappers.pb.h

@ -108,7 +108,7 @@ public abstract class AbstractMessage
@Override
public final String toString() {
return TextFormat.printToString(this);
return TextFormat.printer().printToString(this);
}
@Override
@ -468,7 +468,7 @@ public abstract class AbstractMessage
@Override
public String toString() {
return TextFormat.printToString(this);
return TextFormat.printer().printToString(this);
}
/** Construct an UninitializedMessageException reporting missing fields in the given message. */

@ -76,6 +76,10 @@ public class ExtensionRegistryLite {
// applications. Need to support this feature on smaller granularity.
private static volatile boolean eagerlyParseMessageSets = false;
// short circuit the ExtensionRegistryFactory via assumevalues trickery
@SuppressWarnings("JavaOptionalSuggestions")
private static boolean doFullRuntimeInheritanceCheck = true;
// Visible for testing.
static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension";
@ -107,7 +111,9 @@ public class ExtensionRegistryLite {
* available.
*/
public static ExtensionRegistryLite newInstance() {
return ExtensionRegistryFactory.create();
return doFullRuntimeInheritanceCheck
? ExtensionRegistryFactory.create()
: new ExtensionRegistryLite();
}
private static volatile ExtensionRegistryLite emptyRegistry;
@ -122,7 +128,11 @@ public class ExtensionRegistryLite {
synchronized (ExtensionRegistryLite.class) {
result = emptyRegistry;
if (result == null) {
result = emptyRegistry = ExtensionRegistryFactory.createEmpty();
result =
emptyRegistry =
doFullRuntimeInheritanceCheck
? ExtensionRegistryFactory.createEmpty()
: EMPTY_REGISTRY_LITE;
}
}
}
@ -163,7 +173,7 @@ public class ExtensionRegistryLite {
if (GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom(extension.getClass())) {
add((GeneratedMessageLite.GeneratedExtension<?, ?>) extension);
}
if (ExtensionRegistryFactory.isFullRegistry(this)) {
if (doFullRuntimeInheritanceCheck && ExtensionRegistryFactory.isFullRegistry(this)) {
try {
this.getClass().getMethod("add", extensionClass).invoke(this, extension);
} catch (Exception e) {

@ -85,7 +85,7 @@ public interface Message extends MessageLite, MessageOrBuilder {
/**
* Converts the message to a string in protocol buffer text format. This is just a trivial wrapper
* around {@link TextFormat#printToString(MessageOrBuilder)}.
* around {@link TextFormat.Printer#printToString(MessageOrBuilder)}.
*/
@Override
String toString();

@ -61,135 +61,132 @@ public final class TextFormat {
* Outputs a textual representation of the Protocol Message supplied into the parameter output.
* (This representation is the new version of the classic "ProtocolPrinter" output from the
* original Protocol Buffer system)
*
* @deprecated Use {@code printer().print(MessageOrBuilder, Appendable)}
*/
@Deprecated
public static void print(final MessageOrBuilder message, final Appendable output)
throws IOException {
Printer.DEFAULT.print(message, multiLineOutput(output));
printer().print(message, output);
}
/** Outputs a textual representation of {@code fields} to {@code output}. */
/**
* Outputs a textual representation of {@code fields} to {@code output}.
*
* @deprecated Use {@code printer().print(UnknownFieldSet, Appendable)}
*/
@Deprecated
public static void print(final UnknownFieldSet fields, final Appendable output)
throws IOException {
Printer.DEFAULT.printUnknownFields(fields, multiLineOutput(output));
printer().print(fields, output);
}
/** Same as {@code print()}, except that non-ASCII characters are not escaped. */
/**
* Same as {@code print()}, except that non-ASCII characters are not escaped.
*
* @deprecated Use {@code printer().escapingNonAscii(false).print(MessageOrBuilder, Appendable)}
*/
@Deprecated
public static void printUnicode(final MessageOrBuilder message, final Appendable output)
throws IOException {
Printer.UNICODE.print(message, multiLineOutput(output));
printer().escapingNonAscii(false).print(message, output);
}
/** Same as {@code print()}, except that non-ASCII characters are not escaped. */
/**
* Same as {@code print()}, except that non-ASCII characters are not escaped.
*
* @deprecated Use {@code printer().escapingNonAscii(false).print(UnknownFieldSet, Appendable)}
*/
@Deprecated
public static void printUnicode(final UnknownFieldSet fields, final Appendable output)
throws IOException {
Printer.UNICODE.printUnknownFields(fields, multiLineOutput(output));
printer().escapingNonAscii(false).print(fields, output);
}
/**
* Generates a human readable form of this message, useful for debugging and other purposes, with
* no newline characters.
* no newline characters. This is just a trivial wrapper around
* {@link TextFormat.Printer#shortDebugString(MessageOrBuilder)}.
*/
public static String shortDebugString(final MessageOrBuilder message) {
try {
final StringBuilder text = new StringBuilder();
Printer.DEFAULT.print(message, singleLineOutput(text));
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
return printer().shortDebugString(message);
}
/**
* Generates a human readable form of the field, useful for debugging and other purposes, with no
* newline characters.
*
* @deprecated Use {@code printer().shortDebugString(FieldDescriptor, Object)}
*/
@Deprecated
public static String shortDebugString(final FieldDescriptor field, final Object value) {
try {
final StringBuilder text = new StringBuilder();
Printer.DEFAULT.printField(field, value, singleLineOutput(text));
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
return printer().shortDebugString(field, value);
}
/**
* Generates a human readable form of the unknown fields, useful for debugging and other purposes,
* with no newline characters.
*
* @deprecated Use {@code printer().shortDebugString(UnknownFieldSet)}
*/
@Deprecated
public static String shortDebugString(final UnknownFieldSet fields) {
try {
final StringBuilder text = new StringBuilder();
Printer.DEFAULT.printUnknownFields(fields, singleLineOutput(text));
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
return printer().shortDebugString(fields);
}
/** Like {@code print()}, but writes directly to a {@code String} and returns it. */
/**
* Like {@code print()}, but writes directly to a {@code String} and returns it.
*
* @deprecated Use {@link MessageOrBuilder#toString()}
*/
@Deprecated
public static String printToString(final MessageOrBuilder message) {
try {
final StringBuilder text = new StringBuilder();
print(message, text);
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
return printer().printToString(message);
}
/** Like {@code print()}, but writes directly to a {@code String} and returns it. */
/**
* Like {@code print()}, but writes directly to a {@code String} and returns it.
*
* @deprecated Use {@link UnknownFieldSet#toString()}
*/
@Deprecated
public static String printToString(final UnknownFieldSet fields) {
try {
final StringBuilder text = new StringBuilder();
print(fields, text);
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
return printer().printToString(fields);
}
/**
* Same as {@code printToString()}, except that non-ASCII characters in string type fields are not
* escaped in backslash+octals.
*
* @deprecated Use {@code printer().escapingNonAscii(false).printToString(MessageOrBuilder)}
*/
@Deprecated
public static String printToUnicodeString(final MessageOrBuilder message) {
try {
final StringBuilder text = new StringBuilder();
Printer.UNICODE.print(message, multiLineOutput(text));
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
return printer().escapingNonAscii(false).printToString(message);
}
/**
* Same as {@code printToString()}, except that non-ASCII characters in string type fields are not
* escaped in backslash+octals.
*
* @deprecated Use {@code printer().escapingNonAscii(false).printToString(UnknownFieldSet)}
*/
@Deprecated
public static String printToUnicodeString(final UnknownFieldSet fields) {
try {
final StringBuilder text = new StringBuilder();
Printer.UNICODE.printUnknownFields(fields, multiLineOutput(text));
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
return printer().escapingNonAscii(false).printToString(fields);
}
/** @deprecated Use {@code printer().printField(FieldDescriptor, Object, Appendable)} */
@Deprecated
public static void printField(
final FieldDescriptor field, final Object value, final Appendable output) throws IOException {
Printer.DEFAULT.printField(field, value, multiLineOutput(output));
printer().printField(field, value, output);
}
/** @deprecated Use {@code printer().printFieldToString(FieldDescriptor, Object)} */
@Deprecated
public static String printFieldToString(final FieldDescriptor field, final Object value) {
try {
final StringBuilder text = new StringBuilder();
printField(field, value, text);
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
return printer().printFieldToString(field, value);
}
/**
@ -198,29 +195,34 @@ public final class TextFormat {
* <p>Same as {@code printFieldValue()}, except that non-ASCII characters in string type fields
* are not escaped in backslash+octals.
*
* @deprecated Use {@code printer().escapingNonAscii(false).printFieldValue(FieldDescriptor,
* Object, Appendable)}
* @param field the descriptor of the field
* @param value the value of the field
* @param output the output to which to append the formatted value
* @throws ClassCastException if the value is not appropriate for the given field descriptor
* @throws IOException if there is an exception writing to the output
*/
@Deprecated
public static void printUnicodeFieldValue(
final FieldDescriptor field, final Object value, final Appendable output) throws IOException {
Printer.UNICODE.printFieldValue(field, value, multiLineOutput(output));
printer().escapingNonAscii(false).printFieldValue(field, value, output);
}
/**
* Outputs a textual representation of the value of given field value.
*
* @deprecated Use {@code printer().printFieldValue(FieldDescriptor, Object, Appendable)}
* @param field the descriptor of the field
* @param value the value of the field
* @param output the output to which to append the formatted value
* @throws ClassCastException if the value is not appropriate for the given field descriptor
* @throws IOException if there is an exception writing to the output
*/
@Deprecated
public static void printFieldValue(
final FieldDescriptor field, final Object value, final Appendable output) throws IOException {
Printer.DEFAULT.printFieldValue(field, value, multiLineOutput(output));
printer().printFieldValue(field, value, output);
}
/**
@ -256,7 +258,7 @@ public final class TextFormat {
generator.print("{");
generator.eol();
generator.indent();
Printer.DEFAULT.printUnknownFields(message, generator);
Printer.printUnknownFields(message, generator);
generator.outdent();
generator.print("}");
} catch (InvalidProtocolBufferException e) {
@ -267,19 +269,23 @@ public final class TextFormat {
}
break;
case WireFormat.WIRETYPE_START_GROUP:
Printer.DEFAULT.printUnknownFields((UnknownFieldSet) value, generator);
Printer.printUnknownFields((UnknownFieldSet) value, generator);
break;
default:
throw new IllegalArgumentException("Bad tag: " + tag);
}
}
/** Printer instance which escapes non-ASCII characters. */
public static Printer printer() {
return Printer.DEFAULT;
}
/** Helper class for converting protobufs to text. */
private static final class Printer {
public static final class Printer {
// Printer instance which escapes non-ASCII characters.
static final Printer DEFAULT = new Printer(true);
// Printer instance which emits Unicode (it still escapes newlines and quotes in strings).
static final Printer UNICODE = new Printer(false);
private static final Printer DEFAULT = new Printer(true);
/** Whether to escape non ASCII characters with backslash and octal. */
private final boolean escapeNonAscii;
@ -288,12 +294,51 @@ public final class TextFormat {
this.escapeNonAscii = escapeNonAscii;
}
/**
* Return a new Printer instance with the specified escape mode.
*
* @param escapeNonAscii If true, the new Printer will escape non-ASCII characters (this is the
* default behavior. If false, the new Printer will print non-ASCII characters as is. In
* either case, the new Printer still escapes newlines and quotes in strings.
* @return a new Printer that clones all other configurations from the current {@link Printer},
* with the escape mode set to the given parameter.
*/
public Printer escapingNonAscii(boolean escapeNonAscii) {
return new Printer(escapeNonAscii);
}
/**
* Outputs a textual representation of the Protocol Message supplied into the parameter output.
* (This representation is the new version of the classic "ProtocolPrinter" output from the
* original Protocol Buffer system)
*/
public void print(final MessageOrBuilder message, final Appendable output) throws IOException {
print(message, multiLineOutput(output));
}
/** Outputs a textual representation of {@code fields} to {@code output}. */
public void print(final UnknownFieldSet fields, final Appendable output) throws IOException {
printUnknownFields(fields, multiLineOutput(output));
}
private void print(final MessageOrBuilder message, final TextGenerator generator)
throws IOException {
for (Map.Entry<FieldDescriptor, Object> field : message.getAllFields().entrySet()) {
printField(field.getKey(), field.getValue(), generator);
printMessage(message, generator);
}
public String printFieldToString(final FieldDescriptor field, final Object value) {
try {
final StringBuilder text = new StringBuilder();
printField(field, value, text);
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
printUnknownFields(message.getUnknownFields(), generator);
}
public void printField(final FieldDescriptor field, final Object value, final Appendable output)
throws IOException {
printField(field, value, multiLineOutput(output));
}
private void printField(
@ -309,46 +354,19 @@ public final class TextFormat {
}
}
private void printSingleField(
final FieldDescriptor field, final Object value, final TextGenerator generator)
/**
* Outputs a textual representation of the value of given field value.
*
* @param field the descriptor of the field
* @param value the value of the field
* @param output the output to which to append the formatted value
* @throws ClassCastException if the value is not appropriate for the given field descriptor
* @throws IOException if there is an exception writing to the output
*/
public void printFieldValue(
final FieldDescriptor field, final Object value, final Appendable output)
throws IOException {
if (field.isExtension()) {
generator.print("[");
// We special-case MessageSet elements for compatibility with proto1.
if (field.getContainingType().getOptions().getMessageSetWireFormat()
&& (field.getType() == FieldDescriptor.Type.MESSAGE)
&& (field.isOptional())
// object equality
&& (field.getExtensionScope() == field.getMessageType())) {
generator.print(field.getMessageType().getFullName());
} else {
generator.print(field.getFullName());
}
generator.print("]");
} else {
if (field.getType() == FieldDescriptor.Type.GROUP) {
// Groups must be serialized with their original capitalization.
generator.print(field.getMessageType().getName());
} else {
generator.print(field.getName());
}
}
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
generator.print(" {");
generator.eol();
generator.indent();
} else {
generator.print(": ");
}
printFieldValue(field, value, generator);
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
generator.outdent();
generator.print("}");
}
generator.eol();
printFieldValue(field, value, multiLineOutput(output));
}
private void printFieldValue(
@ -419,7 +437,157 @@ public final class TextFormat {
}
}
private void printUnknownFields(
/** Like {@code print()}, but writes directly to a {@code String} and returns it. */
public String printToString(final MessageOrBuilder message) {
try {
final StringBuilder text = new StringBuilder();
print(message, text);
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
/** Like {@code print()}, but writes directly to a {@code String} and returns it. */
public String printToString(final UnknownFieldSet fields) {
try {
final StringBuilder text = new StringBuilder();
print(fields, text);
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
/**
* Generates a human readable form of this message, useful for debugging and other purposes,
* with no newline characters.
*/
public String shortDebugString(final MessageOrBuilder message) {
try {
final StringBuilder text = new StringBuilder();
print(message, singleLineOutput(text));
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
/**
* Generates a human readable form of the field, useful for debugging and other purposes, with
* no newline characters.
*/
public String shortDebugString(final FieldDescriptor field, final Object value) {
try {
final StringBuilder text = new StringBuilder();
printField(field, value, singleLineOutput(text));
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
/**
* Generates a human readable form of the unknown fields, useful for debugging and other
* purposes, with no newline characters.
*/
public String shortDebugString(final UnknownFieldSet fields) {
try {
final StringBuilder text = new StringBuilder();
printUnknownFields(fields, singleLineOutput(text));
return text.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
private static void printUnknownFieldValue(
final int tag, final Object value, final TextGenerator generator) throws IOException {
switch (WireFormat.getTagWireType(tag)) {
case WireFormat.WIRETYPE_VARINT:
generator.print(unsignedToString((Long) value));
break;
case WireFormat.WIRETYPE_FIXED32:
generator.print(String.format((Locale) null, "0x%08x", (Integer) value));
break;
case WireFormat.WIRETYPE_FIXED64:
generator.print(String.format((Locale) null, "0x%016x", (Long) value));
break;
case WireFormat.WIRETYPE_LENGTH_DELIMITED:
try {
// Try to parse and print the field as an embedded message
UnknownFieldSet message = UnknownFieldSet.parseFrom((ByteString) value);
generator.print("{");
generator.eol();
generator.indent();
printUnknownFields(message, generator);
generator.outdent();
generator.print("}");
} catch (InvalidProtocolBufferException e) {
// If not parseable as a message, print as a String
generator.print("\"");
generator.print(escapeBytes((ByteString) value));
generator.print("\"");
}
break;
case WireFormat.WIRETYPE_START_GROUP:
printUnknownFields((UnknownFieldSet) value, generator);
break;
default:
throw new IllegalArgumentException("Bad tag: " + tag);
}
}
private void printMessage(final MessageOrBuilder message, final TextGenerator generator)
throws IOException {
for (Map.Entry<FieldDescriptor, Object> field : message.getAllFields().entrySet()) {
printField(field.getKey(), field.getValue(), generator);
}
printUnknownFields(message.getUnknownFields(), generator);
}
private void printSingleField(
final FieldDescriptor field, final Object value, final TextGenerator generator)
throws IOException {
if (field.isExtension()) {
generator.print("[");
// We special-case MessageSet elements for compatibility with proto1.
if (field.getContainingType().getOptions().getMessageSetWireFormat()
&& (field.getType() == FieldDescriptor.Type.MESSAGE)
&& (field.isOptional())
// object equality
&& (field.getExtensionScope() == field.getMessageType())) {
generator.print(field.getMessageType().getFullName());
} else {
generator.print(field.getFullName());
}
generator.print("]");
} else {
if (field.getType() == FieldDescriptor.Type.GROUP) {
// Groups must be serialized with their original capitalization.
generator.print(field.getMessageType().getName());
} else {
generator.print(field.getName());
}
}
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
generator.print(" {");
generator.eol();
generator.indent();
} else {
generator.print(": ");
}
printFieldValue(field, value, generator);
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
generator.outdent();
generator.print("}");
}
generator.eol();
}
private static void printUnknownFields(
final UnknownFieldSet unknownFields, final TextGenerator generator) throws IOException {
for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.asMap().entrySet()) {
final int number = entry.getKey();
@ -445,7 +613,7 @@ public final class TextFormat {
}
}
private void printUnknownField(
private static void printUnknownField(
final int number, final int wireType, final List<?> values, final TextGenerator generator)
throws IOException {
for (final Object value : values) {
@ -1994,7 +2162,7 @@ public final class TextFormat {
return escapeBytes(ByteString.copyFromUtf8(input));
}
/** Escape double quotes and backslashes in a String for unicode output of a message. */
/** Escape double quotes and backslashes in a String for emittingUnicode output of a message. */
public static String escapeDoubleQuotesAndBackslashes(final String input) {
return TextFormatEscaper.escapeDoubleQuotesAndBackslashes(input);
}

@ -140,11 +140,11 @@ public final class UnknownFieldSet implements MessageLite {
/**
* Converts the set to a string in protocol buffer text format. This is just a trivial wrapper
* around {@link TextFormat#printToString(UnknownFieldSet)}.
* around {@link TextFormat.Printer#printToString(UnknownFieldSet)}.
*/
@Override
public String toString() {
return TextFormat.printToString(this);
return TextFormat.printer().printToString(this);
}
/**

@ -766,7 +766,7 @@ public class MapForProto2Test extends TestCase {
setMapValuesUsingAccessors(builder);
TestMap message = builder.build();
String textData = TextFormat.printToString(message);
String textData = TextFormat.printer().printToString(message);
builder = TestMap.newBuilder();
TextFormat.merge(textData, builder);

@ -857,7 +857,7 @@ public class MapTest extends TestCase {
setMapValuesUsingAccessors(builder);
TestMap message = builder.build();
String textData = TextFormat.printToString(message);
String textData = TextFormat.printer().printToString(message);
builder = TestMap.newBuilder();
TextFormat.merge(textData, builder);

@ -147,7 +147,7 @@ public class TextFormatTest extends TestCase {
/** Print TestAllTypes and compare with golden file. */
public void testPrintMessage() throws Exception {
String javaText = TextFormat.printToString(TestUtil.getAllSet());
String javaText = TextFormat.printer().printToString(TestUtil.getAllSet());
// Java likes to add a trailing ".0" to floats and doubles. C printf
// (with %g format) does not. Our golden files are used for both
@ -159,7 +159,7 @@ public class TextFormatTest extends TestCase {
/** Print TestAllTypes as Builder and compare with golden file. */
public void testPrintMessageBuilder() throws Exception {
String javaText = TextFormat.printToString(TestUtil.getAllSetBuilder());
String javaText = TextFormat.printer().printToString(TestUtil.getAllSetBuilder());
// Java likes to add a trailing ".0" to floats and doubles. C printf
// (with %g format) does not. Our golden files are used for both
@ -171,7 +171,7 @@ public class TextFormatTest extends TestCase {
/** Print TestAllExtensions and compare with golden file. */
public void testPrintExtensions() throws Exception {
String javaText = TextFormat.printToString(TestUtil.getAllExtensionsSet());
String javaText = TextFormat.printer().printToString(TestUtil.getAllExtensionsSet());
// Java likes to add a trailing ".0" to floats and doubles. C printf
// (with %g format) does not. Our golden files are used for both
@ -237,12 +237,13 @@ public class TextFormatTest extends TestCase {
+ "15: 12379813812177893520\n"
+ "15: 0xabcd1234\n"
+ "15: 0xabcdef1234567890\n",
TextFormat.printToString(message));
TextFormat.printer().printToString(message));
}
public void testPrintField() throws Exception {
final FieldDescriptor dataField = OneString.getDescriptor().findFieldByName("data");
assertEquals("data: \"test data\"\n", TextFormat.printFieldToString(dataField, "test data"));
assertEquals(
"data: \"test data\"\n", TextFormat.printer().printFieldToString(dataField, "test data"));
final FieldDescriptor optionalField =
TestAllTypes.getDescriptor().findFieldByName("optional_nested_message");
@ -250,7 +251,7 @@ public class TextFormatTest extends TestCase {
assertEquals(
"optional_nested_message {\n bb: 42\n}\n",
TextFormat.printFieldToString(optionalField, value));
TextFormat.printer().printFieldToString(optionalField, value));
}
/**
@ -885,7 +886,8 @@ public class TextFormatTest extends TestCase {
private void assertPrintFieldValue(String expect, Object value, String fieldName)
throws Exception {
StringBuilder sb = new StringBuilder();
TextFormat.printFieldValue(TestAllTypes.getDescriptor().findFieldByName(fieldName), value, sb);
TextFormat.printer()
.printFieldValue(TestAllTypes.getDescriptor().findFieldByName(fieldName), value, sb);
assertEquals(expect, sb.toString());
}
@ -902,14 +904,17 @@ public class TextFormatTest extends TestCase {
public void testShortDebugString_field() {
final FieldDescriptor dataField = OneString.getDescriptor().findFieldByName("data");
assertEquals("data: \"test data\"", TextFormat.shortDebugString(dataField, "test data"));
assertEquals(
"data: \"test data\"",
TextFormat.printer().shortDebugString(dataField, "test data"));
final FieldDescriptor optionalField =
TestAllTypes.getDescriptor().findFieldByName("optional_nested_message");
final Object value = NestedMessage.newBuilder().setBb(42).build();
assertEquals(
"optional_nested_message { bb: 42 }", TextFormat.shortDebugString(optionalField, value));
"optional_nested_message { bb: 42 }",
TextFormat.printer().shortDebugString(optionalField, value));
}
public void testShortDebugString_unknown() {
@ -917,7 +922,7 @@ public class TextFormatTest extends TestCase {
"5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5: { 12: 6 } 5 { 10: 5 }"
+ " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:"
+ " 0xabcdef1234567890",
TextFormat.shortDebugString(makeUnknownFieldSet()));
TextFormat.printer().shortDebugString(makeUnknownFieldSet()));
}
public void testPrintToUnicodeString() throws Exception {
@ -925,23 +930,26 @@ public class TextFormatTest extends TestCase {
"optional_string: \"abc\u3042efg\"\n"
+ "optional_bytes: \"\\343\\201\\202\"\n"
+ "repeated_string: \"\u3093XYZ\"\n",
TextFormat.printToUnicodeString(
TestAllTypes.newBuilder()
.setOptionalString("abc\u3042efg")
.setOptionalBytes(bytes(0xe3, 0x81, 0x82))
.addRepeatedString("\u3093XYZ")
.build()));
TextFormat.printer()
.escapingNonAscii(false)
.printToString(
TestAllTypes.newBuilder()
.setOptionalString("abc\u3042efg")
.setOptionalBytes(bytes(0xe3, 0x81, 0x82))
.addRepeatedString("\u3093XYZ")
.build()));
// Double quotes and backslashes should be escaped
assertEquals(
"optional_string: \"a\\\\bc\\\"ef\\\"g\"\n",
TextFormat.printToUnicodeString(
TestAllTypes.newBuilder().setOptionalString("a\\bc\"ef\"g").build()));
TextFormat.printer()
.escapingNonAscii(false)
.printToString(TestAllTypes.newBuilder().setOptionalString("a\\bc\"ef\"g").build()));
// Test escaping roundtrip
TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("a\\bc\\\"ef\"g").build();
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
TextFormat.merge(TextFormat.printToUnicodeString(message), builder);
TextFormat.merge(TextFormat.printer().escapingNonAscii(false).printToString(message), builder);
assertEquals(message.getOptionalString(), builder.getOptionalString());
}
@ -949,48 +957,61 @@ public class TextFormatTest extends TestCase {
// No newlines at start and end
assertEquals(
"optional_string: \"test newlines\\n\\nin\\nstring\"\n",
TextFormat.printToUnicodeString(
TestAllTypes.newBuilder().setOptionalString("test newlines\n\nin\nstring").build()));
TextFormat.printer()
.escapingNonAscii(false)
.printToString(
TestAllTypes.newBuilder()
.setOptionalString("test newlines\n\nin\nstring")
.build()));
// Newlines at start and end
assertEquals(
"optional_string: \"\\ntest\\nnewlines\\n\\nin\\nstring\\n\"\n",
TextFormat.printToUnicodeString(
TestAllTypes.newBuilder()
.setOptionalString("\ntest\nnewlines\n\nin\nstring\n")
.build()));
TextFormat.printer()
.escapingNonAscii(false)
.printToString(
TestAllTypes.newBuilder()
.setOptionalString("\ntest\nnewlines\n\nin\nstring\n")
.build()));
// Strings with 0, 1 and 2 newlines.
assertEquals(
"optional_string: \"\"\n",
TextFormat.printToUnicodeString(TestAllTypes.newBuilder().setOptionalString("").build()));
TextFormat.printer()
.escapingNonAscii(false)
.printToString(TestAllTypes.newBuilder().setOptionalString("").build()));
assertEquals(
"optional_string: \"\\n\"\n",
TextFormat.printToUnicodeString(TestAllTypes.newBuilder().setOptionalString("\n").build()));
TextFormat.printer()
.escapingNonAscii(false)
.printToString(TestAllTypes.newBuilder().setOptionalString("\n").build()));
assertEquals(
"optional_string: \"\\n\\n\"\n",
TextFormat.printToUnicodeString(
TestAllTypes.newBuilder().setOptionalString("\n\n").build()));
TextFormat.printer()
.escapingNonAscii(false)
.printToString(TestAllTypes.newBuilder().setOptionalString("\n\n").build()));
// Test escaping roundtrip
TestAllTypes message =
TestAllTypes.newBuilder().setOptionalString("\ntest\nnewlines\n\nin\nstring\n").build();
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
TextFormat.merge(TextFormat.printToUnicodeString(message), builder);
TextFormat.merge(TextFormat.printer().escapingNonAscii(false).printToString(message), builder);
assertEquals(message.getOptionalString(), builder.getOptionalString());
}
public void testPrintToUnicodeString_unknown() {
assertEquals(
"1: \"\\343\\201\\202\"\n",
TextFormat.printToUnicodeString(
UnknownFieldSet.newBuilder()
.addField(
1,
UnknownFieldSet.Field.newBuilder()
.addLengthDelimited(bytes(0xe3, 0x81, 0x82))
.build())
.build()));
TextFormat.printer()
.escapingNonAscii(false)
.printToString(
UnknownFieldSet.newBuilder()
.addField(
1,
UnknownFieldSet.Field.newBuilder()
.addLengthDelimited(bytes(0xe3, 0x81, 0x82))
.build())
.build()));
}
@ -1120,7 +1141,7 @@ public class TextFormatTest extends TestCase {
TestUtil.setOneof(builder);
TestOneof2 message = builder.build();
TestOneof2.Builder dest = TestOneof2.newBuilder();
TextFormat.merge(TextFormat.printToUnicodeString(message), dest);
TextFormat.merge(TextFormat.printer().escapingNonAscii(false).printToString(message), dest);
TestUtil.assertOneofSet(dest.build());
}
@ -1159,7 +1180,7 @@ public class TextFormatTest extends TestCase {
.putInt32ToStringField(20, "banana")
.putInt32ToStringField(30, "cherry")
.build();
String text = TextFormat.printToUnicodeString(message);
String text = TextFormat.printer().escapingNonAscii(false).printToString(message);
{
TestMap.Builder dest = TestMap.newBuilder();
TextFormat.merge(text, dest);

@ -234,7 +234,7 @@ public class UnknownEnumValueTest extends TestCase {
TestAllTypes message = builder.build();
// We can print a message with unknown enum values.
String textData = TextFormat.printToString(message);
String textData = TextFormat.printer().printToString(message);
assertEquals(
"optional_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_4321\n"
+ "repeated_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_5432\n"

@ -958,19 +958,19 @@ jspb.Message.getMapField = function(msg, fieldNumber, noLazyCreate,
// If we already have a map in the map wrappers, return that.
if (fieldNumber in msg.wrappers_) {
return msg.wrappers_[fieldNumber];
} else if (noLazyCreate) {
return undefined;
} else {
// Wrap the underlying elements array with a Map.
var arr = jspb.Message.getField(msg, fieldNumber);
if (!arr) {
arr = [];
jspb.Message.setField(msg, fieldNumber, arr);
}
var arr = jspb.Message.getField(msg, fieldNumber);
// Wrap the underlying elements array with a Map.
if (!arr) {
if (noLazyCreate) {
return undefined;
}
return msg.wrappers_[fieldNumber] =
new jspb.Map(
/** @type {!Array<!Array<!Object>>} */ (arr), opt_valueCtor);
arr = [];
jspb.Message.setField(msg, fieldNumber, arr);
}
return msg.wrappers_[fieldNumber] =
new jspb.Map(
/** @type {!Array<!Array<!Object>>} */ (arr), opt_valueCtor);
};

@ -8,5 +8,6 @@ Description: Google's Data Interchange Format
Version: @VERSION@
Libs: -L${libdir} -lprotobuf @PTHREAD_LIBS@
Libs.private: @LIBS@
Cflags: -I${includedir} @PTHREAD_CFLAGS@
Conflicts: protobuf-lite

@ -615,18 +615,86 @@ class SecondaryDescriptorFromDescriptorDB(DescriptorPoolTestBase,
factory_test1_pb2.DESCRIPTOR.serialized_pb)
self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
factory_test2_pb2.DESCRIPTOR.serialized_pb)
db = descriptor_database.DescriptorDatabase()
db.Add(self.factory_test1_fd)
db.Add(self.factory_test2_fd)
db.Add(descriptor_pb2.FileDescriptorProto.FromString(
self.db = descriptor_database.DescriptorDatabase()
self.db.Add(self.factory_test1_fd)
self.db.Add(self.factory_test2_fd)
self.db.Add(descriptor_pb2.FileDescriptorProto.FromString(
unittest_import_public_pb2.DESCRIPTOR.serialized_pb))
db.Add(descriptor_pb2.FileDescriptorProto.FromString(
self.db.Add(descriptor_pb2.FileDescriptorProto.FromString(
unittest_import_pb2.DESCRIPTOR.serialized_pb))
db.Add(descriptor_pb2.FileDescriptorProto.FromString(
self.db.Add(descriptor_pb2.FileDescriptorProto.FromString(
unittest_pb2.DESCRIPTOR.serialized_pb))
db.Add(descriptor_pb2.FileDescriptorProto.FromString(
self.db.Add(descriptor_pb2.FileDescriptorProto.FromString(
no_package_pb2.DESCRIPTOR.serialized_pb))
self.pool = descriptor_pool.DescriptorPool(descriptor_db=db)
self.pool = descriptor_pool.DescriptorPool(descriptor_db=self.db)
def testErrorCollector(self):
file_proto = descriptor_pb2.FileDescriptorProto()
file_proto.package = 'collector'
file_proto.name = 'error_file'
message_type = file_proto.message_type.add()
message_type.name = 'ErrorMessage'
field = message_type.field.add()
field.number = 1
field.name = 'nested_message_field'
field.label = descriptor.FieldDescriptor.LABEL_OPTIONAL
field.type = descriptor.FieldDescriptor.TYPE_MESSAGE
field.type_name = 'SubMessage'
oneof = message_type.oneof_decl.add()
oneof.name = 'MyOneof'
enum_type = file_proto.enum_type.add()
enum_type.name = 'MyEnum'
enum_value = enum_type.value.add()
enum_value.name = 'MyEnumValue'
enum_value.number = 0
self.db.Add(file_proto)
self.assertRaisesRegexp(KeyError, 'SubMessage',
self.pool.FindMessageTypeByName,
'collector.ErrorMessage')
self.assertRaisesRegexp(KeyError, 'SubMessage',
self.pool.FindFileByName, 'error_file')
with self.assertRaises(KeyError) as exc:
self.pool.FindFileByName('none_file')
self.assertIn(str(exc.exception), ('\'none_file\'',
'\"Couldn\'t find file none_file\"'))
# Pure python _ConvertFileProtoToFileDescriptor() method has side effect
# that all the symbols found in the file will load into the pool even the
# file can not build. So when FindMessageTypeByName('ErrorMessage') was
# called the first time, a KeyError will be raised but call the find
# method later will return a descriptor which is not build.
# TODO(jieluo): fix pure python to revert the load if file can not be build
if api_implementation.Type() == 'cpp':
error_msg = ('Invalid proto descriptor for file "error_file":\\n '
'collector.ErrorMessage.nested_message_field: "SubMessage" '
'is not defined.\\n collector.ErrorMessage.MyOneof: Oneof '
'must have at least one field.\\n\'')
with self.assertRaises(KeyError) as exc:
self.pool.FindMessageTypeByName('collector.ErrorMessage')
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for '
'message collector.ErrorMessage\\n' + error_msg)
with self.assertRaises(KeyError) as exc:
self.pool.FindFieldByName('collector.ErrorMessage.nested_message_field')
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for field'
' collector.ErrorMessage.nested_message_field\\n'
+ error_msg)
with self.assertRaises(KeyError) as exc:
self.pool.FindEnumTypeByName('collector.MyEnum')
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for enum'
' collector.MyEnum\\n' + error_msg)
with self.assertRaises(KeyError) as exc:
self.pool.FindFileContainingSymbol('collector.MyEnumValue')
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for symbol'
' collector.MyEnumValue\\n' + error_msg)
with self.assertRaises(KeyError) as exc:
self.pool.FindOneofByName('collector.ErrorMessage.MyOneof')
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for oneof'
' collector.ErrorMessage.MyOneof\\n' + error_msg)
class ProtoFile(object):

@ -54,6 +54,7 @@ from google.protobuf import unittest_mset_pb2
from google.protobuf import unittest_pb2
from google.protobuf import descriptor_pool
from google.protobuf import json_format
from google.protobuf.util import json_format_pb2
from google.protobuf.util import json_format_proto3_pb2
@ -247,6 +248,22 @@ class JsonFormatTest(JsonFormatBase):
}
self.assertEqual(golden_dict, message_dict)
def testExtensionSerializationDictMatchesProto3SpecMore(self):
"""See go/proto3-json-spec for spec.
"""
message = json_format_pb2.TestMessageWithExtension()
ext = json_format_pb2.TestExtension.ext
message.Extensions[ext].value = 'stuff'
message_dict = json_format.MessageToDict(
message
)
expected_dict = {
'[protobuf_unittest.TestExtension.ext]': {
'value': u'stuff',
},
}
self.assertEqual(expected_dict, message_dict)
def testExtensionSerializationJsonMatchesProto3Spec(self):
"""See go/proto3-json-spec for spec.

@ -233,12 +233,8 @@ class _Printer(object):
js[name] = [self._FieldToJsonObject(field, k)
for k in value]
elif field.is_extension:
f = field
if (f.containing_type.GetOptions().message_set_wire_format and
f.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
f.label == descriptor.FieldDescriptor.LABEL_OPTIONAL):
f = f.message_type
name = '[%s.%s]' % (f.full_name, name)
full_qualifier = field.full_name[:-len(field.name)]
name = '[%s%s]' % (full_qualifier, name)
js[name] = self._FieldToJsonObject(field, value)
else:
js[name] = self._FieldToJsonObject(field, value)
@ -493,10 +489,16 @@ class _Parser(object):
raise ParseError('Message type {0} does not have extensions'.format(
message_descriptor.full_name))
identifier = name[1:-1] # strip [] brackets
identifier = '.'.join(identifier.split('.')[:-1])
# pylint: disable=protected-access
field = message.Extensions._FindExtensionByName(identifier)
# pylint: enable=protected-access
if not field:
# Try looking for extension by the message type name, dropping the
# field name following the final . separator in full_name.
identifier = '.'.join(identifier.split('.')[:-1])
# pylint: disable=protected-access
field = message.Extensions._FindExtensionByName(identifier)
# pylint: enable=protected-access
if not field:
if self.ignore_unknown_fields:
continue

@ -67,6 +67,38 @@ static std::unordered_map<const DescriptorPool*, PyDescriptorPool*>*
namespace cdescriptor_pool {
// Collects errors that occur during proto file building to allow them to be
// propagated in the python exception instead of only living in ERROR logs.
class BuildFileErrorCollector : public DescriptorPool::ErrorCollector {
public:
BuildFileErrorCollector() : error_message(""), had_errors_(false) {}
void AddError(const string& filename, const string& element_name,
const Message* descriptor, ErrorLocation location,
const string& message) override {
// Replicates the logging behavior that happens in the C++ implementation
// when an error collector is not passed in.
if (!had_errors_) {
error_message +=
("Invalid proto descriptor for file \"" + filename + "\":\n");
had_errors_ = true;
}
// As this only happens on failure and will result in the program not
// running at all, no effort is made to optimize this string manipulation.
error_message += (" " + element_name + ": " + message + "\n");
}
void Clear() {
had_errors_ = false;
error_message = "";
}
string error_message;
private:
bool had_errors_;
};
// Create a Python DescriptorPool object, but does not fill the "pool"
// attribute.
static PyDescriptorPool* _CreateDescriptorPool() {
@ -76,6 +108,7 @@ static PyDescriptorPool* _CreateDescriptorPool() {
return NULL;
}
cpool->error_collector = nullptr;
cpool->underlay = NULL;
cpool->database = NULL;
@ -124,7 +157,8 @@ static PyDescriptorPool* PyDescriptorPool_NewWithDatabase(
return NULL;
}
if (database != NULL) {
cpool->pool = new DescriptorPool(database);
cpool->error_collector = new BuildFileErrorCollector();
cpool->pool = new DescriptorPool(database, cpool->error_collector);
cpool->database = database;
} else {
cpool->pool = new DescriptorPool();
@ -167,6 +201,7 @@ static void Dealloc(PyObject* pself) {
delete self->descriptor_options;
delete self->database;
delete self->pool;
delete self->error_collector;
Py_TYPE(self)->tp_free(pself);
}
@ -182,6 +217,20 @@ static int GcClear(PyObject* pself) {
return 0;
}
PyObject* SetErrorFromCollector(DescriptorPool::ErrorCollector* self,
char* name, char* error_type) {
BuildFileErrorCollector* error_collector =
reinterpret_cast<BuildFileErrorCollector*>(self);
if (error_collector && !error_collector->error_message.empty()) {
PyErr_Format(PyExc_KeyError, "Couldn't build file for %s %.200s\n%s",
error_type, name, error_collector->error_message.c_str());
error_collector->Clear();
return NULL;
}
PyErr_Format(PyExc_KeyError, "Couldn't find %s %.200s", error_type, name);
return NULL;
}
static PyObject* FindMessageByName(PyObject* self, PyObject* arg) {
Py_ssize_t name_size;
char* name;
@ -194,8 +243,9 @@ static PyObject* FindMessageByName(PyObject* self, PyObject* arg) {
string(name, name_size));
if (message_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find message %.200s", name);
return NULL;
return SetErrorFromCollector(
reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
"message");
}
@ -212,12 +262,12 @@ static PyObject* FindFileByName(PyObject* self, PyObject* arg) {
return NULL;
}
PyDescriptorPool* py_pool = reinterpret_cast<PyDescriptorPool*>(self);
const FileDescriptor* file_descriptor =
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileByName(
string(name, name_size));
py_pool->pool->FindFileByName(string(name, name_size));
if (file_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find file %.200s", name);
return NULL;
return SetErrorFromCollector(py_pool->error_collector, name, "file");
}
return PyFileDescriptor_FromDescriptor(file_descriptor);
}
@ -232,9 +282,7 @@ PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) {
const FieldDescriptor* field_descriptor =
self->pool->FindFieldByName(string(name, name_size));
if (field_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find field %.200s",
name);
return NULL;
return SetErrorFromCollector(self->error_collector, name, "field");
}
@ -255,8 +303,8 @@ PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) {
const FieldDescriptor* field_descriptor =
self->pool->FindExtensionByName(string(name, name_size));
if (field_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find extension field %.200s", name);
return NULL;
return SetErrorFromCollector(self->error_collector, name,
"extension field");
}
@ -277,8 +325,7 @@ PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) {
const EnumDescriptor* enum_descriptor =
self->pool->FindEnumTypeByName(string(name, name_size));
if (enum_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find enum %.200s", name);
return NULL;
return SetErrorFromCollector(self->error_collector, name, "enum");
}
@ -299,8 +346,7 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) {
const OneofDescriptor* oneof_descriptor =
self->pool->FindOneofByName(string(name, name_size));
if (oneof_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find oneof %.200s", name);
return NULL;
return SetErrorFromCollector(self->error_collector, name, "oneof");
}
@ -322,8 +368,9 @@ static PyObject* FindServiceByName(PyObject* self, PyObject* arg) {
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName(
string(name, name_size));
if (service_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find service %.200s", name);
return NULL;
return SetErrorFromCollector(
reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
"service");
}
@ -341,8 +388,9 @@ static PyObject* FindMethodByName(PyObject* self, PyObject* arg) {
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMethodByName(
string(name, name_size));
if (method_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
return NULL;
return SetErrorFromCollector(
reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
"method");
}
@ -360,8 +408,9 @@ static PyObject* FindFileContainingSymbol(PyObject* self, PyObject* arg) {
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileContainingSymbol(
string(name, name_size));
if (file_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find symbol %.200s", name);
return NULL;
return SetErrorFromCollector(
reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
"symbol");
}
@ -384,7 +433,16 @@ static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) {
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByNumber(
descriptor, number);
if (extension_descriptor == NULL) {
PyErr_Format(PyExc_KeyError, "Couldn't find extension %d", number);
BuildFileErrorCollector* error_collector =
reinterpret_cast<BuildFileErrorCollector*>(
reinterpret_cast<PyDescriptorPool*>(self)->error_collector);
if (error_collector && !error_collector->error_message.empty()) {
PyErr_Format(PyExc_KeyError, "Couldn't build file for Extension %.d\n%s",
number, error_collector->error_message.c_str());
error_collector->Clear();
return NULL;
}
PyErr_Format(PyExc_KeyError, "Couldn't find Extension %d", number);
return NULL;
}
@ -511,32 +569,6 @@ static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) {
}
// The code below loads new Descriptors from a serialized FileDescriptorProto.
// Collects errors that occur during proto file building to allow them to be
// propagated in the python exception instead of only living in ERROR logs.
class BuildFileErrorCollector : public DescriptorPool::ErrorCollector {
public:
BuildFileErrorCollector() : error_message(""), had_errors(false) {}
void AddError(const string& filename, const string& element_name,
const Message* descriptor, ErrorLocation location,
const string& message) {
// Replicates the logging behavior that happens in the C++ implementation
// when an error collector is not passed in.
if (!had_errors) {
error_message +=
("Invalid proto descriptor for file \"" + filename + "\":\n");
had_errors = true;
}
// As this only happens on failure and will result in the program not
// running at all, no effort is made to optimize this string manipulation.
error_message += (" " + element_name + ": " + message + "\n");
}
string error_message;
bool had_errors;
};
static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) {
PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
char* message_type;

@ -59,6 +59,10 @@ typedef struct PyDescriptorPool {
// The C++ pool containing Descriptors.
DescriptorPool* pool;
// The error collector to store error info. Can be NULL. This pointer is
// owned.
DescriptorPool::ErrorCollector* error_collector;
// The C++ pool acting as an underlay. Can be NULL.
// This pointer is not owned and must stay alive.
const DescriptorPool* underlay;

@ -92,6 +92,7 @@ def GenerateUnittestProtos():
generate_proto("../src/google/protobuf/unittest_mset_wire_format.proto", False)
generate_proto("../src/google/protobuf/unittest_no_generic_services.proto", False)
generate_proto("../src/google/protobuf/unittest_proto3_arena.proto", False)
generate_proto("../src/google/protobuf/util/json_format.proto", False)
generate_proto("../src/google/protobuf/util/json_format_proto3.proto", False)
generate_proto("google/protobuf/internal/any_test.proto", False)
generate_proto("google/protobuf/internal/descriptor_pool_test1.proto", False)

@ -115,11 +115,6 @@ class Any::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Any::kTypeUrlFieldNumber;
const int Any::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Any::Any()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr), _any_metadata_(&type_url_, &value_) {
SharedCtor();
@ -419,10 +414,6 @@ bool Any::IsInitialized() const {
return true;
}
void Any::Swap(Any* other) {
if (other == this) return;
InternalSwap(other);
}
void Any::InternalSwap(Any* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -126,10 +126,13 @@ class PROTOBUF_EXPORT Any :
}
static bool ParseAnyTypeUrl(const string& type_url,
std::string* full_type_name);
void Swap(Any* other);
friend void swap(Any& a, Any& b) {
a.Swap(&b);
}
inline void Swap(Any* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -191,9 +194,12 @@ class PROTOBUF_EXPORT Any :
// accessors -------------------------------------------------------
enum : int {
kTypeUrlFieldNumber = 1,
kValueFieldNumber = 2,
};
// string type_url = 1;
void clear_type_url();
static const int kTypeUrlFieldNumber = 1;
const std::string& type_url() const;
void set_type_url(const std::string& value);
void set_type_url(std::string&& value);
@ -205,7 +211,6 @@ class PROTOBUF_EXPORT Any :
// bytes value = 2;
void clear_value();
static const int kValueFieldNumber = 2;
const std::string& value() const;
void set_value(const std::string& value);
void set_value(std::string&& value);

@ -196,16 +196,6 @@ void Api::clear_source_context() {
}
source_context_ = nullptr;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Api::kNameFieldNumber;
const int Api::kMethodsFieldNumber;
const int Api::kOptionsFieldNumber;
const int Api::kVersionFieldNumber;
const int Api::kSourceContextFieldNumber;
const int Api::kMixinsFieldNumber;
const int Api::kSyntaxFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Api::Api()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -777,10 +767,6 @@ bool Api::IsInitialized() const {
return true;
}
void Api::Swap(Api* other) {
if (other == this) return;
InternalSwap(other);
}
void Api::InternalSwap(Api* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -811,16 +797,6 @@ class Method::_Internal {
void Method::clear_options() {
options_.Clear();
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Method::kNameFieldNumber;
const int Method::kRequestTypeUrlFieldNumber;
const int Method::kRequestStreamingFieldNumber;
const int Method::kResponseTypeUrlFieldNumber;
const int Method::kResponseStreamingFieldNumber;
const int Method::kOptionsFieldNumber;
const int Method::kSyntaxFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Method::Method()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1374,10 +1350,6 @@ bool Method::IsInitialized() const {
return true;
}
void Method::Swap(Method* other) {
if (other == this) return;
InternalSwap(other);
}
void Method::InternalSwap(Method* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -1406,11 +1378,6 @@ class Mixin::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Mixin::kNameFieldNumber;
const int Mixin::kRootFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Mixin::Mixin()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1721,10 +1688,6 @@ bool Mixin::IsInitialized() const {
return true;
}
void Mixin::Swap(Mixin* other) {
if (other == this) return;
InternalSwap(other);
}
void Mixin::InternalSwap(Mixin* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -120,10 +120,13 @@ class PROTOBUF_EXPORT Api :
static constexpr int kIndexInFileMessages =
0;
void Swap(Api* other);
friend void swap(Api& a, Api& b) {
a.Swap(&b);
}
inline void Swap(Api* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -185,10 +188,18 @@ class PROTOBUF_EXPORT Api :
// accessors -------------------------------------------------------
enum : int {
kMethodsFieldNumber = 2,
kOptionsFieldNumber = 3,
kMixinsFieldNumber = 6,
kNameFieldNumber = 1,
kVersionFieldNumber = 4,
kSourceContextFieldNumber = 5,
kSyntaxFieldNumber = 7,
};
// repeated .google.protobuf.Method methods = 2;
int methods_size() const;
void clear_methods();
static const int kMethodsFieldNumber = 2;
PROTOBUF_NAMESPACE_ID::Method* mutable_methods(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Method >*
mutable_methods();
@ -200,7 +211,6 @@ class PROTOBUF_EXPORT Api :
// repeated .google.protobuf.Option options = 3;
int options_size() const;
void clear_options();
static const int kOptionsFieldNumber = 3;
PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
mutable_options();
@ -212,7 +222,6 @@ class PROTOBUF_EXPORT Api :
// repeated .google.protobuf.Mixin mixins = 6;
int mixins_size() const;
void clear_mixins();
static const int kMixinsFieldNumber = 6;
PROTOBUF_NAMESPACE_ID::Mixin* mutable_mixins(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Mixin >*
mutable_mixins();
@ -223,7 +232,6 @@ class PROTOBUF_EXPORT Api :
// string name = 1;
void clear_name();
static const int kNameFieldNumber = 1;
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
@ -235,7 +243,6 @@ class PROTOBUF_EXPORT Api :
// string version = 4;
void clear_version();
static const int kVersionFieldNumber = 4;
const std::string& version() const;
void set_version(const std::string& value);
void set_version(std::string&& value);
@ -248,7 +255,6 @@ class PROTOBUF_EXPORT Api :
// .google.protobuf.SourceContext source_context = 5;
bool has_source_context() const;
void clear_source_context();
static const int kSourceContextFieldNumber = 5;
const PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
@ -256,7 +262,6 @@ class PROTOBUF_EXPORT Api :
// .google.protobuf.Syntax syntax = 7;
void clear_syntax();
static const int kSyntaxFieldNumber = 7;
PROTOBUF_NAMESPACE_ID::Syntax syntax() const;
void set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value);
@ -321,10 +326,13 @@ class PROTOBUF_EXPORT Method :
static constexpr int kIndexInFileMessages =
1;
void Swap(Method* other);
friend void swap(Method& a, Method& b) {
a.Swap(&b);
}
inline void Swap(Method* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -386,10 +394,18 @@ class PROTOBUF_EXPORT Method :
// accessors -------------------------------------------------------
enum : int {
kOptionsFieldNumber = 6,
kNameFieldNumber = 1,
kRequestTypeUrlFieldNumber = 2,
kResponseTypeUrlFieldNumber = 4,
kRequestStreamingFieldNumber = 3,
kResponseStreamingFieldNumber = 5,
kSyntaxFieldNumber = 7,
};
// repeated .google.protobuf.Option options = 6;
int options_size() const;
void clear_options();
static const int kOptionsFieldNumber = 6;
PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
mutable_options();
@ -400,7 +416,6 @@ class PROTOBUF_EXPORT Method :
// string name = 1;
void clear_name();
static const int kNameFieldNumber = 1;
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
@ -412,7 +427,6 @@ class PROTOBUF_EXPORT Method :
// string request_type_url = 2;
void clear_request_type_url();
static const int kRequestTypeUrlFieldNumber = 2;
const std::string& request_type_url() const;
void set_request_type_url(const std::string& value);
void set_request_type_url(std::string&& value);
@ -424,7 +438,6 @@ class PROTOBUF_EXPORT Method :
// string response_type_url = 4;
void clear_response_type_url();
static const int kResponseTypeUrlFieldNumber = 4;
const std::string& response_type_url() const;
void set_response_type_url(const std::string& value);
void set_response_type_url(std::string&& value);
@ -436,19 +449,16 @@ class PROTOBUF_EXPORT Method :
// bool request_streaming = 3;
void clear_request_streaming();
static const int kRequestStreamingFieldNumber = 3;
bool request_streaming() const;
void set_request_streaming(bool value);
// bool response_streaming = 5;
void clear_response_streaming();
static const int kResponseStreamingFieldNumber = 5;
bool response_streaming() const;
void set_response_streaming(bool value);
// .google.protobuf.Syntax syntax = 7;
void clear_syntax();
static const int kSyntaxFieldNumber = 7;
PROTOBUF_NAMESPACE_ID::Syntax syntax() const;
void set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value);
@ -513,10 +523,13 @@ class PROTOBUF_EXPORT Mixin :
static constexpr int kIndexInFileMessages =
2;
void Swap(Mixin* other);
friend void swap(Mixin& a, Mixin& b) {
a.Swap(&b);
}
inline void Swap(Mixin* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -578,9 +591,12 @@ class PROTOBUF_EXPORT Mixin :
// accessors -------------------------------------------------------
enum : int {
kNameFieldNumber = 1,
kRootFieldNumber = 2,
};
// string name = 1;
void clear_name();
static const int kNameFieldNumber = 1;
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
@ -592,7 +608,6 @@ class PROTOBUF_EXPORT Mixin :
// string root = 2;
void clear_root();
static const int kRootFieldNumber = 2;
const std::string& root() const;
void set_root(const std::string& value);
void set_root(std::string&& value);

@ -245,7 +245,7 @@ struct ArenaOptions {
// well as protobuf container types like RepeatedPtrField and Map. The protocol
// is internal to protobuf and is not guaranteed to be stable. Non-proto types
// should not rely on this protocol.
class PROTOBUF_EXPORT Arena final {
class PROTOBUF_EXPORT alignas(8) Arena final {
public:
// Arena constructor taking custom options. See ArenaOptions below for
// descriptions of the options available.

@ -2023,6 +2023,10 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
// Error written to stdout by child process after exec() fails.
ExpectErrorSubstring("no_such_file: program not found or is not executable");
ExpectErrorSubstring(
"Please specify a program using absolute path or make sure "
"the program is available in your PATH system variable");
// Error written by parent process when child fails.
ExpectErrorSubstring(
"--badplug_out: prefix-gen-badplug: Plugin failed with status code 1.");

@ -1489,9 +1489,9 @@ class ParseLoopGenerator {
std::string enum_validator;
if (field->type() == FieldDescriptor::TYPE_ENUM &&
!HasPreservingUnknownEnumSemantics(field)) {
enum_validator = StrCat(
", ", QualifiedClassName(field->enum_type(), options_),
"_IsValid, mutable_unknown_fields(), ", field->number());
enum_validator =
StrCat(", ", QualifiedClassName(field->enum_type(), options_),
"_IsValid, &_internal_metadata_, ", field->number());
}
format_("ptr = $pi_ns$::Packed$1$Parser(mutable_$2$(), ptr, ctx$3$);\n",
DeclaredTypeMethodName(field->type()), FieldName(field),

@ -714,6 +714,18 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) {
ordered_fields.push_back(field);
}
if (!ordered_fields.empty()) {
format("enum : int {\n");
for (auto field : ordered_fields) {
Formatter::SaveState save(&format);
std::map<std::string, std::string> vars;
SetCommonFieldVariables(field, &vars, options_);
format.AddMap(vars);
format(" ${1$$2$$}$ = $number$,\n", field, FieldConstantName(field));
}
format("};\n");
}
for (auto field : ordered_fields) {
PrintFieldComment(format, field);
@ -735,10 +747,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) {
field);
}
format(
"$deprecated_attr$void ${1$clear_$name$$}$();\n"
"$deprecated_attr$static const int ${1$$2$$}$ = $number$;\n",
field, FieldConstantName(field));
format("$deprecated_attr$void ${1$clear_$name$$}$();\n", field);
// Generate type-specific accessor declarations.
field_generators_.get(field).GenerateAccessorDeclarations(printer);
@ -1159,10 +1168,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
"\n",
index_in_file_messages_);
if (SupportsArenas(descriptor_)) {
format("void UnsafeArenaSwap($classname$* other);\n");
}
if (IsAnyMessage(descriptor_, options_)) {
format(
"// implements Any -----------------------------------------------\n"
@ -1205,10 +1210,34 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
ShouldMarkNewAsFinal(descriptor_, options_) ? "final" : "");
format(
"void Swap($classname$* other);\n"
"friend void swap($classname$& a, $classname$& b) {\n"
" a.Swap(&b);\n"
"}\n"
"}\n");
if (SupportsArenas(descriptor_)) {
format(
"inline void Swap($classname$* other) {\n"
" if (other == this) return;\n"
" if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {\n"
" InternalSwap(other);\n"
" } else {\n"
" ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n"
" }\n"
"}\n"
"void UnsafeArenaSwap($classname$* other) {\n"
" if (other == this) return;\n"
" $DCHK$(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n"
" InternalSwap(other);\n"
"}\n");
} else {
format(
"inline void Swap($classname$* other) {\n"
" if (other == this) return;\n"
" InternalSwap(other);\n"
"}\n");
}
format(
"\n"
"// implements Message ----------------------------------------------\n"
"\n"
@ -2031,15 +2060,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
}
}
// Generate field number constants.
format("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
for (auto field : FieldRange(descriptor_)) {
format("const int $classname$::$1$;\n", FieldConstantName(field));
}
format(
"#endif // !defined(_MSC_VER) || _MSC_VER >= 1900\n"
"\n");
GenerateStructors(printer);
format("\n");
@ -3003,40 +3023,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) {
void MessageGenerator::GenerateSwap(io::Printer* printer) {
Formatter format(printer, variables_);
if (SupportsArenas(descriptor_)) {
// Generate the Swap member function. This is a lightweight wrapper around
// UnsafeArenaSwap() / MergeFrom() with temporaries, depending on the memory
// ownership situation: swapping across arenas or between an arena and a
// heap requires copying.
format(
"void $classname$::Swap($classname$* other) {\n"
" if (other == this) return;\n"
" if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {\n"
" InternalSwap(other);\n"
" } else {\n"
" $classname$* temp = New(GetArenaNoVirtual());\n"
" temp->MergeFrom(*other);\n"
" other->CopyFrom(*this);\n"
" InternalSwap(temp);\n"
" if (GetArenaNoVirtual() == nullptr) {\n"
" delete temp;\n"
" }\n"
" }\n"
"}\n"
"void $classname$::UnsafeArenaSwap($classname$* other) {\n"
" if (other == this) return;\n"
" $DCHK$(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n"
" InternalSwap(other);\n"
"}\n");
} else {
format(
"void $classname$::Swap($classname$* other) {\n"
" if (other == this) return;\n"
" InternalSwap(other);\n"
"}\n");
}
// Generate the UnsafeArenaSwap member function.
format("void $classname$::InternalSwap($classname$* other) {\n");
format.Indent();
format("using std::swap;\n");

@ -1651,7 +1651,11 @@ bool IsWellKnownTypeFile(const FileDescriptor* file) {
} // anonymous namespace
void Generator::GenerateHeader(const GeneratorOptions& options,
const FileDescriptor* file,
io::Printer* printer) const {
if (file != nullptr) {
printer->Print("// source: $filename$\n", "filename", file->name());
}
printer->Print(
"/**\n"
" * @fileoverview\n"
@ -3637,7 +3641,7 @@ bool Generator::GenerateFile(const FileDescriptor* file,
void Generator::GenerateFile(const GeneratorOptions& options,
io::Printer* printer,
const FileDescriptor* file) const {
GenerateHeader(options, printer);
GenerateHeader(options, file, printer);
// Generate "require" statements.
if ((options.import_style == GeneratorOptions::kImportCommonJs ||
@ -3748,7 +3752,11 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
}
}
GenerateHeader(options, &printer);
if (files.size() == 1) {
GenerateHeader(options, files[0], &printer);
} else {
GenerateHeader(options, nullptr, &printer);
}
std::set<std::string> provided;
FindProvides(options, &printer, files, &provided);
@ -3811,7 +3819,7 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
output.get(), '$',
options.annotate_code ? &annotation_collector : nullptr);
GenerateHeader(options, &printer);
GenerateHeader(options, file, &printer);
std::set<std::string> provided;
for (auto one_desc : scc->descriptors) {
@ -3864,7 +3872,7 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
output.get(), '$',
options.annotate_code ? &annotation_collector : nullptr);
GenerateHeader(options, &printer);
GenerateHeader(options, file, &printer);
std::set<std::string> provided;
FindProvidesForEnum(options, &printer, enumdesc, &provided);
@ -3896,7 +3904,7 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
output.get(), '$',
options.annotate_code ? &annotation_collector : nullptr);
GenerateHeader(options, &printer);
GenerateHeader(options, file, &printer);
std::set<std::string> provided;
std::vector<const FieldDescriptor*> fields;

@ -157,7 +157,7 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
private:
void GenerateHeader(const GeneratorOptions& options,
io::Printer* printer) const;
const FileDescriptor* file, io::Printer* printer) const;
// Generate goog.provides() calls.
void FindProvides(const GeneratorOptions& options, io::Printer* printer,

@ -225,13 +225,6 @@ class Version::_Internal {
}
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Version::kMajorFieldNumber;
const int Version::kMinorFieldNumber;
const int Version::kPatchFieldNumber;
const int Version::kSuffixFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Version::Version()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -631,10 +624,6 @@ bool Version::IsInitialized() const {
return true;
}
void Version::Swap(Version* other) {
if (other == this) return;
InternalSwap(other);
}
void Version::InternalSwap(Version* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -676,13 +665,6 @@ CodeGeneratorRequest::_Internal::compiler_version(const CodeGeneratorRequest* ms
void CodeGeneratorRequest::clear_proto_file() {
proto_file_.Clear();
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int CodeGeneratorRequest::kFileToGenerateFieldNumber;
const int CodeGeneratorRequest::kParameterFieldNumber;
const int CodeGeneratorRequest::kProtoFileFieldNumber;
const int CodeGeneratorRequest::kCompilerVersionFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
CodeGeneratorRequest::CodeGeneratorRequest()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1115,10 +1097,6 @@ bool CodeGeneratorRequest::IsInitialized() const {
return true;
}
void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) {
if (other == this) return;
InternalSwap(other);
}
void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -1153,12 +1131,6 @@ class CodeGeneratorResponse_File::_Internal {
}
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int CodeGeneratorResponse_File::kNameFieldNumber;
const int CodeGeneratorResponse_File::kInsertionPointFieldNumber;
const int CodeGeneratorResponse_File::kContentFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
CodeGeneratorResponse_File::CodeGeneratorResponse_File()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1551,10 +1523,6 @@ bool CodeGeneratorResponse_File::IsInitialized() const {
return true;
}
void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) {
if (other == this) return;
InternalSwap(other);
}
void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -1584,11 +1552,6 @@ class CodeGeneratorResponse::_Internal {
}
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int CodeGeneratorResponse::kErrorFieldNumber;
const int CodeGeneratorResponse::kFileFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
CodeGeneratorResponse::CodeGeneratorResponse()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1902,10 +1865,6 @@ bool CodeGeneratorResponse::IsInitialized() const {
return true;
}
void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) {
if (other == this) return;
InternalSwap(other);
}
void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -139,10 +139,13 @@ class PROTOC_EXPORT Version :
static constexpr int kIndexInFileMessages =
0;
void Swap(Version* other);
friend void swap(Version& a, Version& b) {
a.Swap(&b);
}
inline void Swap(Version* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -204,10 +207,15 @@ class PROTOC_EXPORT Version :
// accessors -------------------------------------------------------
enum : int {
kSuffixFieldNumber = 4,
kMajorFieldNumber = 1,
kMinorFieldNumber = 2,
kPatchFieldNumber = 3,
};
// optional string suffix = 4;
bool has_suffix() const;
void clear_suffix();
static const int kSuffixFieldNumber = 4;
const std::string& suffix() const;
void set_suffix(const std::string& value);
void set_suffix(std::string&& value);
@ -220,21 +228,18 @@ class PROTOC_EXPORT Version :
// optional int32 major = 1;
bool has_major() const;
void clear_major();
static const int kMajorFieldNumber = 1;
::PROTOBUF_NAMESPACE_ID::int32 major() const;
void set_major(::PROTOBUF_NAMESPACE_ID::int32 value);
// optional int32 minor = 2;
bool has_minor() const;
void clear_minor();
static const int kMinorFieldNumber = 2;
::PROTOBUF_NAMESPACE_ID::int32 minor() const;
void set_minor(::PROTOBUF_NAMESPACE_ID::int32 value);
// optional int32 patch = 3;
bool has_patch() const;
void clear_patch();
static const int kPatchFieldNumber = 3;
::PROTOBUF_NAMESPACE_ID::int32 patch() const;
void set_patch(::PROTOBUF_NAMESPACE_ID::int32 value);
@ -304,10 +309,13 @@ class PROTOC_EXPORT CodeGeneratorRequest :
static constexpr int kIndexInFileMessages =
1;
void Swap(CodeGeneratorRequest* other);
friend void swap(CodeGeneratorRequest& a, CodeGeneratorRequest& b) {
a.Swap(&b);
}
inline void Swap(CodeGeneratorRequest* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -369,10 +377,15 @@ class PROTOC_EXPORT CodeGeneratorRequest :
// accessors -------------------------------------------------------
enum : int {
kFileToGenerateFieldNumber = 1,
kProtoFileFieldNumber = 15,
kParameterFieldNumber = 2,
kCompilerVersionFieldNumber = 3,
};
// repeated string file_to_generate = 1;
int file_to_generate_size() const;
void clear_file_to_generate();
static const int kFileToGenerateFieldNumber = 1;
const std::string& file_to_generate(int index) const;
std::string* mutable_file_to_generate(int index);
void set_file_to_generate(int index, const std::string& value);
@ -390,7 +403,6 @@ class PROTOC_EXPORT CodeGeneratorRequest :
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
int proto_file_size() const;
void clear_proto_file();
static const int kProtoFileFieldNumber = 15;
PROTOBUF_NAMESPACE_ID::FileDescriptorProto* mutable_proto_file(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::FileDescriptorProto >*
mutable_proto_file();
@ -402,7 +414,6 @@ class PROTOC_EXPORT CodeGeneratorRequest :
// optional string parameter = 2;
bool has_parameter() const;
void clear_parameter();
static const int kParameterFieldNumber = 2;
const std::string& parameter() const;
void set_parameter(const std::string& value);
void set_parameter(std::string&& value);
@ -415,7 +426,6 @@ class PROTOC_EXPORT CodeGeneratorRequest :
// optional .google.protobuf.compiler.Version compiler_version = 3;
bool has_compiler_version() const;
void clear_compiler_version();
static const int kCompilerVersionFieldNumber = 3;
const PROTOBUF_NAMESPACE_ID::compiler::Version& compiler_version() const;
PROTOBUF_NAMESPACE_ID::compiler::Version* release_compiler_version();
PROTOBUF_NAMESPACE_ID::compiler::Version* mutable_compiler_version();
@ -487,10 +497,13 @@ class PROTOC_EXPORT CodeGeneratorResponse_File :
static constexpr int kIndexInFileMessages =
2;
void Swap(CodeGeneratorResponse_File* other);
friend void swap(CodeGeneratorResponse_File& a, CodeGeneratorResponse_File& b) {
a.Swap(&b);
}
inline void Swap(CodeGeneratorResponse_File* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -552,10 +565,14 @@ class PROTOC_EXPORT CodeGeneratorResponse_File :
// accessors -------------------------------------------------------
enum : int {
kNameFieldNumber = 1,
kInsertionPointFieldNumber = 2,
kContentFieldNumber = 15,
};
// optional string name = 1;
bool has_name() const;
void clear_name();
static const int kNameFieldNumber = 1;
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
@ -568,7 +585,6 @@ class PROTOC_EXPORT CodeGeneratorResponse_File :
// optional string insertion_point = 2;
bool has_insertion_point() const;
void clear_insertion_point();
static const int kInsertionPointFieldNumber = 2;
const std::string& insertion_point() const;
void set_insertion_point(const std::string& value);
void set_insertion_point(std::string&& value);
@ -581,7 +597,6 @@ class PROTOC_EXPORT CodeGeneratorResponse_File :
// optional string content = 15;
bool has_content() const;
void clear_content();
static const int kContentFieldNumber = 15;
const std::string& content() const;
void set_content(const std::string& value);
void set_content(std::string&& value);
@ -656,10 +671,13 @@ class PROTOC_EXPORT CodeGeneratorResponse :
static constexpr int kIndexInFileMessages =
3;
void Swap(CodeGeneratorResponse* other);
friend void swap(CodeGeneratorResponse& a, CodeGeneratorResponse& b) {
a.Swap(&b);
}
inline void Swap(CodeGeneratorResponse* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -723,10 +741,13 @@ class PROTOC_EXPORT CodeGeneratorResponse :
// accessors -------------------------------------------------------
enum : int {
kFileFieldNumber = 15,
kErrorFieldNumber = 1,
};
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
int file_size() const;
void clear_file();
static const int kFileFieldNumber = 15;
PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* mutable_file(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >*
mutable_file();
@ -738,7 +759,6 @@ class PROTOC_EXPORT CodeGeneratorResponse :
// optional string error = 1;
bool has_error() const;
void clear_error();
static const int kErrorFieldNumber = 1;
const std::string& error() const;
void set_error(const std::string& value);
void set_error(std::string&& value);

@ -338,7 +338,10 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode) {
// stuff that is unsafe here.
int ignored;
ignored = write(STDERR_FILENO, argv[0], strlen(argv[0]));
const char* message = ": program not found or is not executable\n";
const char* message =
": program not found or is not executable\n"
"Please specify a program using absolute path or make sure "
"the program is available in your PATH system variable\n";
ignored = write(STDERR_FILENO, message, strlen(message));
(void)ignored;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -90,11 +90,6 @@ class Duration::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Duration::kSecondsFieldNumber;
const int Duration::kNanosFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Duration::Duration()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -386,25 +381,6 @@ bool Duration::IsInitialized() const {
return true;
}
void Duration::Swap(Duration* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Duration* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Duration::UnsafeArenaSwap(Duration* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Duration::InternalSwap(Duration* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -116,11 +116,22 @@ class PROTOBUF_EXPORT Duration :
static constexpr int kIndexInFileMessages =
0;
void UnsafeArenaSwap(Duration* other);
void Swap(Duration* other);
friend void swap(Duration& a, Duration& b) {
a.Swap(&b);
}
inline void Swap(Duration* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Duration* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -187,15 +198,17 @@ class PROTOBUF_EXPORT Duration :
// accessors -------------------------------------------------------
enum : int {
kSecondsFieldNumber = 1,
kNanosFieldNumber = 2,
};
// int64 seconds = 1;
void clear_seconds();
static const int kSecondsFieldNumber = 1;
::PROTOBUF_NAMESPACE_ID::int64 seconds() const;
void set_seconds(::PROTOBUF_NAMESPACE_ID::int64 value);
// int32 nanos = 2;
void clear_nanos();
static const int kNanosFieldNumber = 2;
::PROTOBUF_NAMESPACE_ID::int32 nanos() const;
void set_nanos(::PROTOBUF_NAMESPACE_ID::int32 value);

@ -87,9 +87,6 @@ class Empty::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Empty::Empty()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -286,25 +283,6 @@ bool Empty::IsInitialized() const {
return true;
}
void Empty::Swap(Empty* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Empty* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Empty::UnsafeArenaSwap(Empty* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Empty::InternalSwap(Empty* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -116,11 +116,22 @@ class PROTOBUF_EXPORT Empty :
static constexpr int kIndexInFileMessages =
0;
void UnsafeArenaSwap(Empty* other);
void Swap(Empty* other);
friend void swap(Empty& a, Empty& b) {
a.Swap(&b);
}
inline void Swap(Empty* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Empty* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------

@ -71,8 +71,7 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo(
MutableRawRepeatedField(number, extension.type, extension.is_packed,
extension.descriptor),
ptr, ctx, extension.enum_validity_check.func,
extension.enum_validity_check.arg,
metadata->mutable_unknown_fields(), number);
extension.enum_validity_check.arg, metadata, number);
case WireFormatLite::TYPE_STRING:
case WireFormatLite::TYPE_BYTES:
case WireFormatLite::TYPE_GROUP:

@ -89,10 +89,6 @@ class FieldMask::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int FieldMask::kPathsFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
FieldMask::FieldMask()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -356,25 +352,6 @@ bool FieldMask::IsInitialized() const {
return true;
}
void FieldMask::Swap(FieldMask* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
FieldMask* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void FieldMask::UnsafeArenaSwap(FieldMask* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void FieldMask::InternalSwap(FieldMask* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -116,11 +116,22 @@ class PROTOBUF_EXPORT FieldMask :
static constexpr int kIndexInFileMessages =
0;
void UnsafeArenaSwap(FieldMask* other);
void Swap(FieldMask* other);
friend void swap(FieldMask& a, FieldMask& b) {
a.Swap(&b);
}
inline void Swap(FieldMask* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(FieldMask* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -187,10 +198,12 @@ class PROTOBUF_EXPORT FieldMask :
// accessors -------------------------------------------------------
enum : int {
kPathsFieldNumber = 1,
};
// repeated string paths = 1;
int paths_size() const;
void clear_paths();
static const int kPathsFieldNumber = 1;
const std::string& paths(int index) const;
std::string* mutable_paths(int index);
void set_paths(int index, const std::string& value);

@ -747,6 +747,15 @@ MessageLite* DuplicateIfNonNullInternal(MessageLite* message) {
}
}
void GenericSwap(MessageLite* m1, MessageLite* m2) {
std::unique_ptr<MessageLite> tmp(m1->New());
tmp->CheckTypeAndMergeFrom(*m1);
m1->Clear();
m1->CheckTypeAndMergeFrom(*m2);
m2->Clear();
m2->CheckTypeAndMergeFrom(*tmp);
}
// Returns a message owned by this Arena. This may require Own()ing or
// duplicating the message.
MessageLite* GetOwnedMessageInternal(Arena* message_arena,

@ -145,6 +145,7 @@ PROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message);
PROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena,
MessageLite* submessage,
Arena* submessage_arena);
PROTOBUF_EXPORT void GenericSwap(MessageLite* m1, MessageLite* m2);
template <typename T>
T* DuplicateIfNonNull(T* message) {

@ -158,6 +158,11 @@ class ReflectionAccessor {
return reflection->MutableRawRepeatedField(
msg, field, FieldDescriptor::CPPTYPE_ENUM, 0, nullptr);
}
static InternalMetadataWithArena* MutableInternalMetadataWithArena(
const Reflection* reflection, Message* msg) {
return reflection->MutableInternalMetadataWithArena(msg);
}
};
} // namespace internal
@ -263,7 +268,9 @@ const char* ParsePackedField(const FieldDescriptor* field, Message* msg,
} else {
return internal::PackedEnumParserArg(
object, ptr, ctx, ReflectiveValidator, field->enum_type(),
reflection->MutableUnknownFields(msg), field->number());
internal::ReflectionAccessor::MutableInternalMetadataWithArena(
reflection, msg),
field->number());
}
}
HANDLE_PACKED_TYPE(FIXED32, uint32, Fixed32);

@ -982,7 +982,7 @@ class PROTOBUF_EXPORT Reflection final {
inline const internal::InternalMetadataWithArena&
GetInternalMetadataWithArena(const Message& message) const;
inline internal::InternalMetadataWithArena* MutableInternalMetadataWithArena(
internal::InternalMetadataWithArena* MutableInternalMetadataWithArena(
Message* message) const;
inline bool IsInlined(const FieldDescriptor* field) const;

@ -421,14 +421,15 @@ const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx) {
}
const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx,
bool (*is_valid)(int), std::string* unknown,
bool (*is_valid)(int),
InternalMetadataWithArenaLite* metadata,
int field_num) {
return ctx->ReadPackedVarint(
ptr, [object, is_valid, unknown, field_num](uint64 val) {
ptr, [object, is_valid, metadata, field_num](uint64 val) {
if (is_valid(val)) {
static_cast<RepeatedField<int>*>(object)->Add(val);
} else {
WriteVarint(field_num, val, unknown);
WriteVarint(field_num, val, metadata->mutable_unknown_fields());
}
});
}
@ -436,14 +437,15 @@ const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx,
const char* PackedEnumParserArg(void* object, const char* ptr,
ParseContext* ctx,
bool (*is_valid)(const void*, int),
const void* data, std::string* unknown,
const void* data,
InternalMetadataWithArenaLite* metadata,
int field_num) {
return ctx->ReadPackedVarint(
ptr, [object, is_valid, data, unknown, field_num](uint64 val) {
ptr, [object, is_valid, data, metadata, field_num](uint64 val) {
if (is_valid(data, val)) {
static_cast<RepeatedField<int>*>(object)->Add(val);
} else {
WriteVarint(field_num, val, unknown);
WriteVarint(field_num, val, metadata->mutable_unknown_fields());
}
});
}

@ -718,11 +718,11 @@ PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParser(
void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParser(
void* object, const char* ptr, ParseContext* ctx, bool (*is_valid)(int),
std::string* unknown, int field_num);
InternalMetadataWithArenaLite* metadata, int field_num);
PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParserArg(
void* object, const char* ptr, ParseContext* ctx,
bool (*is_valid)(const void*, int), const void* data, std::string* unknown,
int field_num);
bool (*is_valid)(const void*, int), const void* data,
InternalMetadataWithArenaLite* metadata, int field_num);
PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedBoolParser(
void* object, const char* ptr, ParseContext* ctx);

@ -118,6 +118,10 @@ inline int CalculateReserve(Iter begin, Iter end) {
// set-by-index, and add accessors that are generated for all repeated fields.
template <typename Element>
class RepeatedField final {
static_assert(
alignof(Arena) >= alignof(Element),
"We only support types that have an alignment smaller than Arena");
public:
RepeatedField();
explicit RepeatedField(Arena* arena);
@ -289,23 +293,30 @@ class RepeatedField final {
// Element is double and pointer is 32bit).
static const size_t kRepHeaderSize;
// We reuse the Rep* for an Arena* when total_size == 0, to avoid having to do
// an allocation in the constructor when we have an Arena.
union Pointer {
Pointer(Arena* a) : arena(a) {}
Arena* arena; // When total_size_ == 0.
Element* elements; // When total_size_ != 0, this is Rep->elements of Rep.
} ptr_;
// If total_size_ == 0 this points to an Arena otherwise it points to the
// elements member of a Rep struct. Using this invariant allows the storage of
// the arena pointer without an extra allocation in the constructor.
void* arena_or_elements_;
// Return pointer to elements array.
// pre-condition: the array must have been allocated.
Element* elements() const {
GOOGLE_DCHECK_GT(total_size_, 0);
return ptr_.elements;
// Because of above pre-condition this cast is safe.
return unsafe_elements();
}
// Return pointer to elements array if it exists otherwise either null or
// a invalid pointer is returned. This only happens for empty repeated fields,
// where you can't dereference this pointer anyway (it's empty).
Element* unsafe_elements() const {
return static_cast<Element*>(arena_or_elements_);
}
// Return pointer to the Rep struct.
// pre-condition: the Rep must have been allocated, ie elements() is safe.
Rep* rep() const {
GOOGLE_DCHECK_GT(total_size_, 0);
char* addr =
reinterpret_cast<char*>(ptr_.elements) - offsetof(Rep, elements);
char* addr = reinterpret_cast<char*>(elements()) - offsetof(Rep, elements);
return reinterpret_cast<Rep*>(addr);
}
@ -323,7 +334,8 @@ class RepeatedField final {
// Internal helper expected by Arena methods.
inline Arena* GetArenaNoVirtual() const {
return (total_size_ == 0) ? ptr_.arena : rep()->arena;
return (total_size_ == 0) ? static_cast<Arena*>(arena_or_elements_)
: rep()->arena;
}
// Internal helper to delete all elements and deallocate the storage.
@ -346,9 +358,6 @@ class RepeatedField final {
}
}
}
friend class internal::WireFormatLite;
const Element* unsafe_data() const;
};
template <typename Element>
@ -1057,15 +1066,15 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase {
template <typename Element>
inline RepeatedField<Element>::RepeatedField()
: current_size_(0), total_size_(0), ptr_(NULL) {}
: current_size_(0), total_size_(0), arena_or_elements_(nullptr) {}
template <typename Element>
inline RepeatedField<Element>::RepeatedField(Arena* arena)
: current_size_(0), total_size_(0), ptr_(arena) {}
: current_size_(0), total_size_(0), arena_or_elements_(arena) {}
template <typename Element>
inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
: current_size_(0), total_size_(0), ptr_(NULL) {
: current_size_(0), total_size_(0), arena_or_elements_(nullptr) {
if (other.current_size_ != 0) {
Reserve(other.size());
AddNAlreadyReserved(other.size());
@ -1076,7 +1085,7 @@ inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
template <typename Element>
template <typename Iter>
RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
: current_size_(0), total_size_(0), ptr_(NULL) {
: current_size_(0), total_size_(0), arena_or_elements_(nullptr) {
Add(begin, end);
}
@ -1153,13 +1162,11 @@ template <typename Element>
inline Element* RepeatedField<Element>::AddNAlreadyReserved(int n) {
GOOGLE_DCHECK_GE(total_size_ - current_size_, n)
<< total_size_ << ", " << current_size_;
// Warning: sometimes people call this when n==0 and total_size_==0. This
// forces us to add this branch, to avoid reading the non-active union member
// (which is UB). Luckily the compiler is smart enough to optimize the branch
// away.
Element* ret =
total_size_ == 0 ? reinterpret_cast<Element*>(ptr_.arena) : ptr_.elements;
ret += current_size_;
// Warning: sometimes people call this when n == 0 and total_size_ == 0. In
// this case the return pointer points to a zero size array (n == 0). Hence
// we can just use unsafe_elements(), because the user cannot dereference the
// pointer anyway.
Element* ret = unsafe_elements() + current_size_;
current_size_ += n;
return ret;
}
@ -1313,17 +1320,12 @@ inline typename RepeatedField<Element>::iterator RepeatedField<Element>::erase(
template <typename Element>
inline Element* RepeatedField<Element>::mutable_data() {
return total_size_ > 0 ? elements() : NULL;
return unsafe_elements();
}
template <typename Element>
inline const Element* RepeatedField<Element>::data() const {
return total_size_ > 0 ? elements() : NULL;
}
template <typename Element>
inline const Element* RepeatedField<Element>::unsafe_data() const {
return elements();
return unsafe_elements();
}
template <typename Element>
@ -1331,7 +1333,7 @@ inline void RepeatedField<Element>::InternalSwap(RepeatedField* other) {
GOOGLE_DCHECK(this != other);
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
std::swap(ptr_, other->ptr_);
std::swap(arena_or_elements_, other->arena_or_elements_);
std::swap(current_size_, other->current_size_);
std::swap(total_size_, other->total_size_);
}
@ -1364,31 +1366,31 @@ void RepeatedField<Element>::SwapElements(int index1, int index2) {
template <typename Element>
inline typename RepeatedField<Element>::iterator
RepeatedField<Element>::begin() {
return total_size_ > 0 ? elements() : NULL;
return unsafe_elements();
}
template <typename Element>
inline typename RepeatedField<Element>::const_iterator
RepeatedField<Element>::begin() const {
return total_size_ > 0 ? elements() : NULL;
return unsafe_elements();
}
template <typename Element>
inline typename RepeatedField<Element>::const_iterator
RepeatedField<Element>::cbegin() const {
return total_size_ > 0 ? elements() : NULL;
return unsafe_elements();
}
template <typename Element>
inline typename RepeatedField<Element>::iterator RepeatedField<Element>::end() {
return total_size_ > 0 ? elements() + current_size_ : NULL;
return unsafe_elements() + current_size_;
}
template <typename Element>
inline typename RepeatedField<Element>::const_iterator
RepeatedField<Element>::end() const {
return total_size_ > 0 ? elements() + current_size_ : NULL;
return unsafe_elements() + current_size_;
}
template <typename Element>
inline typename RepeatedField<Element>::const_iterator
RepeatedField<Element>::cend() const {
return total_size_ > 0 ? elements() + current_size_ : NULL;
return unsafe_elements() + current_size_;
}
template <typename Element>
@ -1420,7 +1422,7 @@ void RepeatedField<Element>::Reserve(int new_size) {
new_rep->arena = arena;
int old_total_size = total_size_;
total_size_ = new_size;
ptr_.elements = new_rep->elements;
arena_or_elements_ = new_rep->elements;
// Invoke placement-new on newly allocated elements. We shouldn't have to do
// this, since Element is supposed to be POD, but a previous version of this
// code allocated storage with "new Element[size]" and some code uses

@ -90,10 +90,6 @@ class SourceContext::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int SourceContext::kFileNameFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
SourceContext::SourceContext()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -343,10 +339,6 @@ bool SourceContext::IsInitialized() const {
return true;
}
void SourceContext::Swap(SourceContext* other) {
if (other == this) return;
InternalSwap(other);
}
void SourceContext::InternalSwap(SourceContext* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -110,10 +110,13 @@ class PROTOBUF_EXPORT SourceContext :
static constexpr int kIndexInFileMessages =
0;
void Swap(SourceContext* other);
friend void swap(SourceContext& a, SourceContext& b) {
a.Swap(&b);
}
inline void Swap(SourceContext* other) {
if (other == this) return;
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -175,9 +178,11 @@ class PROTOBUF_EXPORT SourceContext :
// accessors -------------------------------------------------------
enum : int {
kFileNameFieldNumber = 1,
};
// string file_name = 1;
void clear_file_name();
static const int kFileNameFieldNumber = 1;
const std::string& file_name() const;
void set_file_name(const std::string& value);
void set_file_name(std::string&& value);

@ -199,10 +199,6 @@ class Struct::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Struct::kFieldsFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Struct::Struct()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -535,25 +531,6 @@ bool Struct::IsInitialized() const {
return true;
}
void Struct::Swap(Struct* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Struct* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Struct::UnsafeArenaSwap(Struct* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Struct::InternalSwap(Struct* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -622,15 +599,6 @@ void Value::set_allocated_list_value(PROTOBUF_NAMESPACE_ID::ListValue* list_valu
}
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.list_value)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Value::kNullValueFieldNumber;
const int Value::kNumberValueFieldNumber;
const int Value::kStringValueFieldNumber;
const int Value::kBoolValueFieldNumber;
const int Value::kStructValueFieldNumber;
const int Value::kListValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Value::Value()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1181,25 +1149,6 @@ bool Value::IsInitialized() const {
return true;
}
void Value::Swap(Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Value* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Value::UnsafeArenaSwap(Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Value::InternalSwap(Value* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -1220,10 +1169,6 @@ class ListValue::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ListValue::kValuesFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
ListValue::ListValue()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1482,25 +1427,6 @@ bool ListValue::IsInitialized() const {
return true;
}
void ListValue::Swap(ListValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
ListValue* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void ListValue::UnsafeArenaSwap(ListValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void ListValue::InternalSwap(ListValue* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -188,11 +188,22 @@ class PROTOBUF_EXPORT Struct :
static constexpr int kIndexInFileMessages =
1;
void UnsafeArenaSwap(Struct* other);
void Swap(Struct* other);
friend void swap(Struct& a, Struct& b) {
a.Swap(&b);
}
inline void Swap(Struct* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Struct* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -260,10 +271,12 @@ class PROTOBUF_EXPORT Struct :
// accessors -------------------------------------------------------
enum : int {
kFieldsFieldNumber = 1,
};
// map<string, .google.protobuf.Value> fields = 1;
int fields_size() const;
void clear_fields();
static const int kFieldsFieldNumber = 1;
const ::PROTOBUF_NAMESPACE_ID::Map< std::string, PROTOBUF_NAMESPACE_ID::Value >&
fields() const;
::PROTOBUF_NAMESPACE_ID::Map< std::string, PROTOBUF_NAMESPACE_ID::Value >*
@ -348,11 +361,22 @@ class PROTOBUF_EXPORT Value :
static constexpr int kIndexInFileMessages =
2;
void UnsafeArenaSwap(Value* other);
void Swap(Value* other);
friend void swap(Value& a, Value& b) {
a.Swap(&b);
}
inline void Swap(Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -419,12 +443,19 @@ class PROTOBUF_EXPORT Value :
// accessors -------------------------------------------------------
enum : int {
kNullValueFieldNumber = 1,
kNumberValueFieldNumber = 2,
kStringValueFieldNumber = 3,
kBoolValueFieldNumber = 4,
kStructValueFieldNumber = 5,
kListValueFieldNumber = 6,
};
// .google.protobuf.NullValue null_value = 1;
private:
bool has_null_value() const;
public:
void clear_null_value();
static const int kNullValueFieldNumber = 1;
PROTOBUF_NAMESPACE_ID::NullValue null_value() const;
void set_null_value(PROTOBUF_NAMESPACE_ID::NullValue value);
@ -433,7 +464,6 @@ class PROTOBUF_EXPORT Value :
bool has_number_value() const;
public:
void clear_number_value();
static const int kNumberValueFieldNumber = 2;
double number_value() const;
void set_number_value(double value);
@ -442,7 +472,6 @@ class PROTOBUF_EXPORT Value :
bool has_string_value() const;
public:
void clear_string_value();
static const int kStringValueFieldNumber = 3;
const std::string& string_value() const;
void set_string_value(const std::string& value);
void set_string_value(std::string&& value);
@ -466,14 +495,12 @@ class PROTOBUF_EXPORT Value :
bool has_bool_value() const;
public:
void clear_bool_value();
static const int kBoolValueFieldNumber = 4;
bool bool_value() const;
void set_bool_value(bool value);
// .google.protobuf.Struct struct_value = 5;
bool has_struct_value() const;
void clear_struct_value();
static const int kStructValueFieldNumber = 5;
const PROTOBUF_NAMESPACE_ID::Struct& struct_value() const;
PROTOBUF_NAMESPACE_ID::Struct* release_struct_value();
PROTOBUF_NAMESPACE_ID::Struct* mutable_struct_value();
@ -485,7 +512,6 @@ class PROTOBUF_EXPORT Value :
// .google.protobuf.ListValue list_value = 6;
bool has_list_value() const;
void clear_list_value();
static const int kListValueFieldNumber = 6;
const PROTOBUF_NAMESPACE_ID::ListValue& list_value() const;
PROTOBUF_NAMESPACE_ID::ListValue* release_list_value();
PROTOBUF_NAMESPACE_ID::ListValue* mutable_list_value();
@ -579,11 +605,22 @@ class PROTOBUF_EXPORT ListValue :
static constexpr int kIndexInFileMessages =
3;
void UnsafeArenaSwap(ListValue* other);
void Swap(ListValue* other);
friend void swap(ListValue& a, ListValue& b) {
a.Swap(&b);
}
inline void Swap(ListValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(ListValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -650,10 +687,12 @@ class PROTOBUF_EXPORT ListValue :
// accessors -------------------------------------------------------
enum : int {
kValuesFieldNumber = 1,
};
// repeated .google.protobuf.Value values = 1;
int values_size() const;
void clear_values();
static const int kValuesFieldNumber = 1;
PROTOBUF_NAMESPACE_ID::Value* mutable_values(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Value >*
mutable_values();

@ -126,8 +126,7 @@ bool MathUtil::WithinFractionOrMargin(const T x, const T y,
if (MathLimits<T>::kIsInteger) {
return x == y;
} else {
// IsFinite checks are to make kPosInf and kNegInf not within fraction
if (!MathLimits<T>::IsFinite(x) && !MathLimits<T>::IsFinite(y)) {
if (!MathLimits<T>::IsFinite(x) || !MathLimits<T>::IsFinite(y)) {
return false;
}
T relative_margin = static_cast<T>(fraction * Max(Abs(x), Abs(y)));

@ -90,11 +90,6 @@ class Timestamp::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Timestamp::kSecondsFieldNumber;
const int Timestamp::kNanosFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Timestamp::Timestamp()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -386,25 +381,6 @@ bool Timestamp::IsInitialized() const {
return true;
}
void Timestamp::Swap(Timestamp* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Timestamp* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Timestamp::UnsafeArenaSwap(Timestamp* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Timestamp::InternalSwap(Timestamp* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -116,11 +116,22 @@ class PROTOBUF_EXPORT Timestamp :
static constexpr int kIndexInFileMessages =
0;
void UnsafeArenaSwap(Timestamp* other);
void Swap(Timestamp* other);
friend void swap(Timestamp& a, Timestamp& b) {
a.Swap(&b);
}
inline void Swap(Timestamp* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Timestamp* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -187,15 +198,17 @@ class PROTOBUF_EXPORT Timestamp :
// accessors -------------------------------------------------------
enum : int {
kSecondsFieldNumber = 1,
kNanosFieldNumber = 2,
};
// int64 seconds = 1;
void clear_seconds();
static const int kSecondsFieldNumber = 1;
::PROTOBUF_NAMESPACE_ID::int64 seconds() const;
void set_seconds(::PROTOBUF_NAMESPACE_ID::int64 value);
// int32 nanos = 2;
void clear_nanos();
static const int kNanosFieldNumber = 2;
::PROTOBUF_NAMESPACE_ID::int32 nanos() const;
void set_nanos(::PROTOBUF_NAMESPACE_ID::int32 value);

@ -388,15 +388,6 @@ void Type::clear_source_context() {
}
source_context_ = nullptr;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Type::kNameFieldNumber;
const int Type::kFieldsFieldNumber;
const int Type::kOneofsFieldNumber;
const int Type::kOptionsFieldNumber;
const int Type::kSourceContextFieldNumber;
const int Type::kSyntaxFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Type::Type()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -930,25 +921,6 @@ bool Type::IsInitialized() const {
return true;
}
void Type::Swap(Type* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Type* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Type::UnsafeArenaSwap(Type* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Type::InternalSwap(Type* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -974,19 +946,6 @@ class Field::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Field::kKindFieldNumber;
const int Field::kCardinalityFieldNumber;
const int Field::kNumberFieldNumber;
const int Field::kNameFieldNumber;
const int Field::kTypeUrlFieldNumber;
const int Field::kOneofIndexFieldNumber;
const int Field::kPackedFieldNumber;
const int Field::kOptionsFieldNumber;
const int Field::kJsonNameFieldNumber;
const int Field::kDefaultValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Field::Field()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1702,25 +1661,6 @@ bool Field::IsInitialized() const {
return true;
}
void Field::Swap(Field* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Field* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Field::UnsafeArenaSwap(Field* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Field::InternalSwap(Field* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -1779,14 +1719,6 @@ void Enum::clear_source_context() {
}
source_context_ = nullptr;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Enum::kNameFieldNumber;
const int Enum::kEnumvalueFieldNumber;
const int Enum::kOptionsFieldNumber;
const int Enum::kSourceContextFieldNumber;
const int Enum::kSyntaxFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Enum::Enum()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -2260,25 +2192,6 @@ bool Enum::IsInitialized() const {
return true;
}
void Enum::Swap(Enum* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Enum* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Enum::UnsafeArenaSwap(Enum* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Enum::InternalSwap(Enum* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -2303,12 +2216,6 @@ class EnumValue::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EnumValue::kNameFieldNumber;
const int EnumValue::kNumberFieldNumber;
const int EnumValue::kOptionsFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
EnumValue::EnumValue()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -2671,25 +2578,6 @@ bool EnumValue::IsInitialized() const {
return true;
}
void EnumValue::Swap(EnumValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
EnumValue* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void EnumValue::UnsafeArenaSwap(EnumValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void EnumValue::InternalSwap(EnumValue* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -2738,11 +2626,6 @@ void Option::clear_value() {
}
value_ = nullptr;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Option::kNameFieldNumber;
const int Option::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Option::Option()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -3059,25 +2942,6 @@ bool Option::IsInitialized() const {
return true;
}
void Option::Swap(Option* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Option* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Option::UnsafeArenaSwap(Option* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Option::InternalSwap(Option* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -229,11 +229,22 @@ class PROTOBUF_EXPORT Type :
static constexpr int kIndexInFileMessages =
0;
void UnsafeArenaSwap(Type* other);
void Swap(Type* other);
friend void swap(Type& a, Type& b) {
a.Swap(&b);
}
inline void Swap(Type* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Type* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -300,10 +311,17 @@ class PROTOBUF_EXPORT Type :
// accessors -------------------------------------------------------
enum : int {
kFieldsFieldNumber = 2,
kOneofsFieldNumber = 3,
kOptionsFieldNumber = 4,
kNameFieldNumber = 1,
kSourceContextFieldNumber = 5,
kSyntaxFieldNumber = 6,
};
// repeated .google.protobuf.Field fields = 2;
int fields_size() const;
void clear_fields();
static const int kFieldsFieldNumber = 2;
PROTOBUF_NAMESPACE_ID::Field* mutable_fields(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Field >*
mutable_fields();
@ -315,7 +333,6 @@ class PROTOBUF_EXPORT Type :
// repeated string oneofs = 3;
int oneofs_size() const;
void clear_oneofs();
static const int kOneofsFieldNumber = 3;
const std::string& oneofs(int index) const;
std::string* mutable_oneofs(int index);
void set_oneofs(int index, const std::string& value);
@ -333,7 +350,6 @@ class PROTOBUF_EXPORT Type :
// repeated .google.protobuf.Option options = 4;
int options_size() const;
void clear_options();
static const int kOptionsFieldNumber = 4;
PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
mutable_options();
@ -344,7 +360,6 @@ class PROTOBUF_EXPORT Type :
// string name = 1;
void clear_name();
static const int kNameFieldNumber = 1;
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
@ -366,7 +381,6 @@ class PROTOBUF_EXPORT Type :
// .google.protobuf.SourceContext source_context = 5;
bool has_source_context() const;
void clear_source_context();
static const int kSourceContextFieldNumber = 5;
const PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
@ -377,7 +391,6 @@ class PROTOBUF_EXPORT Type :
// .google.protobuf.Syntax syntax = 6;
void clear_syntax();
static const int kSyntaxFieldNumber = 6;
PROTOBUF_NAMESPACE_ID::Syntax syntax() const;
void set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value);
@ -450,11 +463,22 @@ class PROTOBUF_EXPORT Field :
static constexpr int kIndexInFileMessages =
1;
void UnsafeArenaSwap(Field* other);
void Swap(Field* other);
friend void swap(Field& a, Field& b) {
a.Swap(&b);
}
inline void Swap(Field* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Field* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -619,10 +643,21 @@ class PROTOBUF_EXPORT Field :
// accessors -------------------------------------------------------
enum : int {
kOptionsFieldNumber = 9,
kNameFieldNumber = 4,
kTypeUrlFieldNumber = 6,
kJsonNameFieldNumber = 10,
kDefaultValueFieldNumber = 11,
kKindFieldNumber = 1,
kCardinalityFieldNumber = 2,
kNumberFieldNumber = 3,
kOneofIndexFieldNumber = 7,
kPackedFieldNumber = 8,
};
// repeated .google.protobuf.Option options = 9;
int options_size() const;
void clear_options();
static const int kOptionsFieldNumber = 9;
PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
mutable_options();
@ -633,7 +668,6 @@ class PROTOBUF_EXPORT Field :
// string name = 4;
void clear_name();
static const int kNameFieldNumber = 4;
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
@ -654,7 +688,6 @@ class PROTOBUF_EXPORT Field :
// string type_url = 6;
void clear_type_url();
static const int kTypeUrlFieldNumber = 6;
const std::string& type_url() const;
void set_type_url(const std::string& value);
void set_type_url(std::string&& value);
@ -675,7 +708,6 @@ class PROTOBUF_EXPORT Field :
// string json_name = 10;
void clear_json_name();
static const int kJsonNameFieldNumber = 10;
const std::string& json_name() const;
void set_json_name(const std::string& value);
void set_json_name(std::string&& value);
@ -696,7 +728,6 @@ class PROTOBUF_EXPORT Field :
// string default_value = 11;
void clear_default_value();
static const int kDefaultValueFieldNumber = 11;
const std::string& default_value() const;
void set_default_value(const std::string& value);
void set_default_value(std::string&& value);
@ -717,31 +748,26 @@ class PROTOBUF_EXPORT Field :
// .google.protobuf.Field.Kind kind = 1;
void clear_kind();
static const int kKindFieldNumber = 1;
PROTOBUF_NAMESPACE_ID::Field_Kind kind() const;
void set_kind(PROTOBUF_NAMESPACE_ID::Field_Kind value);
// .google.protobuf.Field.Cardinality cardinality = 2;
void clear_cardinality();
static const int kCardinalityFieldNumber = 2;
PROTOBUF_NAMESPACE_ID::Field_Cardinality cardinality() const;
void set_cardinality(PROTOBUF_NAMESPACE_ID::Field_Cardinality value);
// int32 number = 3;
void clear_number();
static const int kNumberFieldNumber = 3;
::PROTOBUF_NAMESPACE_ID::int32 number() const;
void set_number(::PROTOBUF_NAMESPACE_ID::int32 value);
// int32 oneof_index = 7;
void clear_oneof_index();
static const int kOneofIndexFieldNumber = 7;
::PROTOBUF_NAMESPACE_ID::int32 oneof_index() const;
void set_oneof_index(::PROTOBUF_NAMESPACE_ID::int32 value);
// bool packed = 8;
void clear_packed();
static const int kPackedFieldNumber = 8;
bool packed() const;
void set_packed(bool value);
@ -818,11 +844,22 @@ class PROTOBUF_EXPORT Enum :
static constexpr int kIndexInFileMessages =
2;
void UnsafeArenaSwap(Enum* other);
void Swap(Enum* other);
friend void swap(Enum& a, Enum& b) {
a.Swap(&b);
}
inline void Swap(Enum* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Enum* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -889,10 +926,16 @@ class PROTOBUF_EXPORT Enum :
// accessors -------------------------------------------------------
enum : int {
kEnumvalueFieldNumber = 2,
kOptionsFieldNumber = 3,
kNameFieldNumber = 1,
kSourceContextFieldNumber = 4,
kSyntaxFieldNumber = 5,
};
// repeated .google.protobuf.EnumValue enumvalue = 2;
int enumvalue_size() const;
void clear_enumvalue();
static const int kEnumvalueFieldNumber = 2;
PROTOBUF_NAMESPACE_ID::EnumValue* mutable_enumvalue(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::EnumValue >*
mutable_enumvalue();
@ -904,7 +947,6 @@ class PROTOBUF_EXPORT Enum :
// repeated .google.protobuf.Option options = 3;
int options_size() const;
void clear_options();
static const int kOptionsFieldNumber = 3;
PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
mutable_options();
@ -915,7 +957,6 @@ class PROTOBUF_EXPORT Enum :
// string name = 1;
void clear_name();
static const int kNameFieldNumber = 1;
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
@ -937,7 +978,6 @@ class PROTOBUF_EXPORT Enum :
// .google.protobuf.SourceContext source_context = 4;
bool has_source_context() const;
void clear_source_context();
static const int kSourceContextFieldNumber = 4;
const PROTOBUF_NAMESPACE_ID::SourceContext& source_context() const;
PROTOBUF_NAMESPACE_ID::SourceContext* release_source_context();
PROTOBUF_NAMESPACE_ID::SourceContext* mutable_source_context();
@ -948,7 +988,6 @@ class PROTOBUF_EXPORT Enum :
// .google.protobuf.Syntax syntax = 5;
void clear_syntax();
static const int kSyntaxFieldNumber = 5;
PROTOBUF_NAMESPACE_ID::Syntax syntax() const;
void set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value);
@ -1020,11 +1059,22 @@ class PROTOBUF_EXPORT EnumValue :
static constexpr int kIndexInFileMessages =
3;
void UnsafeArenaSwap(EnumValue* other);
void Swap(EnumValue* other);
friend void swap(EnumValue& a, EnumValue& b) {
a.Swap(&b);
}
inline void Swap(EnumValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(EnumValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -1091,10 +1141,14 @@ class PROTOBUF_EXPORT EnumValue :
// accessors -------------------------------------------------------
enum : int {
kOptionsFieldNumber = 3,
kNameFieldNumber = 1,
kNumberFieldNumber = 2,
};
// repeated .google.protobuf.Option options = 3;
int options_size() const;
void clear_options();
static const int kOptionsFieldNumber = 3;
PROTOBUF_NAMESPACE_ID::Option* mutable_options(int index);
::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option >*
mutable_options();
@ -1105,7 +1159,6 @@ class PROTOBUF_EXPORT EnumValue :
// string name = 1;
void clear_name();
static const int kNameFieldNumber = 1;
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
@ -1126,7 +1179,6 @@ class PROTOBUF_EXPORT EnumValue :
// int32 number = 2;
void clear_number();
static const int kNumberFieldNumber = 2;
::PROTOBUF_NAMESPACE_ID::int32 number() const;
void set_number(::PROTOBUF_NAMESPACE_ID::int32 value);
@ -1196,11 +1248,22 @@ class PROTOBUF_EXPORT Option :
static constexpr int kIndexInFileMessages =
4;
void UnsafeArenaSwap(Option* other);
void Swap(Option* other);
friend void swap(Option& a, Option& b) {
a.Swap(&b);
}
inline void Swap(Option* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Option* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -1267,9 +1330,12 @@ class PROTOBUF_EXPORT Option :
// accessors -------------------------------------------------------
enum : int {
kNameFieldNumber = 1,
kValueFieldNumber = 2,
};
// string name = 1;
void clear_name();
static const int kNameFieldNumber = 1;
const std::string& name() const;
void set_name(const std::string& value);
void set_name(std::string&& value);
@ -1291,7 +1357,6 @@ class PROTOBUF_EXPORT Option :
// .google.protobuf.Any value = 2;
bool has_value() const;
void clear_value();
static const int kValueFieldNumber = 2;
const PROTOBUF_NAMESPACE_ID::Any& value() const;
PROTOBUF_NAMESPACE_ID::Any* release_value();
PROTOBUF_NAMESPACE_ID::Any* mutable_value();

@ -287,28 +287,30 @@ uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const {
#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
namespace internal {
const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx,
bool (*is_valid)(int), UnknownFieldSet* unknown,
bool (*is_valid)(int),
InternalMetadataWithArena* metadata,
int field_num) {
return ctx->ReadPackedVarint(
ptr, [object, is_valid, unknown, field_num](uint64 val) {
ptr, [object, is_valid, metadata, field_num](uint64 val) {
if (is_valid(val)) {
static_cast<RepeatedField<int>*>(object)->Add(val);
} else {
WriteVarint(field_num, val, unknown);
WriteVarint(field_num, val, metadata->mutable_unknown_fields());
}
});
}
const char* PackedEnumParserArg(void* object, const char* ptr,
ParseContext* ctx,
bool (*is_valid)(const void*, int),
const void* data, UnknownFieldSet* unknown,
const void* data,
InternalMetadataWithArena* metadata,
int field_num) {
return ctx->ReadPackedVarint(
ptr, [object, is_valid, data, unknown, field_num](uint64 val) {
ptr, [object, is_valid, data, metadata, field_num](uint64 val) {
if (is_valid(data, val)) {
static_cast<RepeatedField<int>*>(object)->Add(val);
} else {
WriteVarint(field_num, val, unknown);
WriteVarint(field_num, val, metadata->mutable_unknown_fields());
}
});
}

@ -196,13 +196,14 @@ inline void WriteLengthDelimited(uint32 num, StringPiece val,
PROTOBUF_EXPORT
const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx,
bool (*is_valid)(int), UnknownFieldSet* unknown,
int field_num);
bool (*is_valid)(int),
InternalMetadataWithArena* unknown, int field_num);
PROTOBUF_EXPORT
const char* PackedEnumParserArg(void* object, const char* ptr,
ParseContext* ctx,
bool (*is_valid)(const void*, int),
const void* data, UnknownFieldSet* unknown,
const void* data,
InternalMetadataWithArena* unknown,
int field_num);
PROTOBUF_EXPORT

@ -388,6 +388,20 @@ TEST_F(DefaultFieldComparatorTest,
EXPECT_EQ(
FieldComparator::SAME,
comparator_.Compare(message_1_, message_2_, field_double, -1, -1, NULL));
// Finite values and inf should not be equal, even for a positive fraction.
message_1_.set_optional_float(std::numeric_limits<float>::infinity());
message_2_.set_optional_float(0.0f);
message_1_.set_optional_double(std::numeric_limits<double>::infinity());
message_2_.set_optional_double(0.0);
comparator_.SetFractionAndMargin(field_float, 0.1, 0.0);
comparator_.SetFractionAndMargin(field_double, 0.1, 0.0);
EXPECT_EQ(FieldComparator::DIFFERENT,
comparator_.Compare(message_1_, message_2_, field_float, -1, -1,
nullptr));
EXPECT_EQ(FieldComparator::DIFFERENT,
comparator_.Compare(message_1_, message_2_, field_double, -1, -1,
nullptr));
}
TEST_F(DefaultFieldComparatorTest,

@ -117,3 +117,14 @@ message TestStringSerializer {
repeated string repeated_string = 2;
map<string, string> string_map = 3;
}
message TestMessageWithExtension {
extensions 100 to max;
}
message TestExtension {
extend TestMessageWithExtension {
optional TestExtension ext = 100;
}
optional string value = 1;
}

@ -1640,7 +1640,8 @@ bool MessageDifferencer::MatchRepeatedFieldIndices(
for (int j = start_offset; j < count2; j++) {
if (match_list2->at(j) != -1) {
if (!is_treated_as_smart_set || num_diffs_list1[i] == 0) {
if (!is_treated_as_smart_set || num_diffs_list1[i] == 0 ||
num_diffs_list1[match_list2->at(j)] == 0) {
continue;
}
}
@ -1662,8 +1663,13 @@ bool MessageDifferencer::MatchRepeatedFieldIndices(
// Replace with the one with fewer diffs.
const int32 num_diffs = num_diffs_reporter.GetNumDiffs();
if (num_diffs < num_diffs_list1[i]) {
num_diffs_list1[i] = num_diffs;
match = true;
// If j has been already matched to some element, ensure the
// current num_diffs is smaller.
if (match_list2->at(j) == -1 ||
num_diffs < num_diffs_list1[match_list2->at(j)]) {
num_diffs_list1[i] = num_diffs;
match = true;
}
}
}
}

@ -1158,6 +1158,65 @@ TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest) {
diff_report);
}
TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest_IdenticalElements) {
// Create the testing protos
protobuf_unittest::TestDiffMessage msg1;
protobuf_unittest::TestDiffMessage msg2;
protobuf_unittest::TestField elem;
elem.set_a(1);
elem.set_b(1);
elem.set_c(1);
*msg1.add_rm() = elem;
*msg1.add_rm() = elem;
*msg2.add_rm() = elem;
*msg2.add_rm() = elem;
util::MessageDifferencer differencer;
differencer.set_repeated_field_comparison(
util::MessageDifferencer::AS_SMART_SET);
EXPECT_TRUE(differencer.Compare(msg1, msg2));
}
TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest_PreviouslyMatch) {
// Create the testing protos
protobuf_unittest::TestDiffMessage msg1;
protobuf_unittest::TestDiffMessage msg2;
protobuf_unittest::TestField elem1_1, elem1_2;
protobuf_unittest::TestField elem2_1, elem2_2;
elem1_1.set_a(1);
elem1_1.set_b(1);
elem1_1.set_c(1);
elem1_2.set_a(1);
elem1_2.set_b(1);
elem1_2.set_c(0);
elem2_1.set_a(1);
elem2_1.set_b(1);
elem2_1.set_c(1);
elem2_2.set_a(1);
elem2_2.set_b(0);
elem2_2.set_c(1);
*msg1.add_rm() = elem1_1;
*msg1.add_rm() = elem2_1;
*msg2.add_rm() = elem1_2;
*msg2.add_rm() = elem2_2;
string diff_report;
util::MessageDifferencer differencer;
differencer.ReportDifferencesToString(&diff_report);
differencer.set_repeated_field_comparison(
util::MessageDifferencer::AS_SMART_SET);
EXPECT_FALSE(differencer.Compare(msg1, msg2));
EXPECT_EQ(
"modified: rm[0].c: 1 -> 0\n"
"modified: rm[1].b: 1 -> 0\n",
diff_report);
}
TEST(MessageDifferencerTest, RepeatedFieldSmartSet_MultipleMatches) {
// Create the testing protos
protobuf_unittest::TestDiffMessage msg1;

@ -1427,7 +1427,7 @@ inline uint8* WireFormatLite::WritePrimitiveNoTagToArray(
const int n = value.size();
GOOGLE_DCHECK_GT(n, 0);
const T* ii = value.unsafe_data();
const T* ii = value.data();
int i = 0;
do {
target = Writer(ii[i], target);
@ -1445,7 +1445,7 @@ inline uint8* WireFormatLite::WriteFixedNoTagToArray(
const int n = value.size();
GOOGLE_DCHECK_GT(n, 0);
const T* ii = value.unsafe_data();
const T* ii = value.data();
const int bytes = n * static_cast<int>(sizeof(ii[0]));
memcpy(target, ii, static_cast<size_t>(bytes));
return target + bytes;
@ -1591,7 +1591,7 @@ inline uint8* WireFormatLite::WritePrimitiveToArray(
return target;
}
const T* ii = value.unsafe_data();
const T* ii = value.data();
int i = 0;
do {
target = Writer(field_number, ii[i], target);

@ -311,10 +311,6 @@ class DoubleValue::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int DoubleValue::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
DoubleValue::DoubleValue()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -558,25 +554,6 @@ bool DoubleValue::IsInitialized() const {
return true;
}
void DoubleValue::Swap(DoubleValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
DoubleValue* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void DoubleValue::UnsafeArenaSwap(DoubleValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void DoubleValue::InternalSwap(DoubleValue* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -596,10 +573,6 @@ class FloatValue::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int FloatValue::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
FloatValue::FloatValue()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -843,25 +816,6 @@ bool FloatValue::IsInitialized() const {
return true;
}
void FloatValue::Swap(FloatValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
FloatValue* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void FloatValue::UnsafeArenaSwap(FloatValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void FloatValue::InternalSwap(FloatValue* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -881,10 +835,6 @@ class Int64Value::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Int64Value::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Int64Value::Int64Value()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1130,25 +1080,6 @@ bool Int64Value::IsInitialized() const {
return true;
}
void Int64Value::Swap(Int64Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Int64Value* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Int64Value::UnsafeArenaSwap(Int64Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Int64Value::InternalSwap(Int64Value* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -1168,10 +1099,6 @@ class UInt64Value::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int UInt64Value::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
UInt64Value::UInt64Value()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1417,25 +1344,6 @@ bool UInt64Value::IsInitialized() const {
return true;
}
void UInt64Value::Swap(UInt64Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
UInt64Value* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void UInt64Value::UnsafeArenaSwap(UInt64Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void UInt64Value::InternalSwap(UInt64Value* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -1455,10 +1363,6 @@ class Int32Value::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Int32Value::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Int32Value::Int32Value()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1704,25 +1608,6 @@ bool Int32Value::IsInitialized() const {
return true;
}
void Int32Value::Swap(Int32Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
Int32Value* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void Int32Value::UnsafeArenaSwap(Int32Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Int32Value::InternalSwap(Int32Value* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -1742,10 +1627,6 @@ class UInt32Value::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int UInt32Value::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
UInt32Value::UInt32Value()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -1991,25 +1872,6 @@ bool UInt32Value::IsInitialized() const {
return true;
}
void UInt32Value::Swap(UInt32Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
UInt32Value* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void UInt32Value::UnsafeArenaSwap(UInt32Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void UInt32Value::InternalSwap(UInt32Value* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -2029,10 +1891,6 @@ class BoolValue::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int BoolValue::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
BoolValue::BoolValue()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -2276,25 +2134,6 @@ bool BoolValue::IsInitialized() const {
return true;
}
void BoolValue::Swap(BoolValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
BoolValue* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void BoolValue::UnsafeArenaSwap(BoolValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void BoolValue::InternalSwap(BoolValue* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -2314,10 +2153,6 @@ class StringValue::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int StringValue::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
StringValue::StringValue()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -2582,25 +2417,6 @@ bool StringValue::IsInitialized() const {
return true;
}
void StringValue::Swap(StringValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
StringValue* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void StringValue::UnsafeArenaSwap(StringValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void StringValue::InternalSwap(StringValue* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);
@ -2621,10 +2437,6 @@ class BytesValue::_Internal {
public:
};
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int BytesValue::kValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
BytesValue::BytesValue()
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
SharedCtor();
@ -2877,25 +2689,6 @@ bool BytesValue::IsInitialized() const {
return true;
}
void BytesValue::Swap(BytesValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
BytesValue* temp = New(GetArenaNoVirtual());
temp->MergeFrom(*other);
other->CopyFrom(*this);
InternalSwap(temp);
if (GetArenaNoVirtual() == nullptr) {
delete temp;
}
}
}
void BytesValue::UnsafeArenaSwap(BytesValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void BytesValue::InternalSwap(BytesValue* other) {
using std::swap;
_internal_metadata_.Swap(&other->_internal_metadata_);

@ -148,11 +148,22 @@ class PROTOBUF_EXPORT DoubleValue :
static constexpr int kIndexInFileMessages =
0;
void UnsafeArenaSwap(DoubleValue* other);
void Swap(DoubleValue* other);
friend void swap(DoubleValue& a, DoubleValue& b) {
a.Swap(&b);
}
inline void Swap(DoubleValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(DoubleValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -219,9 +230,11 @@ class PROTOBUF_EXPORT DoubleValue :
// accessors -------------------------------------------------------
enum : int {
kValueFieldNumber = 1,
};
// double value = 1;
void clear_value();
static const int kValueFieldNumber = 1;
double value() const;
void set_value(double value);
@ -289,11 +302,22 @@ class PROTOBUF_EXPORT FloatValue :
static constexpr int kIndexInFileMessages =
1;
void UnsafeArenaSwap(FloatValue* other);
void Swap(FloatValue* other);
friend void swap(FloatValue& a, FloatValue& b) {
a.Swap(&b);
}
inline void Swap(FloatValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(FloatValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -360,9 +384,11 @@ class PROTOBUF_EXPORT FloatValue :
// accessors -------------------------------------------------------
enum : int {
kValueFieldNumber = 1,
};
// float value = 1;
void clear_value();
static const int kValueFieldNumber = 1;
float value() const;
void set_value(float value);
@ -430,11 +456,22 @@ class PROTOBUF_EXPORT Int64Value :
static constexpr int kIndexInFileMessages =
2;
void UnsafeArenaSwap(Int64Value* other);
void Swap(Int64Value* other);
friend void swap(Int64Value& a, Int64Value& b) {
a.Swap(&b);
}
inline void Swap(Int64Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Int64Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -501,9 +538,11 @@ class PROTOBUF_EXPORT Int64Value :
// accessors -------------------------------------------------------
enum : int {
kValueFieldNumber = 1,
};
// int64 value = 1;
void clear_value();
static const int kValueFieldNumber = 1;
::PROTOBUF_NAMESPACE_ID::int64 value() const;
void set_value(::PROTOBUF_NAMESPACE_ID::int64 value);
@ -571,11 +610,22 @@ class PROTOBUF_EXPORT UInt64Value :
static constexpr int kIndexInFileMessages =
3;
void UnsafeArenaSwap(UInt64Value* other);
void Swap(UInt64Value* other);
friend void swap(UInt64Value& a, UInt64Value& b) {
a.Swap(&b);
}
inline void Swap(UInt64Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(UInt64Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -642,9 +692,11 @@ class PROTOBUF_EXPORT UInt64Value :
// accessors -------------------------------------------------------
enum : int {
kValueFieldNumber = 1,
};
// uint64 value = 1;
void clear_value();
static const int kValueFieldNumber = 1;
::PROTOBUF_NAMESPACE_ID::uint64 value() const;
void set_value(::PROTOBUF_NAMESPACE_ID::uint64 value);
@ -712,11 +764,22 @@ class PROTOBUF_EXPORT Int32Value :
static constexpr int kIndexInFileMessages =
4;
void UnsafeArenaSwap(Int32Value* other);
void Swap(Int32Value* other);
friend void swap(Int32Value& a, Int32Value& b) {
a.Swap(&b);
}
inline void Swap(Int32Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(Int32Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -783,9 +846,11 @@ class PROTOBUF_EXPORT Int32Value :
// accessors -------------------------------------------------------
enum : int {
kValueFieldNumber = 1,
};
// int32 value = 1;
void clear_value();
static const int kValueFieldNumber = 1;
::PROTOBUF_NAMESPACE_ID::int32 value() const;
void set_value(::PROTOBUF_NAMESPACE_ID::int32 value);
@ -853,11 +918,22 @@ class PROTOBUF_EXPORT UInt32Value :
static constexpr int kIndexInFileMessages =
5;
void UnsafeArenaSwap(UInt32Value* other);
void Swap(UInt32Value* other);
friend void swap(UInt32Value& a, UInt32Value& b) {
a.Swap(&b);
}
inline void Swap(UInt32Value* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(UInt32Value* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -924,9 +1000,11 @@ class PROTOBUF_EXPORT UInt32Value :
// accessors -------------------------------------------------------
enum : int {
kValueFieldNumber = 1,
};
// uint32 value = 1;
void clear_value();
static const int kValueFieldNumber = 1;
::PROTOBUF_NAMESPACE_ID::uint32 value() const;
void set_value(::PROTOBUF_NAMESPACE_ID::uint32 value);
@ -994,11 +1072,22 @@ class PROTOBUF_EXPORT BoolValue :
static constexpr int kIndexInFileMessages =
6;
void UnsafeArenaSwap(BoolValue* other);
void Swap(BoolValue* other);
friend void swap(BoolValue& a, BoolValue& b) {
a.Swap(&b);
}
inline void Swap(BoolValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(BoolValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -1065,9 +1154,11 @@ class PROTOBUF_EXPORT BoolValue :
// accessors -------------------------------------------------------
enum : int {
kValueFieldNumber = 1,
};
// bool value = 1;
void clear_value();
static const int kValueFieldNumber = 1;
bool value() const;
void set_value(bool value);
@ -1135,11 +1226,22 @@ class PROTOBUF_EXPORT StringValue :
static constexpr int kIndexInFileMessages =
7;
void UnsafeArenaSwap(StringValue* other);
void Swap(StringValue* other);
friend void swap(StringValue& a, StringValue& b) {
a.Swap(&b);
}
inline void Swap(StringValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(StringValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -1206,9 +1308,11 @@ class PROTOBUF_EXPORT StringValue :
// accessors -------------------------------------------------------
enum : int {
kValueFieldNumber = 1,
};
// string value = 1;
void clear_value();
static const int kValueFieldNumber = 1;
const std::string& value() const;
void set_value(const std::string& value);
void set_value(std::string&& value);
@ -1291,11 +1395,22 @@ class PROTOBUF_EXPORT BytesValue :
static constexpr int kIndexInFileMessages =
8;
void UnsafeArenaSwap(BytesValue* other);
void Swap(BytesValue* other);
friend void swap(BytesValue& a, BytesValue& b) {
a.Swap(&b);
}
inline void Swap(BytesValue* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(BytesValue* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
// implements Message ----------------------------------------------
@ -1362,9 +1477,11 @@ class PROTOBUF_EXPORT BytesValue :
// accessors -------------------------------------------------------
enum : int {
kValueFieldNumber = 1,
};
// bytes value = 1;
void clear_value();
static const int kValueFieldNumber = 1;
const std::string& value() const;
void set_value(const std::string& value);
void set_value(std::string&& value);

Loading…
Cancel
Save