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. 21
      java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
  15. 165
      java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
  16. 118
      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. 68
      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. 4
      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. 6
      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. 35
      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' regex: 'release notes: yes'
message: 'Please include release notes: yes' message: 'Please include release notes: yes'
- must_include: - must_include:
regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel)' 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, cleanup, conformance tests, integration.' 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: - must_include:
regex: 'release notes: no' regex: 'release notes: no'
message: 'Please include release notes: no' message: 'Please include release notes: no'

@ -13,4 +13,4 @@ jobs:
with: with:
check_filenames: true 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 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 # build configuration
################################################################################ ################################################################################
# TODO(yannic): Remove in 3.14.0.
string_flag( string_flag(
name = "incompatible_use_com_google_googletest", name = "incompatible_use_com_google_googletest",
# TODO(yannic): Flip to `true` for `3.13.0`. build_setting_default = "true",
build_setting_default = "false",
values = ["true", "false"] values = ["true", "false"]
) )
@ -368,7 +368,15 @@ cc_library(
cc_proto_blacklist_test( cc_proto_blacklist_test(
name = "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 + [ copts = COPTS + [
"-DPYTHON_PROTO2_CPP_IMPL_V2", "-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, linkshared = 1,
linkstatic = 1, linkstatic = 1,
deps = select({ deps = select({
@ -780,6 +795,13 @@ cc_binary(
"python/", "python/",
"src/", "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, linkshared = 1,
linkstatic = 1, linkstatic = 1,
deps = [ deps = [

@ -29,13 +29,13 @@ bind(
actual = "//util/python:python_headers", actual = "//util/python:python_headers",
) )
# TODO(yannic): Remove in 3.13.0. # TODO(yannic): Remove in 3.14.0.
bind( bind(
name = "gtest", name = "gtest",
actual = "@com_google_googletest//:gtest", actual = "@com_google_googletest//:gtest",
) )
# TODO(yannic): Remove in 3.13.0. # TODO(yannic): Remove in 3.14.0.
bind( bind(
name = "gtest_main", name = "gtest_main",
actual = "@com_google_googletest//: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.ProtobufOutput
Required.Proto3.TextFormatInput.AnyField.TextFormatOutput 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.StringFieldBadUTF8Hex
Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput 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.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -2009,14 +2010,14 @@ public abstract class CodedInputStream {
int prevPos = buffer.position(); int prevPos = buffer.position();
int prevLimit = buffer.limit(); int prevLimit = buffer.limit();
try { try {
buffer.position(bufferPos(begin)); ((Buffer) buffer).position(bufferPos(begin));
buffer.limit(bufferPos(end)); ((Buffer) buffer).limit(bufferPos(end));
return buffer.slice(); return buffer.slice();
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw InvalidProtocolBufferException.truncatedMessage(); throw InvalidProtocolBufferException.truncatedMessage();
} finally { } finally {
buffer.position(prevPos); ((Buffer) buffer).position(prevPos);
buffer.limit(prevLimit); ((Buffer) buffer).limit(prevLimit);
} }
} }
} }
@ -3910,14 +3911,14 @@ public abstract class CodedInputStream {
int prevPos = currentByteBuffer.position(); int prevPos = currentByteBuffer.position();
int prevLimit = currentByteBuffer.limit(); int prevLimit = currentByteBuffer.limit();
try { try {
currentByteBuffer.position(begin); ((Buffer) currentByteBuffer).position(begin);
currentByteBuffer.limit(end); ((Buffer) currentByteBuffer).limit(end);
return currentByteBuffer.slice(); return currentByteBuffer.slice();
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw InvalidProtocolBufferException.truncatedMessage(); throw InvalidProtocolBufferException.truncatedMessage();
} finally { } finally {
currentByteBuffer.position(prevPos); ((Buffer) currentByteBuffer).position(prevPos);
currentByteBuffer.limit(prevLimit); ((Buffer) currentByteBuffer).limit(prevLimit);
} }
} }
} }

@ -764,7 +764,10 @@ public final class Descriptors {
/** /**
* Finds a field by name. * 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. * @return The field's descriptor, or {@code null} if not found.
*/ */
public FieldDescriptor findFieldByName(final String name) { public FieldDescriptor findFieldByName(final String name) {

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

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

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

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

@ -30,6 +30,8 @@
package com.google.protobuf; package com.google.protobuf;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor;
@ -2375,6 +2377,73 @@ public final class TextFormat {
result[pos++] = (byte) code; result[pos++] = (byte) code;
break; 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: default:
throw new InvalidEscapeSequenceException( throw new InvalidEscapeSequenceException(
"Invalid escape sequence: '\\" + (char) c + '\''); "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}. * Find a type by its typeUrl. Returns null if it cannot be found in this {@link TypeRegistry}.
*/ */
/* @Nullable */
public final Descriptor getDescriptorForTypeUrl(String typeUrl) public final Descriptor getDescriptorForTypeUrl(String typeUrl)
throws InvalidProtocolBufferException { throws InvalidProtocolBufferException {
return find(getTypeName(typeUrl)); return find(getTypeName(typeUrl));

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

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

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

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

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

@ -30,6 +30,7 @@
package com.google.protobuf; 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_INITIALIZED;
import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED; 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(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\341\\210\\264"));
assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4")); assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4"));
assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\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. // Handling of strings with unescaped Unicode characters > 255.
final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; 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) { } catch (TextFormat.InvalidEscapeSequenceException e) {
// success // 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 { 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 * <ul>
* removing "foo.bar" from the tree, "foo.bar.baz" will be removed. Likewise, if the field path to * When removing a field path from the tree:
* remove is a non-exist sub-path, nothing will be changed. * <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 @CanIgnoreReturnValue
FieldMaskTree removeFieldPath(String path) { FieldMaskTree removeFieldPath(String path) {
@ -149,23 +157,35 @@ final class FieldMaskTree {
if (parts.isEmpty()) { if (parts.isEmpty()) {
return this; return this;
} }
Node node = root; removeFieldPath(root, parts, 0);
for (int i = 0; i < parts.size(); i++) {
String key = parts.get(i);
if (!node.children.containsKey(key)) {
// Path does not exist.
return this;
}
if (i == parts.size() - 1) {
// Remove path.
node.children.remove(key);
return this;
}
node = node.children.get(key);
}
return this; return this;
} }
/**
* 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 node.children.isEmpty();
}
// Recursive remove sub-path.
if (removeFieldPath(node.children.get(key), parts, index + 1)) {
node.children.remove(key);
}
return node.children.isEmpty();
}
/** Removes all field paths in {@code mask} from this tree. */ /** Removes all field paths in {@code mask} from this tree. */
@CanIgnoreReturnValue @CanIgnoreReturnValue
FieldMaskTree removeFromFieldMask(FieldMask mask) { FieldMaskTree removeFromFieldMask(FieldMask mask) {
@ -187,10 +207,8 @@ final class FieldMaskTree {
return FieldMask.newBuilder().addAllPaths(paths).build(); return FieldMask.newBuilder().addAllPaths(paths).build();
} }
/** /** Gathers all field paths in a sub-tree. */
* Gathers all field paths in a sub-tree. private static void getFieldPaths(Node node, String path, List<String> paths) {
*/
private void getFieldPaths(Node node, String path, List<String> paths) {
if (node.children.isEmpty()) { if (node.children.isEmpty()) {
paths.add(path); paths.add(path);
return; return;
@ -247,10 +265,8 @@ final class FieldMaskTree {
merge(root, "", source, destination, options); merge(root, "", source, destination, options);
} }
/** /** Merges all fields specified by a sub-tree from {@code source} to {@code destination}. */
* Merges all fields specified by a sub-tree from {@code source} to {@code destination}. private static void merge(
*/
private void merge(
Node node, Node node,
String path, String path,
Message source, Message source,

@ -276,7 +276,13 @@ public final class FieldMaskUtil {
return maskTree.toFieldMask(); 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( public static FieldMask subtract(
FieldMask firstMask, FieldMask secondMask, FieldMask... otherMasks) { FieldMask firstMask, FieldMask secondMask, FieldMask... otherMasks) {
FieldMaskTree maskTree = new FieldMaskTree(firstMask).removeFromFieldMask(secondMask); FieldMaskTree maskTree = new FieldMaskTree(firstMask).removeFromFieldMask(secondMask);

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

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

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

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

@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \
parallel \ parallel \
time \ time \
wget \ 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 \ parallel \
time \ time \
wget \ 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 \ parallel \
time \ time \
wget \ 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 \ parallel \
time \ time \
wget \ 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 \ parallel \
time \ time \
wget \ 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 # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { action {

@ -1,7 +1,7 @@
# Config file for running tests in Kokoro # Config file for running tests in Kokoro
# Location of the build script in repository # 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 timeout_mins: 120
action { 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); upb_msg_set(intern->msg, f, msgval, arena);
#if PHP_VERSION_ID < 704000 #if PHP_VERSION_ID < 70400
return; return;
#else #else
return val; return val;
#endif #endif
error: error:
#if PHP_VERSION_ID < 704000 #if PHP_VERSION_ID < 70400
return; return;
#else #else
return &EG(error_zval); return &EG(error_zval);

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

@ -56,7 +56,7 @@ const zval *get_generated_pool();
// instead of zval* and zend_string* instead of zval* for property names. // instead of zval* and zend_string* instead of zval* for property names.
// https://github.com/php/php-src/blob/php-8.0.0beta1/UPGRADING.INTERNALS#L37-L39 // https://github.com/php/php-src/blob/php-8.0.0beta1/UPGRADING.INTERNALS#L37-L39
#if PHP_VERSION_ID < 80000 #if PHP_VERSION_ID < 80000
#define PROTO_VAL zval #define PROTO_VAL zval
#define PROTO_STR zval #define PROTO_STR zval
#define PROTO_MSG_P(obj) (Message*)Z_OBJ_P(obj) #define PROTO_MSG_P(obj) (Message*)Z_OBJ_P(obj)
#define PROTO_STRVAL_P(obj) Z_STRVAL_P(obj) #define PROTO_STRVAL_P(obj) Z_STRVAL_P(obj)
@ -69,7 +69,7 @@ const zval *get_generated_pool();
#define PROTO_STRLEN_P(obj) ZSTR_LEN(obj) #define PROTO_STRLEN_P(obj) ZSTR_LEN(obj)
#endif #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 // ptr -> PHP object cache. This is a weak map that caches lazily-created
// wrapper objects around upb types: // wrapper objects around upb types:

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

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

@ -883,7 +883,8 @@ class _Parser(object):
(expanded_any_end_token,)) (expanded_any_end_token,))
self._MergeField(tokenizer, expanded_any_sub_message) self._MergeField(tokenizer, expanded_any_sub_message)
message.Pack(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 return
if tokenizer.TryConsume('['): if tokenizer.TryConsume('['):

@ -103,4 +103,19 @@ $ python -m pip install .
By default, the protoc binary (the Protobuf compiler) is found by By default, the protoc binary (the Protobuf compiler) is found by
searching the environment path. To use a specific protoc binary, its 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 = commands =
python setup.py -q build_py python setup.py -q build_py
python: python setup.py -q build 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 python: python setup.py -q test -q
cpp: python setup.py -q test -q --cpp_implementation cpp: python setup.py -q test -q --cpp_implementation
python: python setup.py -q test_conformance python: python setup.py -q test_conformance

@ -60,7 +60,8 @@ class PROTOBUF_EXPORT AnyMetadata {
typedef ArenaStringPtr ValueType; typedef ArenaStringPtr ValueType;
public: public:
// AnyMetadata does not take ownership of "type_url" and "value". // 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". // Packs a message using the default type URL prefix: "type.googleapis.com".
// The resulted type URL will be "type.googleapis.com/<message_full_name>". // 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 kTypeGoogleApisComPrefix[] = "type.googleapis.com/";
const char kTypeGoogleProdComPrefix[] = "type.googleprod.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, void AnyMetadata::InternalPackFrom(const MessageLite& message,
StringPiece type_url_prefix, StringPiece type_url_prefix,
StringPiece type_name) { StringPiece type_name) {

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

@ -47,6 +47,10 @@ static const size_t kMaxCleanupListElements = 64; // 1kB on 64-bit.
namespace google { namespace google {
namespace protobuf { namespace protobuf {
PROTOBUF_EXPORT /*static*/ void* (*const ArenaOptions::kDefaultBlockAlloc)(
size_t) = &::operator new;
namespace internal { namespace internal {
const size_t ArenaImpl::kBlockHeaderSize; const size_t ArenaImpl::kBlockHeaderSize;
@ -54,7 +58,7 @@ const size_t ArenaImpl::kSerialArenaSize;
const size_t ArenaImpl::kOptionsSize; const size_t ArenaImpl::kOptionsSize;
std::atomic<LifecycleId> ArenaImpl::lifecycle_id_generator_; ArenaImpl::CacheAlignedLifecycleIdGenerator ArenaImpl::lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ = static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ =
@ -63,12 +67,13 @@ ArenaImpl::ThreadCache& ArenaImpl::thread_cache() {
} }
#elif defined(PROTOBUF_USE_DLLS) #elif defined(PROTOBUF_USE_DLLS)
ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { 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_; return thread_cache_;
} }
#else #else
PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {
NULL}; 0, static_cast<LifecycleIdAtomic>(-1), nullptr};
#endif #endif
void ArenaFree(void* object, size_t size) { void ArenaFree(void* object, size_t size) {
@ -122,9 +127,26 @@ ArenaImpl::ArenaImpl(const ArenaOptions& options) {
} }
void ArenaImpl::Init(bool record_allocs) { 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_. // 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 | (record_allocs ? 1 : 0);
lifecycle_id_ = (id << 1) | (record_allocs ? 1 : 0);
hint_.store(nullptr, std::memory_order_relaxed); hint_.store(nullptr, std::memory_order_relaxed);
threads_.store(nullptr, std::memory_order_relaxed); threads_.store(nullptr, std::memory_order_relaxed);
space_allocated_.store(0, std::memory_order_relaxed); space_allocated_.store(0, std::memory_order_relaxed);

@ -142,10 +142,12 @@ struct ArenaOptions {
max_block_size(kDefaultMaxBlockSize), max_block_size(kDefaultMaxBlockSize),
initial_block(NULL), initial_block(NULL),
initial_block_size(0), initial_block_size(0),
block_alloc(&::operator new), block_alloc(kDefaultBlockAlloc),
block_dealloc(&internal::ArenaFree), block_dealloc(&internal::ArenaFree),
make_metrics_collector(nullptr) {} make_metrics_collector(nullptr) {}
PROTOBUF_EXPORT static void* (*const kDefaultBlockAlloc)(size_t);
private: private:
// If make_metrics_collector is not nullptr, it will be called at Arena init // 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 // 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); 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); void PROTOBUF_EXPORT ArenaFree(void* object, size_t size);
@ -328,20 +328,43 @@ class PROTOBUF_EXPORT ArenaImpl {
ArenaMetricsCollector* metrics_collector; ArenaMetricsCollector* metrics_collector;
}; };
struct ThreadCache { #ifdef _MSC_VER
#pragma warning(disable:4324)
#endif
struct alignas(64) ThreadCache {
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// If we are using the ThreadLocalStorage class to store the ThreadCache, // If we are using the ThreadLocalStorage class to store the ThreadCache,
// then the ThreadCache's default constructor has to be responsible for // then the ThreadCache's default constructor has to be responsible for
// initializing it. // 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 #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 // The ThreadCache is considered valid as long as this matches the
// lifecycle_id of the arena being used. // lifecycle_id of the arena being used.
LifecycleId last_lifecycle_id_seen; uint64 last_lifecycle_id_seen;
SerialArena* last_serial_arena; 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) #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// Android ndk does not support __thread keyword so we use a custom thread // Android ndk does not support __thread keyword so we use a custom thread
// local storage class we implemented. // local storage class we implemented.
@ -430,7 +453,7 @@ class PROTOBUF_EXPORT ArenaImpl {
// Unique for each arena. Changes on Reset(). // Unique for each arena. Changes on Reset().
// Least-significant-bit is 1 iff allocations should be recorded. // Least-significant-bit is 1 iff allocations should be recorded.
LifecycleId lifecycle_id_; uint64 lifecycle_id_;
Options* options_ = nullptr; Options* options_ = nullptr;

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

@ -45,6 +45,9 @@
#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/strutil.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google { namespace google {
namespace protobuf { 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/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/mock_code_generator.h>
#include <google/protobuf/compiler/subprocess.h> #include <google/protobuf/compiler/subprocess.h>
#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/code_generator.h>
@ -123,7 +124,7 @@ class CommandLineInterfaceTest : public testing::Test {
void SwitchToTempDirectory() { void SwitchToTempDirectory() {
File::ChangeWorkingDirectory(temp_directory_); File::ChangeWorkingDirectory(temp_directory_);
} }
#else // !PROTOBUF_OPENSOURCE #else // !PROTOBUF_OPENSOURCE
// TODO(teboring): Figure out how to change and get working directory in // TODO(teboring): Figure out how to change and get working directory in
// google3. // google3.
#endif // !PROTOBUF_OPENSOURCE #endif // !PROTOBUF_OPENSOURCE
@ -681,6 +682,9 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs_UnusedImport_DescriptorSetIn) {
FileDescriptorProto::descriptor()->file(); FileDescriptorProto::descriptor()->file();
descriptor_file->CopyTo(file_descriptor_set.add_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 = const FileDescriptor* custom_file =
protobuf_unittest::AggregateMessage::descriptor()->file(); protobuf_unittest::AggregateMessage::descriptor()->file();
FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file();

@ -164,10 +164,6 @@ class FieldGenerator {
return false; 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", // Generate lines to serialize this field directly to the array "target",
// which are placed within the message's SerializeWithCachedSizesToArray() // which are placed within the message's SerializeWithCachedSizesToArray()
// method. This must also advance "target" past the written bytes. // 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) { if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
continue; continue;
} }
message_generators_[i]->GenerateFieldDefaultInstances(printer);
format( format(
"{\n" "{\n"
" void* ptr = &$1$;\n" " void* ptr = &$1$;\n"

@ -1895,13 +1895,6 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
return num_field_metadata; 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) { void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
Formatter format(printer, variables_); Formatter format(printer, variables_);
if (IsMapEntryMessage(descriptor_)) { if (IsMapEntryMessage(descriptor_)) {

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

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

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

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

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

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

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

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

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

@ -38,6 +38,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <google/protobuf/any.pb.h>
#include <google/protobuf/compiler/importer.h> #include <google/protobuf/compiler/importer.h>
#include <google/protobuf/compiler/parser.h> #include <google/protobuf/compiler/parser.h>
#include <google/protobuf/unittest.pb.h> #include <google/protobuf/unittest.pb.h>
@ -287,9 +288,8 @@ class MockErrorCollector : public DescriptorPool::ErrorCollector {
break; break;
} }
strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", filename,
filename, element_name, location_name, element_name, location_name, message);
message);
} }
}; };
@ -3148,6 +3148,11 @@ TEST(CustomOptions, OptionsFromOtherFile) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); 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( protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto); &file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@ -3206,6 +3211,10 @@ TEST(CustomOptions, MessageOptionThreeFieldsSet) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); 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( protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto); &file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@ -3283,6 +3292,10 @@ TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); 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( protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto); &file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@ -3363,6 +3376,10 @@ TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); 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( protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto); &file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@ -3463,6 +3480,10 @@ TEST(CustomOptions, AggregateOptions) {
message_set_extension) message_set_extension)
.s()); .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 // Simple tests for all the other types of annotations
EXPECT_EQ("MessageAnnotation", EXPECT_EQ("MessageAnnotation",
msg->options().GetExtension(protobuf_unittest::msgopt).s()); msg->options().GetExtension(protobuf_unittest::msgopt).s());
@ -3485,6 +3506,10 @@ TEST(CustomOptions, UnusedImportError) {
FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); 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( protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
&file_proto); &file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
@ -7182,8 +7207,8 @@ class SourceLocationTest : public testing::Test {
static std::string PrintSourceLocation(const SourceLocation& loc) { static std::string PrintSourceLocation(const SourceLocation& loc) {
return strings::Substitute("$0:$1-$2:$3", 1 + loc.start_line, return strings::Substitute("$0:$1-$2:$3", 1 + loc.start_line,
1 + loc.start_column, 1 + loc.end_line, 1 + loc.start_column, 1 + loc.end_line,
1 + loc.end_column); 1 + loc.end_column);
} }
private: private:

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

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

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

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

@ -68,16 +68,25 @@ void DestroyString(const void* s) {
static_cast<const std::string*>(s)->~basic_string(); 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() { static bool InitProtobufDefaultsImpl() {
fixed_address_empty_string.DefaultConstruct(); ::new (static_cast<void*>(&fixed_address_empty_string.value)) std::string();
OnShutdownDestroyString(fixed_address_empty_string.get_mutable()); 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; return true;
} }
void InitProtobufDefaults() { void InitProtobufDefaultsSlow() {
static bool is_inited = InitProtobufDefaultsImpl(); static bool is_inited = InitProtobufDefaultsImpl();
(void)is_inited; (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 // This used by proto1
PROTOBUF_EXPORT inline const std::string& GetEmptyString() { PROTOBUF_EXPORT inline const std::string& GetEmptyString() {

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

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

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

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

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

@ -324,6 +324,16 @@ class PROTOBUF_EXPORT MapFieldBase {
public: public:
MapFieldBase() MapFieldBase()
: arena_(NULL), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {} : 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) explicit MapFieldBase(Arena* arena)
: arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) { : arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {
// Mutex's destructor needs to be called explicitly to release resources // Mutex's destructor needs to be called explicitly to release resources
@ -466,6 +476,12 @@ template <typename Key, typename T>
class TypeDefinedMapFieldBase : public MapFieldBase { class TypeDefinedMapFieldBase : public MapFieldBase {
public: public:
TypeDefinedMapFieldBase() {} 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) {} explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
~TypeDefinedMapFieldBase() override {} ~TypeDefinedMapFieldBase() override {}
void MapBegin(MapIterator* map_iter) const override; void MapBegin(MapIterator* map_iter) const override;
@ -521,6 +537,12 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> {
typedef Map<Key, T> MapType; typedef Map<Key, T> MapType;
MapField() {} 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) explicit MapField(Arena* arena)
: TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {} : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}

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

@ -45,6 +45,9 @@
#include <google/protobuf/repeated_field.h> #include <google/protobuf/repeated_field.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google { namespace google {
namespace protobuf { 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 internal
} // namespace protobuf } // namespace protobuf

@ -80,6 +80,7 @@
#include <google/protobuf/stubs/substitute.h> #include <google/protobuf/stubs/substitute.h>
// Must be included last.
#include <google/protobuf/port_def.inc> #include <google/protobuf/port_def.inc>
namespace google { namespace google {
@ -1180,6 +1181,11 @@ TEST_F(MapImplTest, TransparentLookupForString) {
TestTransparent(std::cref(abc), std::cref(lkj)); 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 ======================================== // Map Field Reflection Test ========================================
static int Func(int i, int j) { return i * j; } static int Func(int i, int j) { return i * j; }
@ -2047,6 +2053,39 @@ TEST_F(MapFieldReflectionTest, UninitializedEntry) {
EXPECT_FALSE(message.IsInitialized()); 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 =========================================== // Generated Message Test ===========================================
TEST(GeneratedMapFieldTest, Accessors) { TEST(GeneratedMapFieldTest, Accessors) {

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

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

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

Loading…
Cancel
Save