PROTOBUF_SYNC_PIPER
pull/7925/head
Joshua Haberman 4 years ago
parent 38d6de1eef
commit de371235c9
  1. 4
      .github/mergeable.yml
  2. 2
      .github/workflows/codespell.yml
  3. 28
      BUILD
  4. 4
      WORKSPACE
  5. 8
      conformance/text_format_failure_list_java.txt
  6. 17
      java/core/src/main/java/com/google/protobuf/CodedInputStream.java
  7. 5
      java/core/src/main/java/com/google/protobuf/Descriptors.java
  8. 2
      java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java
  9. 2
      java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
  10. 2
      java/core/src/main/java/com/google/protobuf/FieldType.java
  11. 7
      java/core/src/main/java/com/google/protobuf/NioByteString.java
  12. 69
      java/core/src/main/java/com/google/protobuf/TextFormat.java
  13. 1
      java/core/src/main/java/com/google/protobuf/TypeRegistry.java
  14. 13
      java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
  15. 165
      java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
  16. 108
      java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
  17. 179
      java/core/src/test/java/com/google/protobuf/MapLiteTest.java
  18. 190
      java/core/src/test/java/com/google/protobuf/MapTest.java
  19. 88
      java/core/src/test/java/com/google/protobuf/TextFormatTest.java
  20. 60
      java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
  21. 8
      java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
  22. 1
      java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
  23. 24
      java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
  24. 2
      java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java
  25. 4
      java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
  26. 10
      kokoro/linux/dockerfile/test/python27/Dockerfile
  27. 10
      kokoro/linux/dockerfile/test/python35/Dockerfile
  28. 10
      kokoro/linux/dockerfile/test/python36/Dockerfile
  29. 10
      kokoro/linux/dockerfile/test/python37/Dockerfile
  30. 10
      kokoro/linux/dockerfile/test/python38/Dockerfile
  31. 2
      kokoro/linux/python27/continuous.cfg
  32. 2
      kokoro/linux/python27/presubmit.cfg
  33. 2
      kokoro/linux/python27_cpp/continuous.cfg
  34. 2
      kokoro/linux/python27_cpp/presubmit.cfg
  35. 2
      kokoro/linux/python35/continuous.cfg
  36. 2
      kokoro/linux/python35/presubmit.cfg
  37. 2
      kokoro/linux/python35_cpp/continuous.cfg
  38. 2
      kokoro/linux/python35_cpp/presubmit.cfg
  39. 2
      kokoro/linux/python36/continuous.cfg
  40. 2
      kokoro/linux/python36/presubmit.cfg
  41. 2
      kokoro/linux/python36_cpp/continuous.cfg
  42. 2
      kokoro/linux/python36_cpp/presubmit.cfg
  43. 2
      kokoro/linux/python37/continuous.cfg
  44. 2
      kokoro/linux/python37/presubmit.cfg
  45. 2
      kokoro/linux/python37_cpp/continuous.cfg
  46. 2
      kokoro/linux/python37_cpp/presubmit.cfg
  47. 2
      kokoro/linux/python38/continuous.cfg
  48. 2
      kokoro/linux/python38/presubmit.cfg
  49. 2
      kokoro/linux/python38_cpp/continuous.cfg
  50. 2
      kokoro/linux/python38_cpp/presubmit.cfg
  51. 11
      kokoro/macos/php5.6_mac/build.sh
  52. 5
      kokoro/macos/php5.6_mac/continuous.cfg
  53. 5
      kokoro/macos/php5.6_mac/presubmit.cfg
  54. 4
      php/ext/google/protobuf/message.c
  55. 20
      php/ext/google/protobuf/package.xml
  56. 2
      php/ext/google/protobuf/protobuf.h
  57. 4
      php/release.sh
  58. 2
      python/google/protobuf/pyext/message.cc
  59. 3
      python/google/protobuf/text_format.py
  60. 17
      python/protobuf_distutils/README.md
  61. 5
      python/tox.ini
  62. 3
      src/google/protobuf/any.h
  63. 3
      src/google/protobuf/any_lite.cc
  64. 8
      src/google/protobuf/any_test.cc
  65. 34
      src/google/protobuf/arena.cc
  66. 4
      src/google/protobuf/arena.h
  67. 35
      src/google/protobuf/arena_impl.h
  68. 25
      src/google/protobuf/arenastring.h
  69. 3
      src/google/protobuf/arenastring_unittest.cc
  70. 4
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  71. 4
      src/google/protobuf/compiler/cpp/cpp_field.h
  72. 1
      src/google/protobuf/compiler/cpp/cpp_file.cc
  73. 7
      src/google/protobuf/compiler/cpp/cpp_message.cc
  74. 3
      src/google/protobuf/compiler/cpp/cpp_message.h
  75. 1
      src/google/protobuf/compiler/java/java_file.cc
  76. 1
      src/google/protobuf/compiler/java/java_file.h
  77. 70
      src/google/protobuf/compiler/java/java_name_resolver.cc
  78. 18
      src/google/protobuf/compiler/java/java_name_resolver.h
  79. 1
      src/google/protobuf/compiler/main.cc
  80. 6
      src/google/protobuf/compiler/parser_unittest.cc
  81. 114
      src/google/protobuf/descriptor.cc
  82. 20
      src/google/protobuf/descriptor_database.cc
  83. 31
      src/google/protobuf/descriptor_unittest.cc
  84. 8
      src/google/protobuf/extension_set.cc
  85. 5
      src/google/protobuf/extension_set.h
  86. 9
      src/google/protobuf/extension_set_unittest.cc
  87. 1
      src/google/protobuf/generated_message_reflection.cc
  88. 17
      src/google/protobuf/generated_message_util.cc
  89. 12
      src/google/protobuf/generated_message_util.h
  90. 2
      src/google/protobuf/has_bits.h
  91. 2
      src/google/protobuf/implicit_weak_message.h
  92. 11
      src/google/protobuf/map.h
  93. 2
      src/google/protobuf/map_entry.h
  94. 21
      src/google/protobuf/map_entry_lite.h
  95. 22
      src/google/protobuf/map_field.h
  96. 2
      src/google/protobuf/map_field_lite.h
  97. 19
      src/google/protobuf/map_field_test.cc
  98. 39
      src/google/protobuf/map_test.cc
  99. 26
      src/google/protobuf/map_type_handler.h
  100. 2
      src/google/protobuf/message.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -11,8 +11,8 @@ mergeable:
regex: 'release notes: yes'
message: 'Please include release notes: yes'
- must_include:
regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel)'
message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cleanup, conformance tests, integration.'
regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel|cmake|protoc)'
message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cmake, cleanup, conformance tests, integration, protoc.'
- must_include:
regex: 'release notes: no'
message: 'Please include release notes: no'

@ -13,4 +13,4 @@ jobs:
with:
check_filenames: true
skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal
ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"
ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"

28
BUILD

@ -14,10 +14,10 @@ exports_files(["LICENSE"])
# build configuration
################################################################################
# TODO(yannic): Remove in 3.14.0.
string_flag(
name = "incompatible_use_com_google_googletest",
# TODO(yannic): Flip to `true` for `3.13.0`.
build_setting_default = "false",
build_setting_default = "true",
values = ["true", "false"]
)
@ -368,7 +368,15 @@ cc_library(
cc_proto_blacklist_test(
name = "cc_proto_blacklist_test",
deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()]
deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()],
tags = [
# Exclude this target from wildcard expansion (//...). Due to
# https://github.com/bazelbuild/bazel/issues/10590, this test has to
# be nominated using the `@com_google_protobuf//` prefix. We do that,
# e.g., in kokoro/linux/bazel/build.sh.
# See also https://github.com/protocolbuffers/protobuf/pull/7096.
"manual",
],
)
################################################################################
@ -756,6 +764,13 @@ cc_binary(
copts = COPTS + [
"-DPYTHON_PROTO2_CPP_IMPL_V2",
],
tags = [
# Exclude this target from wildcard expansion (//...) because it may
# not even be buildable. It will be built if it is needed according
# to :use_fast_cpp_protos.
# https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes
"manual",
],
linkshared = 1,
linkstatic = 1,
deps = select({
@ -780,6 +795,13 @@ cc_binary(
"python/",
"src/",
],
tags = [
# Exclude this target from wildcard expansion (//...) because it may
# not even be buildable. It will be built if it is needed according
# to :use_fast_cpp_protos.
# https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes
"manual",
],
linkshared = 1,
linkstatic = 1,
deps = [

@ -29,13 +29,13 @@ bind(
actual = "//util/python:python_headers",
)
# TODO(yannic): Remove in 3.13.0.
# TODO(yannic): Remove in 3.14.0.
bind(
name = "gtest",
actual = "@com_google_googletest//:gtest",
)
# TODO(yannic): Remove in 3.13.0.
# TODO(yannic): Remove in 3.14.0.
bind(
name = "gtest_main",
actual = "@com_google_googletest//:gtest_main",

@ -5,14 +5,6 @@ Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput
Required.Proto3.TextFormatInput.AnyField.ProtobufOutput
Required.Proto3.TextFormatInput.AnyField.TextFormatOutput
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput
Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex
Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput

@ -41,6 +41,7 @@ import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
@ -2009,14 +2010,14 @@ public abstract class CodedInputStream {
int prevPos = buffer.position();
int prevLimit = buffer.limit();
try {
buffer.position(bufferPos(begin));
buffer.limit(bufferPos(end));
((Buffer) buffer).position(bufferPos(begin));
((Buffer) buffer).limit(bufferPos(end));
return buffer.slice();
} catch (IllegalArgumentException e) {
throw InvalidProtocolBufferException.truncatedMessage();
} finally {
buffer.position(prevPos);
buffer.limit(prevLimit);
((Buffer) buffer).position(prevPos);
((Buffer) buffer).limit(prevLimit);
}
}
}
@ -3910,14 +3911,14 @@ public abstract class CodedInputStream {
int prevPos = currentByteBuffer.position();
int prevLimit = currentByteBuffer.limit();
try {
currentByteBuffer.position(begin);
currentByteBuffer.limit(end);
((Buffer) currentByteBuffer).position(begin);
((Buffer) currentByteBuffer).limit(end);
return currentByteBuffer.slice();
} catch (IllegalArgumentException e) {
throw InvalidProtocolBufferException.truncatedMessage();
} finally {
currentByteBuffer.position(prevPos);
currentByteBuffer.limit(prevLimit);
((Buffer) currentByteBuffer).position(prevPos);
((Buffer) currentByteBuffer).limit(prevLimit);
}
}
}

@ -764,7 +764,10 @@ public final class Descriptors {
/**
* Finds a field by name.
*
* @param name The unqualified name of the field (e.g. "foo").
* @param name The unqualified name of the field (e.g. "foo"). For protocol buffer messages that
* follow <a
* href=https://developers.google.com/protocol-buffers/docs/style#message_and_field_names>Google's
* guidance on naming</a> this will be a snake case string, such as <pre>song_name</pre>.
* @return The field's descriptor, or {@code null} if not found.
*/
public FieldDescriptor findFieldByName(final String name) {

@ -46,7 +46,6 @@ final class ExtensionRegistryFactory {
@Nullable */
static final Class<?> EXTENSION_REGISTRY_CLASS = reflectExtensionRegistry();
/* @Nullable */
static Class<?> reflectExtensionRegistry() {
try {
return Class.forName(FULL_REGISTRY_CLASS_NAME);
@ -77,7 +76,6 @@ final class ExtensionRegistryFactory {
&& EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass());
}
/* @Nullable */
private static final ExtensionRegistryLite invokeSubclassFactory(String methodName) {
if (EXTENSION_REGISTRY_CLASS == null) {
return null;

@ -84,10 +84,8 @@ public class ExtensionRegistryLite {
static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension";
private static class ExtensionClassHolder {
/* @Nullable */
static final Class<?> INSTANCE = resolveExtensionClass();
/* @Nullable */
static Class<?> resolveExtensionClass() {
try {
return Class.forName(EXTENSION_CLASS_NAME);

@ -204,7 +204,6 @@ public enum FieldType {
*
* @return the {@link FieldType} or {@code null} if not found.
*/
/* @Nullable */
public static FieldType forId(int id) {
if (id < 0 || id >= VALUES.length) {
return null;
@ -228,7 +227,6 @@ public enum FieldType {
*
* @return the generic super class/interface, or {@code null} if not found.
*/
/* @Nullable */
private static Type getGenericSuperList(Class<?> clazz) {
// First look at interfaces.
Type[] genericInterfaces = clazz.getGenericInterfaces();

@ -37,6 +37,7 @@ import java.io.InputStream;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.InvalidMarkException;
@ -109,7 +110,7 @@ final class NioByteString extends ByteString.LeafByteString {
protected void copyToInternal(
byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
ByteBuffer slice = buffer.slice();
slice.position(sourceOffset);
((Buffer) slice).position(sourceOffset);
slice.get(target, targetOffset, numberToCopy);
}
@ -285,8 +286,8 @@ final class NioByteString extends ByteString.LeafByteString {
}
ByteBuffer slice = buffer.slice();
slice.position(beginIndex - buffer.position());
slice.limit(endIndex - buffer.position());
((Buffer) slice).position(beginIndex - buffer.position());
((Buffer) slice).limit(endIndex - buffer.position());
return slice;
}
}

@ -30,6 +30,8 @@
package com.google.protobuf;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
@ -2375,6 +2377,73 @@ public final class TextFormat {
result[pos++] = (byte) code;
break;
case 'u':
// Unicode escape
++i;
if (i + 3 < input.size()
&& isHex(input.byteAt(i))
&& isHex(input.byteAt(i + 1))
&& isHex(input.byteAt(i + 2))
&& isHex(input.byteAt(i + 3))) {
char ch =
(char)
(digitValue(input.byteAt(i)) << 12
| digitValue(input.byteAt(i + 1)) << 8
| digitValue(input.byteAt(i + 2)) << 4
| digitValue(input.byteAt(i + 3)));
if (Character.isSurrogate(ch)) {
throw new InvalidEscapeSequenceException(
"Invalid escape sequence: '\\u' refers to a surrogate");
}
byte[] chUtf8 = Character.toString(ch).getBytes(UTF_8);
System.arraycopy(chUtf8, 0, result, pos, chUtf8.length);
pos += chUtf8.length;
i += 3;
} else {
throw new InvalidEscapeSequenceException(
"Invalid escape sequence: '\\u' with too few hex chars");
}
break;
case 'U':
// Unicode escape
++i;
if (i + 7 >= input.size()) {
throw new InvalidEscapeSequenceException(
"Invalid escape sequence: '\\U' with too few hex chars");
}
int codepoint = 0;
for (int offset = i; offset < i + 8; offset++) {
byte b = input.byteAt(offset);
if (!isHex(b)) {
throw new InvalidEscapeSequenceException(
"Invalid escape sequence: '\\U' with too few hex chars");
}
codepoint = (codepoint << 4) | digitValue(b);
}
if (!Character.isValidCodePoint(codepoint)) {
throw new InvalidEscapeSequenceException(
"Invalid escape sequence: '\\U"
+ input.substring(i, i + 8).toStringUtf8()
+ "' is not a valid code point value");
}
Character.UnicodeBlock unicodeBlock = Character.UnicodeBlock.of(codepoint);
if (unicodeBlock.equals(Character.UnicodeBlock.LOW_SURROGATES)
|| unicodeBlock.equals(Character.UnicodeBlock.HIGH_SURROGATES)
|| unicodeBlock.equals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES)) {
throw new InvalidEscapeSequenceException(
"Invalid escape sequence: '\\U"
+ input.substring(i, i + 8).toStringUtf8()
+ "' refers to a surrogate code unit");
}
int[] codepoints = new int[1];
codepoints[0] = codepoint;
byte[] chUtf8 = new String(codepoints, 0, 1).getBytes(UTF_8);
System.arraycopy(chUtf8, 0, result, pos, chUtf8.length);
pos += chUtf8.length;
i += 7;
break;
default:
throw new InvalidEscapeSequenceException(
"Invalid escape sequence: '\\" + (char) c + '\'');

@ -70,7 +70,6 @@ public class TypeRegistry {
/**
* Find a type by its typeUrl. Returns null if it cannot be found in this {@link TypeRegistry}.
*/
/* @Nullable */
public final Descriptor getDescriptorForTypeUrl(String typeUrl)
throws InvalidProtocolBufferException {
return find(getTypeName(typeUrl));

@ -41,7 +41,6 @@ import java.util.logging.Logger;
/** Utility class for working with unsafe operations. */
final class UnsafeUtil {
private static final Logger logger = Logger.getLogger(UnsafeUtil.class.getName());
private static final sun.misc.Unsafe UNSAFE = getUnsafe();
private static final Class<?> MEMORY_CLASS = Android.getMemoryClass();
private static final boolean IS_ANDROID_64 = determineAndroidSupportByAddressSize(long.class);
@ -363,7 +362,11 @@ final class UnsafeUtil {
return true;
} catch (Throwable e) {
logger.log(
// Because log statements are fairly sparse in this class, this logger is initialized
// non-statically. Static initialization adds undue runtime costs to the first client to
// initialize this class.
Logger.getLogger(UnsafeUtil.class.getName())
.log(
Level.WARNING,
"platform method missing - proto runtime falling back to safer methods: " + e);
}
@ -397,7 +400,11 @@ final class UnsafeUtil {
clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class);
return true;
} catch (Throwable e) {
logger.log(
// Because log statements are fairly sparse in this class, this logger is initialized
// non-statically. Static initialization adds undue runtime costs to the first client to
// initialize this class.
Logger.getLogger(UnsafeUtil.class.getName())
.log(
Level.WARNING,
"platform method missing - proto runtime falling back to safer methods: " + e);
}

@ -77,44 +77,44 @@ public final class MapForProto2LiteTest extends TestCase {
private void copyMapValues(TestMap source, TestMap.Builder destination) {
destination
.putAllInt32ToInt32Field(source.getInt32ToInt32Field())
.putAllInt32ToStringField(source.getInt32ToStringField())
.putAllInt32ToBytesField(source.getInt32ToBytesField())
.putAllInt32ToEnumField(source.getInt32ToEnumField())
.putAllInt32ToMessageField(source.getInt32ToMessageField())
.putAllStringToInt32Field(source.getStringToInt32Field());
.putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap())
.putAllInt32ToStringField(source.getInt32ToStringFieldMap())
.putAllInt32ToBytesField(source.getInt32ToBytesFieldMap())
.putAllInt32ToEnumField(source.getInt32ToEnumFieldMap())
.putAllInt32ToMessageField(source.getInt32ToMessageFieldMap())
.putAllStringToInt32Field(source.getStringToInt32FieldMap());
}
private void assertMapValuesSet(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
assertEquals(3, message.getInt32ToInt32FieldMap().size());
assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue());
assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue());
assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
assertEquals(3, message.getInt32ToStringField().size());
assertEquals("11", message.getInt32ToStringField().get(1));
assertEquals("22", message.getInt32ToStringField().get(2));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals(3, message.getInt32ToStringFieldMap().size());
assertEquals("11", message.getInt32ToStringFieldMap().get(1));
assertEquals("22", message.getInt32ToStringFieldMap().get(2));
assertEquals("33", message.getInt32ToStringFieldMap().get(3));
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(3, message.getInt32ToBytesFieldMap().size());
assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1));
assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(3, message.getInt32ToEnumFieldMap().size());
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(3, message.getInt32ToMessageFieldMap().size());
assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue());
assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue());
assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(11, message.getStringToInt32Field().get("1").intValue());
assertEquals(22, message.getStringToInt32Field().get("2").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
assertEquals(3, message.getStringToInt32FieldMap().size());
assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue());
assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue());
assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
}
private void updateMapValues(TestMap.Builder builder) {
@ -152,35 +152,35 @@ public final class MapForProto2LiteTest extends TestCase {
}
private void assertMapValuesUpdated(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
assertEquals(3, message.getInt32ToInt32FieldMap().size());
assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue());
assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue());
assertEquals(3, message.getInt32ToStringField().size());
assertEquals("111", message.getInt32ToStringField().get(1));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals("44", message.getInt32ToStringField().get(4));
assertEquals(3, message.getInt32ToStringFieldMap().size());
assertEquals("111", message.getInt32ToStringFieldMap().get(1));
assertEquals("33", message.getInt32ToStringFieldMap().get(3));
assertEquals("44", message.getInt32ToStringFieldMap().get(4));
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
assertEquals(3, message.getInt32ToBytesFieldMap().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4));
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
assertEquals(3, message.getInt32ToEnumFieldMap().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4));
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
assertEquals(3, message.getInt32ToMessageFieldMap().size());
assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue());
assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue());
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(111, message.getStringToInt32Field().get("1").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
assertEquals(44, message.getStringToInt32Field().get("4").intValue());
assertEquals(3, message.getStringToInt32FieldMap().size());
assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue());
assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue());
}
private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
@ -206,13 +206,13 @@ public final class MapForProto2LiteTest extends TestCase {
TestMap.Builder builder = TestMap.newBuilder();
TestMap message = builder.build();
builder.putInt32ToInt32Field(1, 2);
assertTrue(message.getInt32ToInt32Field().isEmpty());
assertTrue(message.getInt32ToInt32FieldMap().isEmpty());
message = builder.build();
assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap());
assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
builder.putInt32ToInt32Field(2, 3);
assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap());
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
}
public void testGetMapIsImmutable() {
@ -254,30 +254,31 @@ public final class MapForProto2LiteTest extends TestCase {
public void testMutableMapLifecycle() {
TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2);
assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap());
assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
builder.putInt32ToInt32Field(2, 3);
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR);
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField());
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField());
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap());
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap());
builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO);
assertEquals(
newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField());
newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
builder.getInt32ToEnumFieldMap());
builder.putInt32ToStringField(1, "1");
assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
assertEquals(newMap(1, "1"), builder.getInt32ToStringField());
assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap());
assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap());
builder.putInt32ToStringField(2, "2");
assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField());
assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap());
builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance());
assertEquals(
newMap(1, TestMap.MessageValue.getDefaultInstance()),
builder.build().getInt32ToMessageField());
builder.build().getInt32ToMessageFieldMap());
assertEquals(
newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField());
newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap());
builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance());
assertEquals(
newMap(
@ -285,7 +286,7 @@ public final class MapForProto2LiteTest extends TestCase {
TestMap.MessageValue.getDefaultInstance(),
2,
TestMap.MessageValue.getDefaultInstance()),
builder.getInt32ToMessageField());
builder.getInt32ToMessageFieldMap());
}
public void testGettersAndSetters() throws Exception {
@ -415,7 +416,7 @@ public final class MapForProto2LiteTest extends TestCase {
} catch (InvalidProtocolBufferException expected) {
assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
map = (TestMap) expected.getUnfinishedMessage();
assertTrue(map.getInt32ToMessageField().isEmpty());
assertTrue(map.getInt32ToMessageFieldMap().isEmpty());
}
map =
@ -476,14 +477,14 @@ public final class MapForProto2LiteTest extends TestCase {
TestMap message = TestMap.parseFrom(data);
// Entries with unknown enum values will be stored into UnknownFieldSet so
// there is only one entry in the map.
assertEquals(1, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(1, message.getInt32ToEnumFieldMap().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
// Serializing and parsing should preserve the unknown entry.
data = message.toByteString();
TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data);
assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size());
assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue());
assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue());
assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size());
assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue());
assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue());
}
public void testIterationOrder() throws Exception {
@ -493,7 +494,7 @@ public final class MapForProto2LiteTest extends TestCase {
assertEquals(
Arrays.asList("1", "2", "3"),
new ArrayList<String>(message.getStringToInt32Field().keySet()));
new ArrayList<String>(message.getStringToInt32FieldMap().keySet()));
}
private static <K, V> Map<K, V> newMap(K key1, V value1) {
@ -513,10 +514,10 @@ public final class MapForProto2LiteTest extends TestCase {
TestMap.Builder builder = TestMap.newBuilder();
setMapValues(builder);
TestMap message = builder.build();
assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap());
assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap());
assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap());
assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap());
assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap());
assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap());
assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap());
}
public void testContains() {

@ -119,12 +119,12 @@ public class MapForProto2Test extends TestCase {
private void copyMapValues(TestMap source, TestMap.Builder destination) {
destination
.putAllInt32ToInt32Field(source.getInt32ToInt32Field())
.putAllInt32ToStringField(source.getInt32ToStringField())
.putAllInt32ToBytesField(source.getInt32ToBytesField())
.putAllInt32ToEnumField(source.getInt32ToEnumField())
.putAllInt32ToMessageField(source.getInt32ToMessageField())
.putAllStringToInt32Field(source.getStringToInt32Field());
.putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap())
.putAllInt32ToStringField(source.getInt32ToStringFieldMap())
.putAllInt32ToBytesField(source.getInt32ToBytesFieldMap())
.putAllInt32ToEnumField(source.getInt32ToEnumFieldMap())
.putAllInt32ToMessageField(source.getInt32ToMessageFieldMap())
.putAllStringToInt32Field(source.getStringToInt32FieldMap());
}
private void assertMapValuesSet(TestMapOrBuilder message) {
@ -236,35 +236,35 @@ public class MapForProto2Test extends TestCase {
}
private void assertMapValuesUpdated(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
assertEquals(3, message.getInt32ToInt32FieldMap().size());
assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue());
assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue());
assertEquals(3, message.getInt32ToStringField().size());
assertEquals("111", message.getInt32ToStringField().get(1));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals("44", message.getInt32ToStringField().get(4));
assertEquals(3, message.getInt32ToStringFieldMap().size());
assertEquals("111", message.getInt32ToStringFieldMap().get(1));
assertEquals("33", message.getInt32ToStringFieldMap().get(3));
assertEquals("44", message.getInt32ToStringFieldMap().get(4));
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
assertEquals(3, message.getInt32ToBytesFieldMap().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4));
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
assertEquals(3, message.getInt32ToEnumFieldMap().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4));
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
assertEquals(3, message.getInt32ToMessageFieldMap().size());
assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue());
assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue());
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(111, message.getStringToInt32Field().get("1").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
assertEquals(44, message.getStringToInt32Field().get("4").intValue());
assertEquals(3, message.getStringToInt32FieldMap().size());
assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue());
assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue());
}
private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
@ -563,7 +563,7 @@ public class MapForProto2Test extends TestCase {
} catch (InvalidProtocolBufferException expected) {
assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
map = (TestMap) expected.getUnfinishedMessage();
assertTrue(map.getInt32ToMessageField().isEmpty());
assertTrue(map.getInt32ToMessageFieldMap().isEmpty());
}
map =
@ -698,8 +698,8 @@ public class MapForProto2Test extends TestCase {
builder.clearField(f("int32_to_int32_field"));
builder.clearField(f("int32_to_message_field"));
message = builder.build();
assertEquals(0, message.getInt32ToInt32Field().size());
assertEquals(0, message.getInt32ToMessageField().size());
assertEquals(0, message.getInt32ToInt32FieldMap().size());
assertEquals(0, message.getInt32ToMessageFieldMap().size());
// Test setField()
setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44));
@ -710,10 +710,10 @@ public class MapForProto2Test extends TestCase {
111, MessageValue.newBuilder().setValue(222).build(),
333, MessageValue.newBuilder().setValue(444).build()));
message = builder.build();
assertEquals(22, message.getInt32ToInt32Field().get(11).intValue());
assertEquals(44, message.getInt32ToInt32Field().get(33).intValue());
assertEquals(222, message.getInt32ToMessageField().get(111).getValue());
assertEquals(444, message.getInt32ToMessageField().get(333).getValue());
assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue());
assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue());
assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue());
assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue());
// Test addRepeatedField
builder.addRepeatedField(
@ -726,8 +726,8 @@ public class MapForProto2Test extends TestCase {
555,
MessageValue.newBuilder().setValue(666).build()));
message = builder.build();
assertEquals(66, message.getInt32ToInt32Field().get(55).intValue());
assertEquals(666, message.getInt32ToMessageField().get(555).getValue());
assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue());
assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue());
// Test addRepeatedField (overriding existing values)
builder.addRepeatedField(
@ -740,8 +740,8 @@ public class MapForProto2Test extends TestCase {
555,
MessageValue.newBuilder().setValue(555).build()));
message = builder.build();
assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
assertEquals(555, message.getInt32ToMessageField().get(555).getValue());
assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue());
assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue());
// Test setRepeatedField
for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) {
@ -755,9 +755,9 @@ public class MapForProto2Test extends TestCase {
builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build());
}
message = builder.build();
assertEquals(11, message.getInt32ToInt32Field().get(22).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(44).intValue());
assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue());
assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue());
assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue());
}
// See additional coverage in TextFormatTest.java.
@ -844,16 +844,16 @@ public class MapForProto2Test extends TestCase {
TestMap message = TestMap.parseFrom(data);
// Entries with unknown enum values will be stored into UnknownFieldSet so
// there is only one entry in the map.
assertEquals(1, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(1, message.getInt32ToEnumFieldMap().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
// UnknownFieldSet should not be empty.
assertFalse(message.getUnknownFields().asMap().isEmpty());
// Serializing and parsing should preserve the unknown entry.
data = message.toByteString();
TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data);
assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size());
assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue());
assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue());
assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size());
assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue());
assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue());
}
public void testRequiredMessage() throws Exception {
@ -885,7 +885,7 @@ public class MapForProto2Test extends TestCase {
assertEquals(
Arrays.asList("1", "2", "3"),
new ArrayList<String>(message.getStringToInt32Field().keySet()));
new ArrayList<String>(message.getStringToInt32FieldMap().keySet()));
}
public void testContains() {
@ -1172,9 +1172,9 @@ public class MapForProto2Test extends TestCase {
setMapValuesUsingAccessors(builder);
assertMapValuesSet(builder);
TestMap message = builder.build();
assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap());
assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap());
assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap());
assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap());
assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap());
assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap());
assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap());
}
}

@ -84,44 +84,44 @@ public final class MapLiteTest extends TestCase {
private void copyMapValues(TestMap source, TestMap.Builder destination) {
destination
.putAllInt32ToInt32Field(source.getInt32ToInt32Field())
.putAllInt32ToStringField(source.getInt32ToStringField())
.putAllInt32ToBytesField(source.getInt32ToBytesField())
.putAllInt32ToEnumField(source.getInt32ToEnumField())
.putAllInt32ToMessageField(source.getInt32ToMessageField())
.putAllStringToInt32Field(source.getStringToInt32Field());
.putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap())
.putAllInt32ToStringField(source.getInt32ToStringFieldMap())
.putAllInt32ToBytesField(source.getInt32ToBytesFieldMap())
.putAllInt32ToEnumField(source.getInt32ToEnumFieldMap())
.putAllInt32ToMessageField(source.getInt32ToMessageFieldMap())
.putAllStringToInt32Field(source.getStringToInt32FieldMap());
}
private void assertMapValuesSet(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
assertEquals(3, message.getInt32ToInt32FieldMap().size());
assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue());
assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue());
assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
assertEquals(3, message.getInt32ToStringField().size());
assertEquals("11", message.getInt32ToStringField().get(1));
assertEquals("22", message.getInt32ToStringField().get(2));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals(3, message.getInt32ToStringFieldMap().size());
assertEquals("11", message.getInt32ToStringFieldMap().get(1));
assertEquals("22", message.getInt32ToStringFieldMap().get(2));
assertEquals("33", message.getInt32ToStringFieldMap().get(3));
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(3, message.getInt32ToBytesFieldMap().size());
assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1));
assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(3, message.getInt32ToEnumFieldMap().size());
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(3, message.getInt32ToMessageFieldMap().size());
assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue());
assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue());
assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(11, message.getStringToInt32Field().get("1").intValue());
assertEquals(22, message.getStringToInt32Field().get("2").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
assertEquals(3, message.getStringToInt32FieldMap().size());
assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue());
assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue());
assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
}
private void updateMapValues(TestMap.Builder builder) {
@ -159,35 +159,35 @@ public final class MapLiteTest extends TestCase {
}
private void assertMapValuesUpdated(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
assertEquals(3, message.getInt32ToInt32FieldMap().size());
assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue());
assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue());
assertEquals(3, message.getInt32ToStringField().size());
assertEquals("111", message.getInt32ToStringField().get(1));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals("44", message.getInt32ToStringField().get(4));
assertEquals(3, message.getInt32ToStringFieldMap().size());
assertEquals("111", message.getInt32ToStringFieldMap().get(1));
assertEquals("33", message.getInt32ToStringFieldMap().get(3));
assertEquals("44", message.getInt32ToStringFieldMap().get(4));
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
assertEquals(3, message.getInt32ToBytesFieldMap().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4));
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
assertEquals(3, message.getInt32ToEnumFieldMap().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4));
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
assertEquals(3, message.getInt32ToMessageFieldMap().size());
assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue());
assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue());
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(111, message.getStringToInt32Field().get("1").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
assertEquals(44, message.getStringToInt32Field().get("4").intValue());
assertEquals(3, message.getStringToInt32FieldMap().size());
assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue());
assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue());
}
private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
@ -213,12 +213,12 @@ public final class MapLiteTest extends TestCase {
TestMap.Builder builder = TestMap.newBuilder();
TestMap message = builder.build();
builder.putInt32ToInt32Field(1, 2);
assertTrue(message.getInt32ToInt32Field().isEmpty());
assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
assertTrue(message.getInt32ToInt32FieldMap().isEmpty());
assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
message = builder.build();
builder.putInt32ToInt32Field(2, 3);
assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap());
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
}
public void testGetMapIsImmutable() {
@ -266,30 +266,31 @@ public final class MapLiteTest extends TestCase {
public void testMutableMapLifecycle() {
TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2);
assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap());
assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap());
builder.putInt32ToInt32Field(2, 3);
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap());
builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR);
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField());
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField());
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap());
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap());
builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO);
assertEquals(
newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField());
newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
builder.getInt32ToEnumFieldMap());
builder.putInt32ToStringField(1, "1");
assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
assertEquals(newMap(1, "1"), builder.getInt32ToStringField());
assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap());
assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap());
builder.putInt32ToStringField(2, "2");
assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField());
assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap());
builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance());
assertEquals(
newMap(1, TestMap.MessageValue.getDefaultInstance()),
builder.build().getInt32ToMessageField());
builder.build().getInt32ToMessageFieldMap());
assertEquals(
newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField());
newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap());
builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance());
assertEquals(
newMap(
@ -297,7 +298,7 @@ public final class MapLiteTest extends TestCase {
TestMap.MessageValue.getDefaultInstance(),
2,
TestMap.MessageValue.getDefaultInstance()),
builder.getInt32ToMessageField());
builder.getInt32ToMessageFieldMap());
}
public void testGettersAndSetters() throws Exception {
@ -342,12 +343,12 @@ public final class MapLiteTest extends TestCase {
TestMap source = sourceBuilder.build();
TestMap.Builder destinationBuilder = TestMap.newBuilder();
destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue());
destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap());
TestMap destination = destinationBuilder.build();
assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue());
assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue());
assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue());
assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue());
assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue());
assertEquals(3, destination.getInt32ToEnumFieldCount());
}
@ -459,7 +460,7 @@ public final class MapLiteTest extends TestCase {
} catch (InvalidProtocolBufferException expected) {
assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
map = (TestMap) expected.getUnfinishedMessage();
assertTrue(map.getInt32ToMessageField().isEmpty());
assertTrue(map.getInt32ToMessageFieldMap().isEmpty());
}
map =
@ -524,24 +525,24 @@ public final class MapLiteTest extends TestCase {
.putInt32ToEnumFieldValue(2, 1000); // unknown value.
TestMap message = builder.build();
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2));
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2));
builder.putAllInt32ToEnumFieldValue(newMap(2, 1000)); // unknown value.
message = builder.build();
assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2));
assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2));
// Unknown enum values should be preserved after:
// 1. Serialization and parsing.
// 2. toBuild().
// 3. mergeFrom().
message = TestMap.parseFrom(message.toByteString());
assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue());
builder = message.toBuilder();
assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue());
builder = TestMap.newBuilder().mergeFrom(message);
assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue());
// hashCode()/equals() should take unknown enum values into account.
builder.putAllInt32ToEnumFieldValue(newMap(2, 1001));
@ -550,7 +551,7 @@ public final class MapLiteTest extends TestCase {
assertFalse(message.equals(message2));
// Unknown values will be converted to UNRECOGNIZED so the resulted enum map
// should be the same.
assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField());
assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
}
public void testIterationOrder() throws Exception {
@ -559,18 +560,18 @@ public final class MapLiteTest extends TestCase {
TestMap message = builder.build();
assertEquals(
Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet()));
Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet()));
}
public void testGetMap() {
TestMap.Builder builder = TestMap.newBuilder();
setMapValues(builder);
TestMap message = builder.build();
assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap());
assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap());
assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap());
assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap());
assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap());
assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap());
assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap());
assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap());
assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap());
}
public void testContains() {

@ -122,44 +122,44 @@ public class MapTest extends TestCase {
private void copyMapValues(TestMap source, TestMap.Builder destination) {
destination
.putAllInt32ToInt32Field(source.getInt32ToInt32Field())
.putAllInt32ToStringField(source.getInt32ToStringField())
.putAllInt32ToBytesField(source.getInt32ToBytesField())
.putAllInt32ToEnumField(source.getInt32ToEnumField())
.putAllInt32ToMessageField(source.getInt32ToMessageField())
.putAllStringToInt32Field(source.getStringToInt32Field());
.putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap())
.putAllInt32ToStringField(source.getInt32ToStringFieldMap())
.putAllInt32ToBytesField(source.getInt32ToBytesFieldMap())
.putAllInt32ToEnumField(source.getInt32ToEnumFieldMap())
.putAllInt32ToMessageField(source.getInt32ToMessageFieldMap())
.putAllStringToInt32Field(source.getStringToInt32FieldMap());
}
private void assertMapValuesSet(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
assertEquals(3, message.getInt32ToInt32FieldMap().size());
assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue());
assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue());
assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
assertEquals(3, message.getInt32ToStringField().size());
assertEquals("11", message.getInt32ToStringField().get(1));
assertEquals("22", message.getInt32ToStringField().get(2));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals(3, message.getInt32ToStringFieldMap().size());
assertEquals("11", message.getInt32ToStringFieldMap().get(1));
assertEquals("22", message.getInt32ToStringFieldMap().get(2));
assertEquals("33", message.getInt32ToStringFieldMap().get(3));
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(3, message.getInt32ToBytesFieldMap().size());
assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1));
assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(3, message.getInt32ToEnumFieldMap().size());
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(3, message.getInt32ToMessageFieldMap().size());
assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue());
assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue());
assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(11, message.getStringToInt32Field().get("1").intValue());
assertEquals(22, message.getStringToInt32Field().get("2").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
assertEquals(3, message.getStringToInt32FieldMap().size());
assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue());
assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue());
assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
}
private void updateMapValuesUsingMutableMap(TestMap.Builder builder) {
@ -239,35 +239,35 @@ public class MapTest extends TestCase {
}
private void assertMapValuesUpdated(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
assertEquals(3, message.getInt32ToInt32FieldMap().size());
assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue());
assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue());
assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue());
assertEquals(3, message.getInt32ToStringField().size());
assertEquals("111", message.getInt32ToStringField().get(1));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals("44", message.getInt32ToStringField().get(4));
assertEquals(3, message.getInt32ToStringFieldMap().size());
assertEquals("111", message.getInt32ToStringFieldMap().get(1));
assertEquals("33", message.getInt32ToStringFieldMap().get(3));
assertEquals("44", message.getInt32ToStringFieldMap().get(4));
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
assertEquals(3, message.getInt32ToBytesFieldMap().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4));
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
assertEquals(3, message.getInt32ToEnumFieldMap().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4));
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
assertEquals(3, message.getInt32ToMessageFieldMap().size());
assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue());
assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue());
assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue());
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(111, message.getStringToInt32Field().get("1").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
assertEquals(44, message.getStringToInt32Field().get("4").intValue());
assertEquals(3, message.getStringToInt32FieldMap().size());
assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue());
assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue());
assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue());
}
private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
@ -468,11 +468,13 @@ public class MapTest extends TestCase {
.build();
TestMap destination =
TestMap.newBuilder().putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue()).build();
TestMap.newBuilder()
.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap())
.build();
assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue());
assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue());
assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue());
assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue());
assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue());
assertEquals(3, destination.getInt32ToEnumFieldCount());
}
@ -583,7 +585,7 @@ public class MapTest extends TestCase {
} catch (InvalidProtocolBufferException expected) {
assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
map = (TestMap) expected.getUnfinishedMessage();
assertTrue(map.getInt32ToMessageField().isEmpty());
assertTrue(map.getInt32ToMessageFieldMap().isEmpty());
}
map =
@ -644,14 +646,14 @@ public class MapTest extends TestCase {
TestOnChangeEventPropagation.Builder parent = TestOnChangeEventPropagation.newBuilder();
parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 2);
TestOnChangeEventPropagation message = parent.build();
assertEquals(2, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
assertEquals(2, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue());
// Make a change using nested builder.
parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 3);
// Should be able to observe the change.
message = parent.build();
assertEquals(3, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
assertEquals(3, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue());
// Make another change using mergeFrom()
TestMap other = TestMap.newBuilder().putInt32ToInt32Field(1, 4).build();
@ -659,14 +661,14 @@ public class MapTest extends TestCase {
// Should be able to observe the change.
message = parent.build();
assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue());
// Make yet another change by clearing the nested builder.
parent.getOptionalMessageBuilder().clear();
// Should be able to observe the change.
message = parent.build();
assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size());
assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size());
}
public void testNestedBuilderOnChangeEventPropagationReflection() {
@ -683,7 +685,7 @@ public class MapTest extends TestCase {
// Should be able to observe the change.
TestOnChangeEventPropagation message = parentBuilder.build();
assertEquals(1, message.getOptionalMessage().getInt32ToInt32Field().size());
assertEquals(1, message.getOptionalMessage().getInt32ToInt32FieldMap().size());
// Change the entry value.
entryBuilder.putInt32ToInt32Field(1, 4);
@ -692,7 +694,7 @@ public class MapTest extends TestCase {
// Should be able to observe the change.
message = parentBuilder.build();
assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue());
assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue());
// Clear the nested builder.
testMapBuilder = parentBuilder.getOptionalMessageBuilder();
@ -700,7 +702,7 @@ public class MapTest extends TestCase {
// Should be able to observe the change.
message = parentBuilder.build();
assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size());
assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size());
}
// The following methods are used to test reflection API.
@ -789,8 +791,8 @@ public class MapTest extends TestCase {
builder.clearField(f("int32_to_int32_field"));
builder.clearField(f("int32_to_message_field"));
message = builder.build();
assertEquals(0, message.getInt32ToInt32Field().size());
assertEquals(0, message.getInt32ToMessageField().size());
assertEquals(0, message.getInt32ToInt32FieldMap().size());
assertEquals(0, message.getInt32ToMessageFieldMap().size());
// Test setField()
setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44));
@ -801,10 +803,10 @@ public class MapTest extends TestCase {
111, MessageValue.newBuilder().setValue(222).build(),
333, MessageValue.newBuilder().setValue(444).build()));
message = builder.build();
assertEquals(22, message.getInt32ToInt32Field().get(11).intValue());
assertEquals(44, message.getInt32ToInt32Field().get(33).intValue());
assertEquals(222, message.getInt32ToMessageField().get(111).getValue());
assertEquals(444, message.getInt32ToMessageField().get(333).getValue());
assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue());
assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue());
assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue());
assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue());
// Test addRepeatedField
builder.addRepeatedField(
@ -817,8 +819,8 @@ public class MapTest extends TestCase {
555,
MessageValue.newBuilder().setValue(666).build()));
message = builder.build();
assertEquals(66, message.getInt32ToInt32Field().get(55).intValue());
assertEquals(666, message.getInt32ToMessageField().get(555).getValue());
assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue());
assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue());
// Test addRepeatedField (overriding existing values)
builder.addRepeatedField(
@ -831,8 +833,8 @@ public class MapTest extends TestCase {
555,
MessageValue.newBuilder().setValue(555).build()));
message = builder.build();
assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
assertEquals(555, message.getInt32ToMessageField().get(555).getValue());
assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue());
assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue());
// Test setRepeatedField
for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) {
@ -846,9 +848,9 @@ public class MapTest extends TestCase {
builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build());
}
message = builder.build();
assertEquals(11, message.getInt32ToInt32Field().get(22).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(44).intValue());
assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue());
assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue());
assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue());
}
// See additional coverage in TextFormatTest.java.
@ -937,21 +939,21 @@ public class MapTest extends TestCase {
2, 1000)); // unknown value.
TestMap message = builder.build();
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2));
assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1));
assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2));
assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue());
// Unknown enum values should be preserved after:
// 1. Serialization and parsing.
// 2. toBuild().
// 3. mergeFrom().
message = TestMap.parseFrom(message.toByteString());
assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue());
builder = message.toBuilder();
assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue());
builder = TestMap.newBuilder().mergeFrom(message);
assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue());
// hashCode()/equals() should take unknown enum values into account.
builder.putAllInt32ToEnumFieldValue(newMap(2, 1001));
@ -960,7 +962,7 @@ public class MapTest extends TestCase {
assertFalse(message.equals(message2));
// Unknown values will be converted to UNRECOGNIZED so the resulted enum map
// should be the same.
assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField());
assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
}
public void testUnknownEnumValuesInReflectionApi() throws Exception {
@ -991,7 +993,7 @@ public class MapTest extends TestCase {
// Verify that enum values have been successfully updated.
TestMap message = builder.build();
for (Map.Entry<Integer, Integer> entry : message.getInt32ToEnumFieldValue().entrySet()) {
for (Map.Entry<Integer, Integer> entry : message.getInt32ToEnumFieldValueMap().entrySet()) {
assertEquals(data.get(entry.getKey()) + 1, entry.getValue().intValue());
}
}
@ -1002,18 +1004,18 @@ public class MapTest extends TestCase {
TestMap message = builder.build();
assertEquals(
Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet()));
Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet()));
}
public void testGetMap() {
TestMap.Builder builder = TestMap.newBuilder();
setMapValuesUsingAccessors(builder);
TestMap message = builder.build();
assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap());
assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap());
assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap());
assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap());
assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap());
assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap());
assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap());
assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap());
assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap());
assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap());
}
public void testContains() {

@ -30,6 +30,7 @@
package com.google.protobuf;
import static com.google.common.truth.Truth.assertThat;
import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED;
import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED;
@ -866,6 +867,12 @@ public class TextFormatTest extends TestCase {
assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\341\\210\\264"));
assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4"));
assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\xe1\\x88\\xb4"));
assertEquals("\u1234", TextFormat.unescapeText("\\u1234"));
assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\u1234"));
assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\U00001234"));
assertEquals(
new String(new int[] {0x10437}, 0, 1), TextFormat.unescapeText("\\xf0\\x90\\x90\\xb7"));
assertEquals(bytes(0xf0, 0x90, 0x90, 0xb7), TextFormat.unescapeBytes("\\U00010437"));
// Handling of strings with unescaped Unicode characters > 255.
final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
@ -893,6 +900,87 @@ public class TextFormatTest extends TestCase {
} catch (TextFormat.InvalidEscapeSequenceException e) {
// success
}
try {
TextFormat.unescapeText("\\u");
fail("Should have thrown an exception.");
} catch (TextFormat.InvalidEscapeSequenceException e) {
assertThat(e)
.hasMessageThat()
.isEqualTo("Invalid escape sequence: '\\u' with too few hex chars");
}
try {
TextFormat.unescapeText("\\ud800");
fail("Should have thrown an exception.");
} catch (TextFormat.InvalidEscapeSequenceException e) {
assertThat(e)
.hasMessageThat()
.isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate");
}
try {
TextFormat.unescapeText("\\ud800\\u1234");
fail("Should have thrown an exception.");
} catch (TextFormat.InvalidEscapeSequenceException e) {
assertThat(e)
.hasMessageThat()
.isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate");
}
try {
TextFormat.unescapeText("\\udc00");
fail("Should have thrown an exception.");
} catch (TextFormat.InvalidEscapeSequenceException e) {
assertThat(e)
.hasMessageThat()
.isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate");
}
try {
TextFormat.unescapeText("\\ud801\\udc37");
fail("Should have thrown an exception.");
} catch (TextFormat.InvalidEscapeSequenceException e) {
assertThat(e)
.hasMessageThat()
.isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate");
}
try {
TextFormat.unescapeText("\\U1234");
fail("Should have thrown an exception.");
} catch (TextFormat.InvalidEscapeSequenceException e) {
assertThat(e)
.hasMessageThat()
.isEqualTo("Invalid escape sequence: '\\U' with too few hex chars");
}
try {
TextFormat.unescapeText("\\U1234no more hex");
fail("Should have thrown an exception.");
} catch (TextFormat.InvalidEscapeSequenceException e) {
assertThat(e)
.hasMessageThat()
.isEqualTo("Invalid escape sequence: '\\U' with too few hex chars");
}
try {
TextFormat.unescapeText("\\U00110000");
fail("Should have thrown an exception.");
} catch (TextFormat.InvalidEscapeSequenceException e) {
assertThat(e)
.hasMessageThat()
.isEqualTo("Invalid escape sequence: '\\U00110000' is not a valid code point value");
}
try {
TextFormat.unescapeText("\\U0000d801\\U00000dc37");
fail("Should have thrown an exception.");
} catch (TextFormat.InvalidEscapeSequenceException e) {
assertThat(e)
.hasMessageThat()
.isEqualTo("Invalid escape sequence: '\\U0000d801' refers to a surrogate code unit");
}
}
public void testParseInteger() throws Exception {

@ -137,11 +137,19 @@ final class FieldMaskTree {
}
/**
* Remove {@code path} from the tree.
* Removes {@code path} from the tree.
*
* <p>When removing a field path from the tree, all sub-paths will be removed. That is, after
* removing "foo.bar" from the tree, "foo.bar.baz" will be removed. Likewise, if the field path to
* remove is a non-exist sub-path, nothing will be changed.
* <ul>
* When removing a field path from the tree:
* <li>All sub-paths will be removed. That is, after removing "foo.bar" from the tree,
* "foo.bar.baz" will be removed.
* <li>If all children of a node has been removed, the node itself will be removed as well.
* That is, if "foo" only has one child "bar" and "foo.bar" only has one child "baz",
* removing "foo.bar.barz" would remove both "foo" and "foo.bar".
* If "foo" has both "bar" and "qux" as children, removing "foo.bar" would leave the path
* "foo.qux" intact.
* <li>If the field path to remove is a non-exist sub-path, nothing will be changed.
* </ul>
*/
@CanIgnoreReturnValue
FieldMaskTree removeFieldPath(String path) {
@ -149,21 +157,33 @@ final class FieldMaskTree {
if (parts.isEmpty()) {
return this;
}
Node node = root;
for (int i = 0; i < parts.size(); i++) {
String key = parts.get(i);
if (!node.children.containsKey(key)) {
// Path does not exist.
removeFieldPath(root, parts, 0);
return this;
}
if (i == parts.size() - 1) {
// Remove path.
/**
* Removes {@code parts} from {@code node} recursively.
*
* @return a boolean value indicating whether current {@code node} should be removed.
*/
@CanIgnoreReturnValue
private static boolean removeFieldPath(Node node, List<String> parts, int index) {
String key = parts.get(index);
// Base case 1: path not match.
if (!node.children.containsKey(key)) {
return false;
}
// Base case 2: last element in parts.
if (index == parts.size() - 1) {
node.children.remove(key);
return this;
return node.children.isEmpty();
}
node = node.children.get(key);
// Recursive remove sub-path.
if (removeFieldPath(node.children.get(key), parts, index + 1)) {
node.children.remove(key);
}
return this;
return node.children.isEmpty();
}
/** Removes all field paths in {@code mask} from this tree. */
@ -187,10 +207,8 @@ final class FieldMaskTree {
return FieldMask.newBuilder().addAllPaths(paths).build();
}
/**
* Gathers all field paths in a sub-tree.
*/
private void getFieldPaths(Node node, String path, List<String> paths) {
/** Gathers all field paths in a sub-tree. */
private static void getFieldPaths(Node node, String path, List<String> paths) {
if (node.children.isEmpty()) {
paths.add(path);
return;
@ -247,10 +265,8 @@ final class FieldMaskTree {
merge(root, "", source, destination, options);
}
/**
* Merges all fields specified by a sub-tree from {@code source} to {@code destination}.
*/
private void merge(
/** Merges all fields specified by a sub-tree from {@code source} to {@code destination}. */
private static void merge(
Node node,
String path,
Message source,

@ -276,7 +276,13 @@ public final class FieldMaskUtil {
return maskTree.toFieldMask();
}
/** Subtracts {@code secondMask} and {@code otherMasks} from {@code firstMask}. */
/**
* Subtracts {@code secondMask} and {@code otherMasks} from {@code firstMask}.
*
* <p>This method disregards proto structure. That is, if {@code firstMask} is "foo" and {@code
* secondMask} is "foo.bar", the response will always be "foo" without considering the internal
* proto structure of message "foo".
*/
public static FieldMask subtract(
FieldMask firstMask, FieldMask secondMask, FieldMask... otherMasks) {
FieldMaskTree maskTree = new FieldMaskTree(firstMask).removeFromFieldMask(secondMask);

@ -525,7 +525,6 @@ public class JsonFormat {
return types.get(name);
}
/* @Nullable */
Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException {
return find(getTypeName(typeUrl));
}

@ -77,25 +77,37 @@ public class FieldMaskTreeTest extends TestCase {
public void testRemoveFieldPath() throws Exception {
String initialTreeString = "bar.baz,bar.quz.bar,foo";
FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
FieldMaskTree tree;
// Empty path.
tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
tree.removeFieldPath("");
assertEquals(initialTreeString, tree.toString());
// Non-exist sub-path of an existing leaf.
tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
tree.removeFieldPath("foo.bar");
assertEquals(initialTreeString, tree.toString());
// Non-exist path.
tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
tree.removeFieldPath("bar.foo");
assertEquals(initialTreeString, tree.toString());
// Match an existing leaf node.
// Match an existing leaf node -> remove leaf node.
tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
tree.removeFieldPath("foo");
assertEquals("bar.baz,bar.quz.bar", tree.toString());
// Match sub-path of an existing leaf node.
// Match sub-path of an existing leaf node -> recursive removal.
tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
tree.removeFieldPath("bar.quz.bar");
assertEquals("bar.baz,bar.quz", tree.toString());
// Match a non-leaf node.
assertEquals("bar.baz,foo", tree.toString());
// Match a non-leaf node -> remove all children.
tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString));
tree.removeFieldPath("bar");
assertThat(tree.toString()).isEmpty();
assertEquals("foo", tree.toString());
}
public void testRemoveFromFieldMask() throws Exception {

@ -239,7 +239,7 @@ public class FieldMaskUtilTest extends TestCase {
FieldMask mask3 = FieldMaskUtil.fromString("bar.quz");
FieldMask mask4 = FieldMaskUtil.fromString("foo,bar.baz");
FieldMask result = FieldMaskUtil.subtract(mask1, mask2, mask3, mask4);
assertEquals("bar", FieldMaskUtil.toString(result));
assertThat(FieldMaskUtil.toString(result)).isEmpty();
}
public void testIntersection() throws Exception {

@ -722,8 +722,8 @@ public class JsonFormatTest extends TestCase {
mergeFromJson(
"{\n" + " int32ToInt32Map: {1: 2},\n" + " stringToInt32Map: {hello: 3}\n" + "}", builder);
TestMap message = builder.build();
assertEquals(2, message.getInt32ToInt32Map().get(1).intValue());
assertEquals(3, message.getStringToInt32Map().get("hello").intValue());
assertEquals(2, message.getInt32ToInt32MapMap().get(1).intValue());
assertEquals(3, message.getStringToInt32MapMap().get("hello").intValue());
}
public void testWrappers() throws Exception {

@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \
parallel \
time \
wget \
&& apt-get clean
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install Python libraries.
RUN python -m pip install --no-cache-dir --upgrade \
pip \
setuptools \
tox \
wheel

@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \
parallel \
time \
wget \
&& apt-get clean
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install Python libraries.
RUN python -m pip install --no-cache-dir --upgrade \
pip \
setuptools \
tox \
wheel

@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \
parallel \
time \
wget \
&& apt-get clean
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install Python libraries.
RUN python -m pip install --no-cache-dir --upgrade \
pip \
setuptools \
tox \
wheel

@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \
parallel \
time \
wget \
&& apt-get clean
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install Python libraries.
RUN python -m pip install --no-cache-dir --upgrade \
pip \
setuptools \
tox \
wheel

@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \
parallel \
time \
wget \
&& apt-get clean
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install Python libraries.
RUN python -m pip install --no-cache-dir --upgrade \
pip \
setuptools \
tox \
wheel

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python27/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python27/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python27_cpp/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python27_cpp/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python35/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python35/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python35_cpp/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python35_cpp/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python36/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python36/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python36_cpp/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python36_cpp/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python37/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python37/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python37_cpp/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python37_cpp/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python38/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python/build.sh"
build_file: "protobuf/kokoro/linux/python38/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python38_cpp/build.sh"
timeout_mins: 120
action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
build_file: "protobuf/kokoro/linux/python38_cpp/build.sh"
timeout_mins: 120
action {

@ -1,11 +0,0 @@
#!/bin/bash
#
# Build file to set up and run tests
# Change to repo root
cd $(dirname $0)/../../..
# Prepare worker environment to run tests
source kokoro/macos/prepare_build_macos_rc
./tests.sh php5.6_mac

@ -1,5 +0,0 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/macos/php5.6_mac/build.sh"
timeout_mins: 1440

@ -1,5 +0,0 @@
# Config file for running tests in Kokoro
# Location of the build script in repository
build_file: "protobuf/kokoro/macos/php5.6_mac/build.sh"
timeout_mins: 1440

@ -356,14 +356,14 @@ static PROTO_RETURN_VAL Message_write_property(
}
upb_msg_set(intern->msg, f, msgval, arena);
#if PHP_VERSION_ID < 704000
#if PHP_VERSION_ID < 70400
return;
#else
return val;
#endif
error:
#if PHP_VERSION_ID < 704000
#if PHP_VERSION_ID < 70400
return;
#else
return &EG(error_zval);

@ -10,11 +10,11 @@
<email>protobuf-opensource@google.com</email>
<active>yes</active>
</lead>
<date>2020-08-14</date>
<date>2020-10-08</date>
<time>14:07:59</time>
<version>
<release>3.13.0</release>
<api>3.13.0</api>
<release>3.13.0.1</release>
<api>3.13.0.1</api>
</version>
<stability>
<release>stable</release>
@ -675,5 +675,19 @@ G A release.
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>GA release.</notes>
</release>
<release>
<version>
<release>3.13.0.1</release>
<api>3.13.0.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2020-10-08</date>
<time>14:07:59</time>
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>GA release.</notes>
</release>
</changelog>
</package>

@ -69,7 +69,7 @@ const zval *get_generated_pool();
#define PROTO_STRLEN_P(obj) ZSTR_LEN(obj)
#endif
#define PHP_PROTOBUF_VERSION "3.13.0"
#define PHP_PROTOBUF_VERSION "3.13.0.1"
// ptr -> PHP object cache. This is a weak map that caches lazily-created
// wrapper objects around upb types:

@ -10,8 +10,8 @@ set -ex
VERSION=$1
git clone git@github.com:protocolbuffers/protobuf-php.git
git clone git@github.com:protocolbuffers/protobuf.git
git clone https://github.com/protocolbuffers/protobuf-php.git
git clone https://github.com/protocolbuffers/protobuf.git
# Clean old files
pushd protobuf-php

@ -809,7 +809,7 @@ bool CheckAndSetString(
return false;
}
string value_string(value, value_len);
std::string value_string(value, value_len);
if (append) {
reflection->AddString(message, descriptor, std::move(value_string));
} else if (index < 0) {

@ -883,7 +883,8 @@ class _Parser(object):
(expanded_any_end_token,))
self._MergeField(tokenizer, expanded_any_sub_message)
message.Pack(expanded_any_sub_message,
type_url_prefix=type_url_prefix)
type_url_prefix=type_url_prefix,
deterministic=True)
return
if tokenizer.TryConsume('['):

@ -103,4 +103,19 @@ $ python -m pip install .
By default, the protoc binary (the Protobuf compiler) is found by
searching the environment path. To use a specific protoc binary, its
path can be specified.
path can be specified. Resolution of the `protoc` value is as follows:
1. If the `--protoc=VALUE` flag is passed to `generate_py_protobufs`,
then `VALUE` will be used.
For example:
```shell
$ python setup.py generate_py_protobufs --protoc=/path/to/protoc
```
2. Otherwise, if a value was set in the `options`, it will be used.
(See "Example setup.py configuration," above.)
3. Otherwise, if the `PROTOC` environment variable is set, it will be
used. For example:
For example:
```shell
$ PROTOC=/path/to/protoc python setup.py generate_py_protobufs
```
4. Otherwise, `$PATH` will be searched.

@ -14,7 +14,10 @@ setenv =
commands =
python setup.py -q build_py
python: python setup.py -q build
cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension
# --warnings_as_errors disabled until we update the Python C extension. See:
# https://github.com/protocolbuffers/protobuf/issues/7930
# cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension
cpp: python setup.py -q build --cpp_implementation --compile_static_extension
python: python setup.py -q test -q
cpp: python setup.py -q test -q --cpp_implementation
python: python setup.py -q test_conformance

@ -60,7 +60,8 @@ class PROTOBUF_EXPORT AnyMetadata {
typedef ArenaStringPtr ValueType;
public:
// AnyMetadata does not take ownership of "type_url" and "value".
AnyMetadata(UrlType* type_url, ValueType* value);
constexpr AnyMetadata(UrlType* type_url, ValueType* value)
: type_url_(type_url), value_(value) {}
// Packs a message using the default type URL prefix: "type.googleapis.com".
// The resulted type URL will be "type.googleapis.com/<message_full_name>".

@ -53,9 +53,6 @@ const char kAnyFullTypeName[] = "google.protobuf.Any";
const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/";
const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/";
AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value)
: type_url_(type_url), value_(value) {}
void AnyMetadata::InternalPackFrom(const MessageLite& message,
StringPiece type_url_prefix,
StringPiece type_name) {

@ -33,10 +33,18 @@
#include <gtest/gtest.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace {
TEST(AnyMetadataTest, ConstInit) {
PROTOBUF_CONSTINIT static internal::AnyMetadata metadata(nullptr, nullptr);
(void)metadata;
}
TEST(AnyTest, TestPackAndUnpack) {
protobuf_unittest::TestAny submessage;
submessage.set_int32_value(12345);

@ -47,6 +47,10 @@ static const size_t kMaxCleanupListElements = 64; // 1kB on 64-bit.
namespace google {
namespace protobuf {
PROTOBUF_EXPORT /*static*/ void* (*const ArenaOptions::kDefaultBlockAlloc)(
size_t) = &::operator new;
namespace internal {
const size_t ArenaImpl::kBlockHeaderSize;
@ -54,7 +58,7 @@ const size_t ArenaImpl::kSerialArenaSize;
const size_t ArenaImpl::kOptionsSize;
std::atomic<LifecycleId> ArenaImpl::lifecycle_id_generator_;
ArenaImpl::CacheAlignedLifecycleIdGenerator ArenaImpl::lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ =
@ -63,12 +67,13 @@ ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
}
#elif defined(PROTOBUF_USE_DLLS)
ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = {-1, NULL};
static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = {
0, static_cast<LifecycleIdAtomic>(-1), nullptr};
return thread_cache_;
}
#else
PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1,
NULL};
PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {
0, static_cast<LifecycleIdAtomic>(-1), nullptr};
#endif
void ArenaFree(void* object, size_t size) {
@ -122,9 +127,26 @@ ArenaImpl::ArenaImpl(const ArenaOptions& options) {
}
void ArenaImpl::Init(bool record_allocs) {
ThreadCache& tc = thread_cache();
auto id = tc.next_lifecycle_id;
constexpr uint64 kInc = ThreadCache::kPerThreadIds * 2;
if (PROTOBUF_PREDICT_FALSE((id & (kInc - 1)) == 0)) {
if (sizeof(lifecycle_id_generator_.id) == 4) {
// 2^32 is dangerous low to guarantee uniqueness. If we start dolling out
// unique id's in ranges of kInc it's unacceptably low. In this case
// we increment by 1. The additional range of kPerThreadIds that are used
// per thread effectively pushes the overflow time from weeks to years
// of continuous running.
id = lifecycle_id_generator_.id.fetch_add(1, std::memory_order_relaxed) *
kInc;
} else {
id =
lifecycle_id_generator_.id.fetch_add(kInc, std::memory_order_relaxed);
}
}
tc.next_lifecycle_id = id + 2;
// We store "record_allocs" in the low bit of lifecycle_id_.
auto id = lifecycle_id_generator_.fetch_add(1, std::memory_order_relaxed);
lifecycle_id_ = (id << 1) | (record_allocs ? 1 : 0);
lifecycle_id_ = id | (record_allocs ? 1 : 0);
hint_.store(nullptr, std::memory_order_relaxed);
threads_.store(nullptr, std::memory_order_relaxed);
space_allocated_.store(0, std::memory_order_relaxed);

@ -142,10 +142,12 @@ struct ArenaOptions {
max_block_size(kDefaultMaxBlockSize),
initial_block(NULL),
initial_block_size(0),
block_alloc(&::operator new),
block_alloc(kDefaultBlockAlloc),
block_dealloc(&internal::ArenaFree),
make_metrics_collector(nullptr) {}
PROTOBUF_EXPORT static void* (*const kDefaultBlockAlloc)(size_t);
private:
// If make_metrics_collector is not nullptr, it will be called at Arena init
// time. It may return a pointer to a collector instance that will be notified

@ -58,7 +58,7 @@ inline size_t AlignUpTo8(size_t n) {
return (n + 7) & static_cast<size_t>(-8);
}
using LifecycleId = int64_t;
using LifecycleIdAtomic = uint64_t;
void PROTOBUF_EXPORT ArenaFree(void* object, size_t size);
@ -328,20 +328,43 @@ class PROTOBUF_EXPORT ArenaImpl {
ArenaMetricsCollector* metrics_collector;
};
struct ThreadCache {
#ifdef _MSC_VER
#pragma warning(disable:4324)
#endif
struct alignas(64) ThreadCache {
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// If we are using the ThreadLocalStorage class to store the ThreadCache,
// then the ThreadCache's default constructor has to be responsible for
// initializing it.
ThreadCache() : last_lifecycle_id_seen(-1), last_serial_arena(NULL) {}
ThreadCache()
: next_lifecycle_id(0),
last_lifecycle_id_seen(-1),
last_serial_arena(NULL) {}
#endif
// Number of per-thread lifecycle IDs to reserve. Must be power of two.
// To reduce contention on a global atomic, each thread reserves a batch of
// IDs. The following number is caluculated based on a stress test with
// ~6500 threads all frequently allocating a new arena.
static constexpr size_t kPerThreadIds = 256;
// Next lifecycle ID available to this thread. We need to reserve a new
// batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`.
uint64 next_lifecycle_id;
// The ThreadCache is considered valid as long as this matches the
// lifecycle_id of the arena being used.
LifecycleId last_lifecycle_id_seen;
uint64 last_lifecycle_id_seen;
SerialArena* last_serial_arena;
};
static std::atomic<LifecycleId> lifecycle_id_generator_;
// Lifecycle_id can be highly contended variable in a situation of lots of
// arena creation. Make sure that other global variables are not sharing the
// cacheline.
#ifdef _MSC_VER
#pragma warning(disable:4324)
#endif
struct alignas(64) CacheAlignedLifecycleIdGenerator {
std::atomic<LifecycleIdAtomic> id;
};
static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// Android ndk does not support __thread keyword so we use a custom thread
// local storage class we implemented.
@ -430,7 +453,7 @@ class PROTOBUF_EXPORT ArenaImpl {
// Unique for each arena. Changes on Reset().
// Least-significant-bit is 1 iff allocations should be recorded.
LifecycleId lifecycle_id_;
uint64 lifecycle_id_;
Options* options_ = nullptr;

@ -87,22 +87,27 @@ class PROTOBUF_EXPORT LazyString {
template <typename T>
class TaggedPtr {
public:
TaggedPtr() = default;
explicit constexpr TaggedPtr(const std::string* ptr)
: ptr_(const_cast<std::string*>(ptr)) {}
void SetTagged(T* p) {
Set(p);
ptr_ |= 1;
ptr_ = reinterpret_cast<void*>(as_int() | 1);
}
void Set(T* p) { ptr_ = reinterpret_cast<uintptr_t>(p); }
T* Get() const { return reinterpret_cast<T*>(ptr_ & -2); }
bool IsTagged() const { return ptr_ & 1; }
void Set(T* p) { ptr_ = p; }
T* Get() const { return reinterpret_cast<T*>(as_int() & -2); }
bool IsTagged() const { return as_int() & 1; }
// Returned value is only safe to dereference if IsTagged() == false.
// It is safe to compare.
T* UnsafeGet() const { return reinterpret_cast<T*>(ptr_); }
T* UnsafeGet() const { return static_cast<T*>(ptr_); }
bool IsNull() { return ptr_ == 0; }
bool IsNull() { return ptr_ == nullptr; }
private:
uintptr_t ptr_;
uintptr_t as_int() const { return reinterpret_cast<uintptr_t>(ptr_); }
void* ptr_;
};
static_assert(std::is_trivial<TaggedPtr<std::string>>::value,
@ -165,9 +170,9 @@ static_assert(std::is_trivial<TaggedPtr<std::string>>::value,
// single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also
// requires the String tag to be 0 so we can avoid the mask before comparing.)
struct PROTOBUF_EXPORT ArenaStringPtr {
// No default constructor or destructor -- we have to be POD because we go
// into a union when used in a oneof. Message code calls UnsafeReset() to zero
// the pointer when necessary instead.
ArenaStringPtr() = default;
explicit constexpr ArenaStringPtr(const std::string* default_value)
: tagged_ptr_(default_value) {}
// Some methods below are overloaded on a `default_value` and on tags.
// The tagged overloads help reduce code size in the callers in generated

@ -45,6 +45,9 @@
#include <google/protobuf/stubs/strutil.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {

@ -47,6 +47,7 @@
#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/any.pb.h>
#include <google/protobuf/compiler/mock_code_generator.h>
#include <google/protobuf/compiler/subprocess.h>
#include <google/protobuf/compiler/code_generator.h>
@ -681,6 +682,9 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs_UnusedImport_DescriptorSetIn) {
FileDescriptorProto::descriptor()->file();
descriptor_file->CopyTo(file_descriptor_set.add_file());
FileDescriptorProto& any_proto = *file_descriptor_set.add_file();
google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
const FileDescriptor* custom_file =
protobuf_unittest::AggregateMessage::descriptor()->file();
FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();

@ -164,10 +164,6 @@ class FieldGenerator {
return false;
}
// Generate code that allocates the fields's default instance.
virtual void GenerateDefaultInstanceAllocator(
io::Printer* /*printer*/) const {}
// Generate lines to serialize this field directly to the array "target",
// which are placed within the message's SerializeWithCachedSizesToArray()
// method. This must also advance "target" past the written bytes.

@ -941,7 +941,6 @@ void FileGenerator::GenerateInitForSCC(const SCC* scc,
if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
continue;
}
message_generators_[i]->GenerateFieldDefaultInstances(printer);
format(
"{\n"
" void* ptr = &$1$;\n"

@ -1895,13 +1895,6 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
return num_field_metadata;
}
void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) {
// Construct the default instances for all fields that need one.
for (auto field : FieldRange(descriptor_)) {
field_generators_.get(field).GenerateDefaultInstanceAllocator(printer);
}
}
void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
Formatter format(printer, variables_);
if (IsMapEntryMessage(descriptor_)) {

@ -82,9 +82,6 @@ class MessageGenerator {
// Source file stuff.
// Generates code that creates default instances for fields.
void GenerateFieldDefaultInstances(io::Printer* printer);
// Generate all non-inline methods for this class.
void GenerateClassMethods(io::Printer* printer);

@ -390,6 +390,7 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Print("}\n");
}
void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
io::Printer* printer) {
printer->Print(

@ -78,6 +78,7 @@ class FileGenerator {
void Generate(io::Printer* printer);
// If we aren't putting everything into one file, this will write all the
// files other than the outer file (i.e. one for each message, enum, and
// service type).

@ -160,7 +160,14 @@ std::string ClassNameResolver::GetFileImmutableClassName(
std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file,
bool immutable) {
if (immutable) {
return GetFileClassName(file, immutable, false);
}
std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file,
bool immutable, bool kotlin) {
if (kotlin) {
return GetFileImmutableClassName(file) + "Kt";
} else if (immutable) {
return GetFileImmutableClassName(file);
} else {
return "Mutable" + GetFileImmutableClassName(file);
@ -200,9 +207,14 @@ std::string ClassNameResolver::GetDescriptorClassName(
std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor,
bool immutable) {
return GetClassName(descriptor, immutable, false);
}
std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor,
bool immutable, bool kotlin) {
std::string result = FileJavaPackage(descriptor, immutable);
if (!result.empty()) result += '.';
result += GetFileClassName(descriptor, immutable);
result += GetFileClassName(descriptor, immutable, kotlin);
return result;
}
@ -211,50 +223,79 @@ std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor,
std::string ClassNameResolver::GetClassFullName(
const std::string& name_without_package, const FileDescriptor* file,
bool immutable, bool is_own_file) {
return GetClassFullName(name_without_package, file, immutable, is_own_file,
false);
}
std::string ClassNameResolver::GetClassFullName(
const std::string& name_without_package, const FileDescriptor* file,
bool immutable, bool is_own_file, bool kotlin) {
std::string result;
if (is_own_file) {
result = FileJavaPackage(file, immutable);
} else {
result = GetClassName(file, immutable);
result = GetClassName(file, immutable, kotlin);
}
if (!result.empty()) {
result += '.';
}
result += name_without_package;
if (kotlin) result += "Kt";
return result;
}
std::string ClassNameResolver::GetClassName(const Descriptor* descriptor,
bool immutable) {
return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
descriptor->file(), immutable,
MultipleJavaFiles(descriptor->file(), immutable));
return GetClassName(descriptor, immutable, false);
}
std::string ClassNameResolver::GetClassName(const Descriptor* descriptor,
bool immutable, bool kotlin) {
return GetClassFullName(
ClassNameWithoutPackage(descriptor, immutable), descriptor->file(),
immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin);
}
std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor,
bool immutable) {
return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
descriptor->file(), immutable,
MultipleJavaFiles(descriptor->file(), immutable));
return GetClassName(descriptor, immutable, false);
}
std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor,
bool immutable, bool kotlin) {
return GetClassFullName(
ClassNameWithoutPackage(descriptor, immutable), descriptor->file(),
immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin);
}
std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor,
bool immutable) {
return GetClassName(descriptor, immutable, false);
}
std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor,
bool immutable, bool kotlin) {
return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
descriptor->file(), immutable,
IsOwnFile(descriptor, immutable));
IsOwnFile(descriptor, immutable), kotlin);
}
// Get the Java Class style full name of a message.
std::string ClassNameResolver::GetJavaClassFullName(
const std::string& name_without_package, const FileDescriptor* file,
bool immutable) {
return GetJavaClassFullName(name_without_package, file, immutable, false);
}
std::string ClassNameResolver::GetJavaClassFullName(
const std::string& name_without_package, const FileDescriptor* file,
bool immutable, bool kotlin) {
std::string result;
if (MultipleJavaFiles(file, immutable)) {
result = FileJavaPackage(file, immutable);
if (!result.empty()) result += '.';
} else {
result = GetClassName(file, immutable);
result = GetClassName(file, immutable, kotlin);
if (!result.empty()) result += '$';
}
result += StringReplace(name_without_package, ".", "$", true);
@ -263,7 +304,12 @@ std::string ClassNameResolver::GetJavaClassFullName(
std::string ClassNameResolver::GetExtensionIdentifierName(
const FieldDescriptor* descriptor, bool immutable) {
return GetClassName(descriptor->containing_type(), immutable) + "." +
return GetExtensionIdentifierName(descriptor, immutable, false);
}
std::string ClassNameResolver::GetExtensionIdentifierName(
const FieldDescriptor* descriptor, bool immutable, bool kotlin) {
return GetClassName(descriptor->containing_type(), immutable, kotlin) + "." +
descriptor->name();
}

@ -60,6 +60,8 @@ class ClassNameResolver {
// Gets the unqualified outer class name for the file.
std::string GetFileClassName(const FileDescriptor* file, bool immutable);
std::string GetFileClassName(const FileDescriptor* file, bool immutable,
bool kotlin);
// Gets the unqualified immutable outer class name of a file.
std::string GetFileImmutableClassName(const FileDescriptor* file);
// Gets the unqualified default immutable outer class name of a file
@ -80,9 +82,17 @@ class ClassNameResolver {
// Gets the fully-qualified class name corresponding to the given descriptor.
std::string GetClassName(const Descriptor* descriptor, bool immutable);
std::string GetClassName(const Descriptor* descriptor, bool immutable,
bool kotlin);
std::string GetClassName(const EnumDescriptor* descriptor, bool immutable);
std::string GetClassName(const EnumDescriptor* descriptor, bool immutable,
bool kotlin);
std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable);
std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable,
bool kotlin);
std::string GetClassName(const FileDescriptor* descriptor, bool immutable);
std::string GetClassName(const FileDescriptor* descriptor, bool immutable,
bool kotlin);
template <class DescriptorType>
std::string GetImmutableClassName(const DescriptorType* descriptor) {
@ -96,6 +106,8 @@ class ClassNameResolver {
// Gets the fully qualified name of an extension identifier.
std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor,
bool immutable);
std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor,
bool immutable, bool kotlin);
// Gets the fully qualified name for generated classes in Java convention.
// Nested classes will be separated using '$' instead of '.'
@ -109,9 +121,15 @@ class ClassNameResolver {
std::string GetClassFullName(const std::string& name_without_package,
const FileDescriptor* file, bool immutable,
bool is_own_file);
std::string GetClassFullName(const std::string& name_without_package,
const FileDescriptor* file, bool immutable,
bool is_own_file, bool kotlin);
// Get the Java Class style full name of a message.
std::string GetJavaClassFullName(const std::string& name_without_package,
const FileDescriptor* file, bool immutable);
std::string GetJavaClassFullName(const std::string& name_without_package,
const FileDescriptor* file, bool immutable,
bool kotlin);
// Caches the result to provide better performance.
std::map<const FileDescriptor*, std::string>
file_immutable_outer_class_names_;

@ -65,6 +65,7 @@ int ProtobufMain(int argc, char* argv[]) {
"Generate Java source file.");
// Proto2 Python
python::Generator py_generator;
cli.RegisterGenerator("--python_out", "--python_opt", &py_generator,

@ -41,6 +41,7 @@
#include <google/protobuf/test_util2.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/any.pb.h>
#include <google/protobuf/unittest_custom_options.pb.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
@ -2276,6 +2277,11 @@ TEST_F(ParseDescriptorDebugTest, TestCustomOptions) {
FileDescriptorProto import_proto;
import->CopyTo(&import_proto);
ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
FileDescriptorProto any_import;
google::protobuf::Any::descriptor()->file()->CopyTo(&any_import);
ASSERT_TRUE(pool_.BuildFile(any_import) != nullptr);
const FileDescriptor* actual = pool_.BuildFile(parsed);
ASSERT_TRUE(actual != NULL);
parsed.Clear();

@ -49,6 +49,7 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/any.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/tokenizer.h>
@ -254,14 +255,14 @@ std::string ToCamelCase(const std::string& input, bool lower_first) {
std::string result;
result.reserve(input.size());
for (int i = 0; i < input.size(); i++) {
if (input[i] == '_') {
for (char character : input) {
if (character == '_') {
capitalize_next = true;
} else if (capitalize_next) {
result.push_back(ToUpper(input[i]));
result.push_back(ToUpper(character));
capitalize_next = false;
} else {
result.push_back(input[i]);
result.push_back(character);
}
}
@ -278,14 +279,14 @@ std::string ToJsonName(const std::string& input) {
std::string result;
result.reserve(input.size());
for (int i = 0; i < input.size(); i++) {
if (input[i] == '_') {
for (char character : input) {
if (character == '_') {
capitalize_next = true;
} else if (capitalize_next) {
result.push_back(ToUpper(input[i]));
result.push_back(ToUpper(character));
capitalize_next = false;
} else {
result.push_back(input[i]);
result.push_back(character);
}
}
@ -297,14 +298,14 @@ std::string EnumValueToPascalCase(const std::string& input) {
std::string result;
result.reserve(input.size());
for (int i = 0; i < input.size(); i++) {
if (input[i] == '_') {
for (char character : input) {
if (character == '_') {
next_upper = true;
} else {
if (next_upper) {
result.push_back(ToUpper(input[i]));
result.push_back(ToUpper(character));
} else {
result.push_back(ToLower(input[i]));
result.push_back(ToLower(character));
}
next_upper = false;
}
@ -318,9 +319,9 @@ class PrefixRemover {
public:
PrefixRemover(StringPiece prefix) {
// Strip underscores and lower-case the prefix.
for (int i = 0; i < prefix.size(); i++) {
if (prefix[i] != '_') {
prefix_ += ascii_tolower(prefix[i]);
for (char character : prefix) {
if (character != '_') {
prefix_ += ascii_tolower(character);
}
}
}
@ -471,16 +472,15 @@ std::set<std::string>* NewAllowedProto3Extendee() {
const char* kOptionNames[] = {
"FileOptions", "MessageOptions", "FieldOptions", "EnumOptions",
"EnumValueOptions", "ServiceOptions", "MethodOptions", "OneofOptions"};
for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) {
for (const char* option_name : kOptionNames) {
// descriptor.proto has a different package name in opensource. We allow
// both so the opensource protocol compiler can also compile internal
// proto3 files with custom options. See: b/27567912
allowed_proto3_extendees->insert(std::string("google.protobuf.") +
kOptionNames[i]);
option_name);
// Split the word to trick the opensource processing scripts so they
// will keep the original package name.
allowed_proto3_extendees->insert(std::string("proto") + "2." +
kOptionNames[i]);
allowed_proto3_extendees->insert(std::string("proto") + "2." + option_name);
}
return allowed_proto3_extendees;
}
@ -1571,8 +1571,7 @@ void DescriptorPool::FindAllExtensions(
std::vector<int> numbers;
if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(),
&numbers)) {
for (int i = 0; i < numbers.size(); ++i) {
int number = numbers[i];
for (int number : numbers) {
if (tables_->FindExtension(extendee, number) == nullptr) {
TryFindExtensionInFallbackDatabase(extendee, number);
}
@ -2279,34 +2278,34 @@ bool RetrieveOptionsAssumingRightPool(
const Reflection* reflection = options.GetReflection();
std::vector<const FieldDescriptor*> fields;
reflection->ListFields(options, &fields);
for (int i = 0; i < fields.size(); i++) {
for (const FieldDescriptor* field : fields) {
int count = 1;
bool repeated = false;
if (fields[i]->is_repeated()) {
count = reflection->FieldSize(options, fields[i]);
if (field->is_repeated()) {
count = reflection->FieldSize(options, field);
repeated = true;
}
for (int j = 0; j < count; j++) {
std::string fieldval;
if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
std::string tmp;
TextFormat::Printer printer;
printer.SetInitialIndentLevel(depth + 1);
printer.PrintFieldValueToString(options, fields[i], repeated ? j : -1,
printer.PrintFieldValueToString(options, field, repeated ? j : -1,
&tmp);
fieldval.append("{\n");
fieldval.append(tmp);
fieldval.append(depth * 2, ' ');
fieldval.append("}");
} else {
TextFormat::PrintFieldValueToString(options, fields[i],
repeated ? j : -1, &fieldval);
TextFormat::PrintFieldValueToString(options, field, repeated ? j : -1,
&fieldval);
}
std::string name;
if (fields[i]->is_extension()) {
name = "(." + fields[i]->full_name() + ")";
if (field->is_extension()) {
name = "(." + field->full_name() + ")";
} else {
name = fields[i]->name();
name = field->name();
}
option_entries->push_back(name + " = " + fieldval);
}
@ -2363,9 +2362,8 @@ bool FormatLineOptions(int depth, const Message& options,
std::string prefix(depth * 2, ' ');
std::vector<std::string> all_options;
if (RetrieveOptions(depth, options, pool, &all_options)) {
for (int i = 0; i < all_options.size(); i++) {
strings::SubstituteAndAppend(output, "$0option $1;\n", prefix,
all_options[i]);
for (const std::string& option : all_options) {
strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, option);
}
}
return !all_options.empty();
@ -2395,8 +2393,9 @@ class SourceLocationCommentPrinter {
void AddPreComment(std::string* output) {
if (have_source_loc_) {
// Detached leading comments.
for (int i = 0; i < source_loc_.leading_detached_comments.size(); ++i) {
*output += FormatComment(source_loc_.leading_detached_comments[i]);
for (const std::string& leading_detached_comment :
source_loc_.leading_detached_comments) {
*output += FormatComment(leading_detached_comment);
*output += "\n";
}
// Attached leading comments.
@ -2418,8 +2417,7 @@ class SourceLocationCommentPrinter {
StripWhitespace(&stripped_comment);
std::vector<std::string> lines = Split(stripped_comment, "\n");
std::string output;
for (int i = 0; i < lines.size(); ++i) {
const std::string& line = lines[i];
for (const std::string& line : lines) {
strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line);
}
return output;
@ -3866,13 +3864,13 @@ Symbol DescriptorBuilder::LookupSymbol(
static bool ValidateQualifiedName(StringPiece name) {
bool last_was_period = false;
for (int i = 0; i < name.size(); i++) {
for (char character : name) {
// I don't trust isalnum() due to locales. :(
if (('a' <= name[i] && name[i] <= 'z') ||
('A' <= name[i] && name[i] <= 'Z') ||
('0' <= name[i] && name[i] <= '9') || (name[i] == '_')) {
if (('a' <= character && character <= 'z') ||
('A' <= character && character <= 'Z') ||
('0' <= character && character <= '9') || (character == '_')) {
last_was_period = false;
} else if (name[i] == '.') {
} else if (character == '.') {
if (last_was_period) return false;
last_was_period = true;
} else {
@ -4096,11 +4094,11 @@ void DescriptorBuilder::ValidateSymbolName(const std::string& name,
AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
"Missing name.");
} else {
for (int i = 0; i < name.size(); i++) {
for (char character : name) {
// I don't trust isalnum() due to locales. :(
if ((name[i] < 'a' || 'z' < name[i]) &&
(name[i] < 'A' || 'Z' < name[i]) &&
(name[i] < '0' || '9' < name[i]) && (name[i] != '_')) {
if ((character < 'a' || 'z' < character) &&
(character < 'A' || 'Z' < character) &&
(character < '0' || '9' < character) && (character != '_')) {
AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
"\"" + name + "\" is not a valid identifier.");
}
@ -5945,12 +5943,12 @@ void DescriptorBuilder::ValidateProto3(FileDescriptor* file,
static std::string ToLowercaseWithoutUnderscores(const std::string& name) {
std::string result;
for (int i = 0; i < name.size(); ++i) {
if (name[i] != '_') {
if (name[i] >= 'A' && name[i] <= 'Z') {
result.push_back(name[i] - 'A' + 'a');
for (char character : name) {
if (character != '_') {
if (character >= 'A' && character <= 'Z') {
result.push_back(character - 'A' + 'a');
} else {
result.push_back(name[i]);
result.push_back(character);
}
}
}
@ -7067,6 +7065,18 @@ class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
public:
DescriptorBuilder* builder_;
const Descriptor* FindAnyType(const Message& message,
const std::string& prefix,
const std::string& name) const override {
if (prefix != internal::kTypeGoogleApisComPrefix &&
prefix != internal::kTypeGoogleProdComPrefix) {
return nullptr;
}
assert_mutex_held(builder_->pool_);
Symbol result = builder_->FindSymbol(name);
return result.type == Symbol::MESSAGE ? result.descriptor : nullptr;
}
const FieldDescriptor* FindExtension(Message* message,
const std::string& name) const override {
assert_mutex_held(builder_->pool_);

@ -552,11 +552,9 @@ class EncodedDescriptorDatabase::DescriptorIndex {
bool EncodedDescriptorDatabase::Add(const void* encoded_file_descriptor,
int size) {
google::protobuf::Arena arena;
auto* file = google::protobuf::Arena::CreateMessage<FileDescriptorProto>(&arena);
if (file->ParseFromArray(encoded_file_descriptor, size)) {
return index_->AddFile(*file,
std::make_pair(encoded_file_descriptor, size));
FileDescriptorProto file;
if (file.ParseFromArray(encoded_file_descriptor, size)) {
return index_->AddFile(file, std::make_pair(encoded_file_descriptor, size));
} else {
GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to "
"EncodedDescriptorDatabase::Add().";
@ -933,8 +931,8 @@ bool DescriptorPoolDatabase::FindAllExtensionNumbers(
std::vector<const FieldDescriptor*> extensions;
pool_.FindAllExtensions(extendee, &extensions);
for (int i = 0; i < extensions.size(); ++i) {
output->push_back(extensions[i]->number());
for (const FieldDescriptor* extension : extensions) {
output->push_back(extension->number());
}
return true;
@ -954,8 +952,8 @@ MergedDescriptorDatabase::~MergedDescriptorDatabase() {}
bool MergedDescriptorDatabase::FindFileByName(const std::string& filename,
FileDescriptorProto* output) {
for (int i = 0; i < sources_.size(); i++) {
if (sources_[i]->FindFileByName(filename, output)) {
for (DescriptorDatabase* source : sources_) {
if (source->FindFileByName(filename, output)) {
return true;
}
}
@ -1012,8 +1010,8 @@ bool MergedDescriptorDatabase::FindAllExtensionNumbers(
std::vector<int> results;
bool success = false;
for (int i = 0; i < sources_.size(); i++) {
if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) {
for (DescriptorDatabase* source : sources_) {
if (source->FindAllExtensionNumbers(extendee_type, &results)) {
std::copy(results.begin(), results.end(),
std::insert_iterator<std::set<int> >(merged_results,
merged_results.begin()));

@ -38,6 +38,7 @@
#include <memory>
#include <vector>
#include <google/protobuf/any.pb.h>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/compiler/parser.h>
#include <google/protobuf/unittest.pb.h>
@ -287,9 +288,8 @@ class MockErrorCollector : public DescriptorPool::ErrorCollector {
break;
}
strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n",
filename, element_name, location_name,
message);
strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", filename,
element_name, location_name, message);
}
};
@ -3148,6 +3148,11 @@ TEST(CustomOptions, OptionsFromOtherFile) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
// We have to import the Any dependency.
FileDescriptorProto any_proto;
google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@ -3206,6 +3211,10 @@ TEST(CustomOptions, MessageOptionThreeFieldsSet) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
FileDescriptorProto any_proto;
google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@ -3283,6 +3292,10 @@ TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
FileDescriptorProto any_proto;
google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@ -3363,6 +3376,10 @@ TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
FileDescriptorProto any_proto;
google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@ -3463,6 +3480,10 @@ TEST(CustomOptions, AggregateOptions) {
message_set_extension)
.s());
protobuf_unittest::AggregateMessageSetElement any_payload;
ASSERT_TRUE(file_options.any().UnpackTo(&any_payload));
EXPECT_EQ("EmbeddedMessageSetElement", any_payload.s());
// Simple tests for all the other types of annotations
EXPECT_EQ("MessageAnnotation",
msg->options().GetExtension(protobuf_unittest::msgopt).s());
@ -3485,6 +3506,10 @@ TEST(CustomOptions, UnusedImportError) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
FileDescriptorProto any_proto;
google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto);
ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr);
protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);

@ -192,14 +192,6 @@ ExtensionSet::ExtensionSet(Arena* arena)
? NULL
: Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
ExtensionSet::ExtensionSet()
: arena_(NULL),
flat_capacity_(0),
flat_size_(0),
map_{flat_capacity_ == 0
? NULL
: Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
ExtensionSet::~ExtensionSet() {
// Deletes all allocated extensions.
if (arena_ == NULL) {

@ -173,7 +173,7 @@ class MessageSetFieldSkipper;
// off to the ExtensionSet for parsing. Etc.
class PROTOBUF_EXPORT ExtensionSet {
public:
ExtensionSet();
constexpr ExtensionSet();
explicit ExtensionSet(Arena* arena);
~ExtensionSet();
@ -850,6 +850,9 @@ class PROTOBUF_EXPORT ExtensionSet {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
};
constexpr ExtensionSet::ExtensionSet()
: arena_(nullptr), flat_capacity_(0), flat_size_(0), map_{nullptr} {}
// These are just for convenience...
inline void ExtensionSet::SetString(int number, FieldType type,
std::string value,

@ -46,13 +46,15 @@
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/stubs/stl_util.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
@ -1324,6 +1326,11 @@ TEST(ExtensionSetTest, BoolExtension) {
EXPECT_TRUE(msg.GetExtension(protobuf_unittest::optional_bool_extension));
}
TEST(ExtensionSetTest, ConstInit) {
PROTOBUF_CONSTINIT static ExtensionSet set{};
EXPECT_EQ(set.NumExtensions(), 0);
}
} // namespace
} // namespace internal
} // namespace protobuf

@ -1065,6 +1065,7 @@ void Reflection::ListFieldsMayFailOnStripped(
output->push_back(field);
}
} else if (has_bits && has_bits_indices[i] != -1) {
CheckInvalidAccess(schema_, field);
// Equivalent to: HasBit(message, field)
if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
output->push_back(field);

@ -68,16 +68,25 @@ void DestroyString(const void* s) {
static_cast<const std::string*>(s)->~basic_string();
}
ExplicitlyConstructed<std::string> fixed_address_empty_string;
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EmptyString
fixed_address_empty_string; // NOLINT
PROTOBUF_CONSTINIT std::atomic<bool> init_protobuf_defaults_state{false};
static bool InitProtobufDefaultsImpl() {
fixed_address_empty_string.DefaultConstruct();
OnShutdownDestroyString(fixed_address_empty_string.get_mutable());
::new (static_cast<void*>(&fixed_address_empty_string.value)) std::string();
OnShutdownDestroyString(&fixed_address_empty_string.value);
// Verify that we can indeed get the address during constant evaluation.
PROTOBUF_CONSTINIT static const std::string& fixed_address_empty_string_test =
GetEmptyStringAlreadyInited();
(void)fixed_address_empty_string_test;
init_protobuf_defaults_state.store(true, std::memory_order_release);
return true;
}
void InitProtobufDefaults() {
void InitProtobufDefaultsSlow() {
static bool is_inited = InitProtobufDefaultsImpl();
(void)is_inited;
}

@ -85,7 +85,17 @@ inline To DownCast(From& f) {
}
PROTOBUF_EXPORT void InitProtobufDefaults();
// This fastpath inlines a single branch instead of having to make the
// InitProtobufDefaults function call.
// It also generates less inlined code than a function-scope static initializer.
PROTOBUF_EXPORT extern std::atomic<bool> init_protobuf_defaults_state;
PROTOBUF_EXPORT void InitProtobufDefaultsSlow();
PROTOBUF_EXPORT inline void InitProtobufDefaults() {
if (PROTOBUF_PREDICT_FALSE(
!init_protobuf_defaults_state.load(std::memory_order_acquire))) {
InitProtobufDefaultsSlow();
}
}
// This used by proto1
PROTOBUF_EXPORT inline const std::string& GetEmptyString() {

@ -47,7 +47,7 @@ namespace internal {
template <size_t doublewords>
class HasBits {
public:
HasBits() PROTOBUF_ALWAYS_INLINE { Clear(); }
constexpr HasBits() PROTOBUF_ALWAYS_INLINE : has_bits_{} {}
void Clear() PROTOBUF_ALWAYS_INLINE {
memset(has_bits_, 0, sizeof(has_bits_));

@ -129,7 +129,7 @@ class ImplicitWeakTypeHandler {
template <typename T>
struct WeakRepeatedPtrField {
using TypeHandler = internal::ImplicitWeakTypeHandler<T>;
WeakRepeatedPtrField() : weak() {}
constexpr WeakRepeatedPtrField() : weak() {}
explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {}
~WeakRepeatedPtrField() { weak.template Destroy<TypeHandler>(); }

@ -105,8 +105,8 @@ class MapAllocator {
using size_type = size_t;
using difference_type = ptrdiff_t;
MapAllocator() : arena_(nullptr) {}
explicit MapAllocator(Arena* arena) : arena_(arena) {}
constexpr MapAllocator() : arena_(nullptr) {}
explicit constexpr MapAllocator(Arena* arena) : arena_(arena) {}
template <typename X>
MapAllocator(const MapAllocator<X>& allocator) // NOLINT(runtime/explicit)
: arena_(allocator.arena()) {}
@ -382,7 +382,7 @@ class Map {
using size_type = size_t;
using hasher = typename internal::TransparentSupport<Key>::hash;
Map() : elements_(nullptr) {}
constexpr Map() : elements_(nullptr) {}
explicit Map(Arena* arena) : elements_(arena) {}
Map(const Map& other) : Map() { insert(other.begin(), other.end()); }
@ -450,11 +450,11 @@ class Map {
// otherwise. This avoids unnecessary copies of string keys, for example.
class InnerMap : private hasher {
public:
explicit InnerMap(Arena* arena)
explicit constexpr InnerMap(Arena* arena)
: hasher(),
num_elements_(0),
num_buckets_(internal::kGlobalEmptyTableSize),
seed_(Seed()),
seed_(0),
index_of_first_non_null_(num_buckets_),
table_(const_cast<void**>(internal::kGlobalEmptyTable)),
alloc_(arena) {}
@ -919,6 +919,7 @@ class Map {
// Just overwrite with a new one. No need to transfer or free anything.
num_buckets_ = index_of_first_non_null_ = kMinTableSize;
table_ = CreateEmptyTable(num_buckets_);
seed_ = Seed();
return;
}

@ -93,7 +93,7 @@ template <typename Derived, typename Key, typename Value,
class MapEntry : public MapEntryImpl<Derived, Message, Key, Value,
kKeyFieldType, kValueFieldType> {
public:
MapEntry() : _internal_metadata_(NULL) {}
constexpr MapEntry() : _internal_metadata_() {}
explicit MapEntry(Arena* arena)
: MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
kValueFieldType>(arena),

@ -182,17 +182,16 @@ class MapEntryImpl : public Base {
static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType;
static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType;
MapEntryImpl() {
KeyTypeHandler::Initialize(&key_, NULL);
ValueTypeHandler::Initialize(&value_, NULL);
_has_bits_[0] = 0;
}
constexpr MapEntryImpl()
: key_(KeyTypeHandler::Constinit()),
value_(ValueTypeHandler::Constinit()),
_has_bits_{} {}
explicit MapEntryImpl(Arena* arena) : Base(arena) {
KeyTypeHandler::Initialize(&key_, arena);
ValueTypeHandler::Initialize(&value_, arena);
_has_bits_[0] = 0;
}
explicit MapEntryImpl(Arena* arena)
: Base(arena),
key_(KeyTypeHandler::Constinit()),
value_(ValueTypeHandler::Constinit()),
_has_bits_{} {}
~MapEntryImpl() {
if (Base::GetArena() != NULL) return;
@ -523,7 +522,7 @@ class MapEntryLite : public MapEntryImpl<T, MessageLite, Key, Value,
typedef MapEntryImpl<T, MessageLite, Key, Value, kKeyFieldType,
kValueFieldType>
SuperType;
MapEntryLite() {}
constexpr MapEntryLite() {}
explicit MapEntryLite(Arena* arena) : SuperType(arena) {}
~MapEntryLite() { MessageLite::_internal_metadata_.Delete<std::string>(); }
void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); }

@ -324,6 +324,16 @@ class PROTOBUF_EXPORT MapFieldBase {
public:
MapFieldBase()
: arena_(NULL), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {}
// This constructor is for constant initialized global instances.
// It uses a linker initialized mutex, so it is not compatible with regular
// runtime instances.
// Except in MSVC, where we can't have a constinit mutex.
explicit PROTOBUF_MAYBE_CONSTEXPR MapFieldBase(ConstantInitialized)
: arena_(nullptr),
repeated_field_(nullptr),
mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED),
state_(STATE_MODIFIED_MAP) {}
explicit MapFieldBase(Arena* arena)
: arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {
// Mutex's destructor needs to be called explicitly to release resources
@ -466,6 +476,12 @@ template <typename Key, typename T>
class TypeDefinedMapFieldBase : public MapFieldBase {
public:
TypeDefinedMapFieldBase() {}
// This constructor is for constant initialized global instances.
// It uses a linker initialized mutex, so it is not compatible with regular
// runtime instances.
explicit constexpr TypeDefinedMapFieldBase(ConstantInitialized tag)
: MapFieldBase(tag) {}
explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
~TypeDefinedMapFieldBase() override {}
void MapBegin(MapIterator* map_iter) const override;
@ -521,6 +537,12 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> {
typedef Map<Key, T> MapType;
MapField() {}
// This constructor is for constant initialized global instances.
// It uses a linker initialized mutex, so it is not compatible with regular
// runtime instances.
explicit constexpr MapField(ConstantInitialized tag)
: TypeDefinedMapFieldBase<Key, T>(tag), impl_() {}
explicit MapField(Arena* arena)
: TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}

@ -63,7 +63,7 @@ class MapFieldLite {
typedef Map<Key, T> MapType;
typedef EntryType EntryTypeTrait;
MapFieldLite() {}
constexpr MapFieldLite() {}
explicit MapFieldLite(Arena* arena) : map_(arena) {}

@ -45,6 +45,9 @@
#include <google/protobuf/repeated_field.h>
#include <gtest/gtest.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
@ -478,6 +481,22 @@ TEST_P(MapFieldStateTest, MutableMapField) {
}
}
class MyMapField
: public MapField<unittest::TestMap_MapInt32Int32Entry_DoNotUse, int32,
int32, internal::WireFormatLite::TYPE_INT32,
internal::WireFormatLite::TYPE_INT32> {
public:
constexpr MyMapField()
: MyMapField::MapField(internal::ConstantInitialized{}) {}
};
TEST(MapFieldTest, ConstInit) {
// This tests that `MapField` and all its base classes can be constant
// initialized.
PROTOBUF_CONSTINIT static MyMapField field; // NOLINT
EXPECT_EQ(field.size(), 0);
}
} // namespace internal
} // namespace protobuf

@ -80,6 +80,7 @@
#include <google/protobuf/stubs/substitute.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google {
@ -1180,6 +1181,11 @@ TEST_F(MapImplTest, TransparentLookupForString) {
TestTransparent(std::cref(abc), std::cref(lkj));
}
TEST_F(MapImplTest, ConstInit) {
PROTOBUF_CONSTINIT static Map<int, int> map; // NOLINT
EXPECT_TRUE(map.empty());
}
// Map Field Reflection Test ========================================
static int Func(int i, int j) { return i * j; }
@ -2047,6 +2053,39 @@ TEST_F(MapFieldReflectionTest, UninitializedEntry) {
EXPECT_FALSE(message.IsInitialized());
}
class MyMapEntry
: public internal::MapEntry<MyMapEntry, ::google::protobuf::int32, ::google::protobuf::int32,
internal::WireFormatLite::TYPE_INT32,
internal::WireFormatLite::TYPE_INT32> {
public:
constexpr MyMapEntry() {}
MyMapEntry(Arena*) { std::abort(); }
Metadata GetMetadata() const override { std::abort(); }
static bool ValidateKey(void*) { return true; }
static bool ValidateValue(void*) { return true; }
};
class MyMapEntryLite
: public internal::MapEntryLite<MyMapEntryLite, ::google::protobuf::int32, ::google::protobuf::int32,
internal::WireFormatLite::TYPE_INT32,
internal::WireFormatLite::TYPE_INT32> {
public:
constexpr MyMapEntryLite() {}
explicit MyMapEntryLite(Arena*) { std::abort(); }
static bool ValidateKey(void*) { return true; }
static bool ValidateValue(void*) { return true; }
};
TEST(MapEntryTest, ConstInit) {
// This verifies that `MapEntry`, `MapEntryLite` and `MapEntryImpl` can be
// constant initialized.
PROTOBUF_CONSTINIT static MyMapEntry entry{};
EXPECT_NE(entry.SpaceUsed(), 0);
PROTOBUF_CONSTINIT static MyMapEntryLite entry_lite{}; // NOLINT
EXPECT_TRUE(entry_lite.IsInitialized());
}
// Generated Message Test ===========================================
TEST(GeneratedMapFieldTest, Accessors) {

@ -157,7 +157,7 @@ class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
static inline void DeleteNoArena(const Type* x);
static inline void Merge(const Type& from, Type** to, Arena* arena);
static inline void Clear(Type** value, Arena* arena);
static inline void Initialize(Type** x, Arena* arena);
static constexpr TypeOnMemory Constinit();
static inline Type* EnsureMutable(Type** value, Arena* arena);
// SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding
@ -207,7 +207,7 @@ class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
const TypeOnMemory& value); \
static inline bool IsInitialized(const TypeOnMemory& value); \
static void DeleteNoArena(TypeOnMemory& value); \
static inline void Initialize(TypeOnMemory* value, Arena* arena); \
static constexpr TypeOnMemory Constinit(); \
static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \
Arena* arena); \
};
@ -522,9 +522,9 @@ void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::DeleteNoArena(
}
template <typename Type>
inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Initialize(
Type** x, Arena* /* arena */) {
*x = NULL;
constexpr auto MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Constinit()
-> TypeOnMemory {
return nullptr;
}
template <typename Type>
@ -583,10 +583,10 @@ inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::IsInitialized(
value.DestroyNoArena(&internal::GetEmptyStringAlreadyInited()); \
} \
template <typename Type> \
inline void \
MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize( \
TypeOnMemory* value, Arena* /* arena */) { \
value->UnsafeSetDefault(&internal::GetEmptyStringAlreadyInited()); \
constexpr auto \
MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Constinit() \
->TypeOnMemory { \
return TypeOnMemory(&internal::GetEmptyStringAlreadyInited()); \
} \
template <typename Type> \
inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
@ -640,10 +640,10 @@ STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES)
inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
Type>::DeleteNoArena(TypeOnMemory& /* x */) {} \
template <typename Type> \
inline void \
MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize( \
TypeOnMemory* value, Arena* /* arena */) { \
*value = 0; \
constexpr auto \
MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Constinit() \
->TypeOnMemory { \
return 0; \
} \
template <typename Type> \
inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \

@ -162,7 +162,7 @@ size_t Message::SpaceUsedLong() const {
return GetReflection()->SpaceUsedLong(*this);
}
size_t Message::GetInvariantPerBuild(size_t salt) {
uint64 Message::GetInvariantPerBuild(uint64 salt) {
return salt;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save