diff --git a/.github/mergeable.yml b/.github/mergeable.yml index a827eb7c68..8577f086ee 100644 --- a/.github/mergeable.yml +++ b/.github/mergeable.yml @@ -11,8 +11,8 @@ mergeable: regex: 'release notes: yes' message: 'Please include release notes: yes' - must_include: - regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel)' - message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cleanup, conformance tests, integration.' + regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel|cmake|protoc)' + message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cmake, cleanup, conformance tests, integration, protoc.' - must_include: regex: 'release notes: no' message: 'Please include release notes: no' diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 4ef1a1bd27..f9795e190c 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -13,4 +13,4 @@ jobs: with: check_filenames: true skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal - ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od" + ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od" diff --git a/BUILD b/BUILD index afad437c10..92e4091db3 100644 --- a/BUILD +++ b/BUILD @@ -14,10 +14,10 @@ exports_files(["LICENSE"]) # build configuration ################################################################################ +# TODO(yannic): Remove in 3.14.0. string_flag( name = "incompatible_use_com_google_googletest", - # TODO(yannic): Flip to `true` for `3.13.0`. - build_setting_default = "false", + build_setting_default = "true", values = ["true", "false"] ) @@ -368,7 +368,15 @@ cc_library( cc_proto_blacklist_test( name = "cc_proto_blacklist_test", - deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()] + deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], + tags = [ + # Exclude this target from wildcard expansion (//...). Due to + # https://github.com/bazelbuild/bazel/issues/10590, this test has to + # be nominated using the `@com_google_protobuf//` prefix. We do that, + # e.g., in kokoro/linux/bazel/build.sh. + # See also https://github.com/protocolbuffers/protobuf/pull/7096. + "manual", + ], ) ################################################################################ @@ -756,6 +764,13 @@ cc_binary( copts = COPTS + [ "-DPYTHON_PROTO2_CPP_IMPL_V2", ], + tags = [ + # Exclude this target from wildcard expansion (//...) because it may + # not even be buildable. It will be built if it is needed according + # to :use_fast_cpp_protos. + # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes + "manual", + ], linkshared = 1, linkstatic = 1, deps = select({ @@ -780,6 +795,13 @@ cc_binary( "python/", "src/", ], + tags = [ + # Exclude this target from wildcard expansion (//...) because it may + # not even be buildable. It will be built if it is needed according + # to :use_fast_cpp_protos. + # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes + "manual", + ], linkshared = 1, linkstatic = 1, deps = [ diff --git a/WORKSPACE b/WORKSPACE index cb16ae882c..5a767a97c0 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -29,13 +29,13 @@ bind( actual = "//util/python:python_headers", ) -# TODO(yannic): Remove in 3.13.0. +# TODO(yannic): Remove in 3.14.0. bind( name = "gtest", actual = "@com_google_googletest//:gtest", ) -# TODO(yannic): Remove in 3.13.0. +# TODO(yannic): Remove in 3.14.0. bind( name = "gtest_main", actual = "@com_google_googletest//:gtest_main", diff --git a/conformance/text_format_failure_list_java.txt b/conformance/text_format_failure_list_java.txt index 8f74bdfb7e..71e32429ec 100644 --- a/conformance/text_format_failure_list_java.txt +++ b/conformance/text_format_failure_list_java.txt @@ -5,14 +5,6 @@ Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput Required.Proto3.TextFormatInput.AnyField.ProtobufOutput Required.Proto3.TextFormatInput.AnyField.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput -Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java index e20a8858c2..ff81e0032f 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -41,6 +41,7 @@ import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; @@ -2009,14 +2010,14 @@ public abstract class CodedInputStream { int prevPos = buffer.position(); int prevLimit = buffer.limit(); try { - buffer.position(bufferPos(begin)); - buffer.limit(bufferPos(end)); + ((Buffer) buffer).position(bufferPos(begin)); + ((Buffer) buffer).limit(bufferPos(end)); return buffer.slice(); } catch (IllegalArgumentException e) { throw InvalidProtocolBufferException.truncatedMessage(); } finally { - buffer.position(prevPos); - buffer.limit(prevLimit); + ((Buffer) buffer).position(prevPos); + ((Buffer) buffer).limit(prevLimit); } } } @@ -3910,14 +3911,14 @@ public abstract class CodedInputStream { int prevPos = currentByteBuffer.position(); int prevLimit = currentByteBuffer.limit(); try { - currentByteBuffer.position(begin); - currentByteBuffer.limit(end); + ((Buffer) currentByteBuffer).position(begin); + ((Buffer) currentByteBuffer).limit(end); return currentByteBuffer.slice(); } catch (IllegalArgumentException e) { throw InvalidProtocolBufferException.truncatedMessage(); } finally { - currentByteBuffer.position(prevPos); - currentByteBuffer.limit(prevLimit); + ((Buffer) currentByteBuffer).position(prevPos); + ((Buffer) currentByteBuffer).limit(prevLimit); } } } diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java index f27602aeb2..c30b00ddf7 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -764,7 +764,10 @@ public final class Descriptors { /** * Finds a field by name. * - * @param name The unqualified name of the field (e.g. "foo"). + * @param name The unqualified name of the field (e.g. "foo"). For protocol buffer messages that + * follow Google's + * guidance on naming this will be a snake case string, such as
song_name
. * @return The field's descriptor, or {@code null} if not found. */ public FieldDescriptor findFieldByName(final String name) { diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java index 241fcbd932..0a63fad187 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java @@ -46,7 +46,6 @@ final class ExtensionRegistryFactory { @Nullable */ static final Class EXTENSION_REGISTRY_CLASS = reflectExtensionRegistry(); - /* @Nullable */ static Class reflectExtensionRegistry() { try { return Class.forName(FULL_REGISTRY_CLASS_NAME); @@ -77,7 +76,6 @@ final class ExtensionRegistryFactory { && EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass()); } - /* @Nullable */ private static final ExtensionRegistryLite invokeSubclassFactory(String methodName) { if (EXTENSION_REGISTRY_CLASS == null) { return null; diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java index 0c4b20ed74..caa58e1ada 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java @@ -84,10 +84,8 @@ public class ExtensionRegistryLite { static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension"; private static class ExtensionClassHolder { - /* @Nullable */ static final Class INSTANCE = resolveExtensionClass(); - /* @Nullable */ static Class resolveExtensionClass() { try { return Class.forName(EXTENSION_CLASS_NAME); diff --git a/java/core/src/main/java/com/google/protobuf/FieldType.java b/java/core/src/main/java/com/google/protobuf/FieldType.java index 1b8f9e5da2..72327537fd 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldType.java +++ b/java/core/src/main/java/com/google/protobuf/FieldType.java @@ -204,7 +204,6 @@ public enum FieldType { * * @return the {@link FieldType} or {@code null} if not found. */ - /* @Nullable */ public static FieldType forId(int id) { if (id < 0 || id >= VALUES.length) { return null; @@ -228,7 +227,6 @@ public enum FieldType { * * @return the generic super class/interface, or {@code null} if not found. */ - /* @Nullable */ private static Type getGenericSuperList(Class clazz) { // First look at interfaces. Type[] genericInterfaces = clazz.getGenericInterfaces(); diff --git a/java/core/src/main/java/com/google/protobuf/NioByteString.java b/java/core/src/main/java/com/google/protobuf/NioByteString.java index 64c46be689..1e594ff878 100644 --- a/java/core/src/main/java/com/google/protobuf/NioByteString.java +++ b/java/core/src/main/java/com/google/protobuf/NioByteString.java @@ -37,6 +37,7 @@ import java.io.InputStream; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.OutputStream; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.InvalidMarkException; @@ -109,7 +110,7 @@ final class NioByteString extends ByteString.LeafByteString { protected void copyToInternal( byte[] target, int sourceOffset, int targetOffset, int numberToCopy) { ByteBuffer slice = buffer.slice(); - slice.position(sourceOffset); + ((Buffer) slice).position(sourceOffset); slice.get(target, targetOffset, numberToCopy); } @@ -285,8 +286,8 @@ final class NioByteString extends ByteString.LeafByteString { } ByteBuffer slice = buffer.slice(); - slice.position(beginIndex - buffer.position()); - slice.limit(endIndex - buffer.position()); + ((Buffer) slice).position(beginIndex - buffer.position()); + ((Buffer) slice).limit(endIndex - buffer.position()); return slice; } } diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java index 7f744ddba7..bbc0f8dd94 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -30,6 +30,8 @@ package com.google.protobuf; +import static java.nio.charset.StandardCharsets.UTF_8; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; @@ -2375,6 +2377,73 @@ public final class TextFormat { result[pos++] = (byte) code; break; + case 'u': + // Unicode escape + ++i; + if (i + 3 < input.size() + && isHex(input.byteAt(i)) + && isHex(input.byteAt(i + 1)) + && isHex(input.byteAt(i + 2)) + && isHex(input.byteAt(i + 3))) { + char ch = + (char) + (digitValue(input.byteAt(i)) << 12 + | digitValue(input.byteAt(i + 1)) << 8 + | digitValue(input.byteAt(i + 2)) << 4 + | digitValue(input.byteAt(i + 3))); + if (Character.isSurrogate(ch)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\u' refers to a surrogate"); + } + byte[] chUtf8 = Character.toString(ch).getBytes(UTF_8); + System.arraycopy(chUtf8, 0, result, pos, chUtf8.length); + pos += chUtf8.length; + i += 3; + } else { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\u' with too few hex chars"); + } + break; + + case 'U': + // Unicode escape + ++i; + if (i + 7 >= input.size()) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U' with too few hex chars"); + } + int codepoint = 0; + for (int offset = i; offset < i + 8; offset++) { + byte b = input.byteAt(offset); + if (!isHex(b)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U' with too few hex chars"); + } + codepoint = (codepoint << 4) | digitValue(b); + } + if (!Character.isValidCodePoint(codepoint)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U" + + input.substring(i, i + 8).toStringUtf8() + + "' is not a valid code point value"); + } + Character.UnicodeBlock unicodeBlock = Character.UnicodeBlock.of(codepoint); + if (unicodeBlock.equals(Character.UnicodeBlock.LOW_SURROGATES) + || unicodeBlock.equals(Character.UnicodeBlock.HIGH_SURROGATES) + || unicodeBlock.equals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U" + + input.substring(i, i + 8).toStringUtf8() + + "' refers to a surrogate code unit"); + } + int[] codepoints = new int[1]; + codepoints[0] = codepoint; + byte[] chUtf8 = new String(codepoints, 0, 1).getBytes(UTF_8); + System.arraycopy(chUtf8, 0, result, pos, chUtf8.length); + pos += chUtf8.length; + i += 7; + break; + default: throw new InvalidEscapeSequenceException( "Invalid escape sequence: '\\" + (char) c + '\''); diff --git a/java/core/src/main/java/com/google/protobuf/TypeRegistry.java b/java/core/src/main/java/com/google/protobuf/TypeRegistry.java index 47d798bfe6..422ff1f870 100644 --- a/java/core/src/main/java/com/google/protobuf/TypeRegistry.java +++ b/java/core/src/main/java/com/google/protobuf/TypeRegistry.java @@ -70,7 +70,6 @@ public class TypeRegistry { /** * Find a type by its typeUrl. Returns null if it cannot be found in this {@link TypeRegistry}. */ - /* @Nullable */ public final Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException { return find(getTypeName(typeUrl)); diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java index b435327ab8..471238ae43 100644 --- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java +++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java @@ -41,7 +41,6 @@ import java.util.logging.Logger; /** Utility class for working with unsafe operations. */ final class UnsafeUtil { - private static final Logger logger = Logger.getLogger(UnsafeUtil.class.getName()); private static final sun.misc.Unsafe UNSAFE = getUnsafe(); private static final Class MEMORY_CLASS = Android.getMemoryClass(); private static final boolean IS_ANDROID_64 = determineAndroidSupportByAddressSize(long.class); @@ -363,9 +362,13 @@ final class UnsafeUtil { return true; } catch (Throwable e) { - logger.log( - Level.WARNING, - "platform method missing - proto runtime falling back to safer methods: " + e); + // Because log statements are fairly sparse in this class, this logger is initialized + // non-statically. Static initialization adds undue runtime costs to the first client to + // initialize this class. + Logger.getLogger(UnsafeUtil.class.getName()) + .log( + Level.WARNING, + "platform method missing - proto runtime falling back to safer methods: " + e); } return false; } @@ -397,9 +400,13 @@ final class UnsafeUtil { clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class); return true; } catch (Throwable e) { - logger.log( - Level.WARNING, - "platform method missing - proto runtime falling back to safer methods: " + e); + // Because log statements are fairly sparse in this class, this logger is initialized + // non-statically. Static initialization adds undue runtime costs to the first client to + // initialize this class. + Logger.getLogger(UnsafeUtil.class.getName()) + .log( + Level.WARNING, + "platform method missing - proto runtime falling back to safer methods: " + e); } return false; } diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java index adca1d51b6..9994ad067a 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java @@ -77,44 +77,44 @@ public final class MapForProto2LiteTest extends TestCase { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValues(TestMap.Builder builder) { @@ -152,35 +152,35 @@ public final class MapForProto2LiteTest extends TestCase { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { @@ -206,13 +206,13 @@ public final class MapForProto2LiteTest extends TestCase { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); builder.putInt32ToInt32Field(1, 2); - assertTrue(message.getInt32ToInt32Field().isEmpty()); + assertTrue(message.getInt32ToInt32FieldMap().isEmpty()); message = builder.build(); - assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); } public void testGetMapIsImmutable() { @@ -254,30 +254,31 @@ public final class MapForProto2LiteTest extends TestCase { public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap()); builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO); assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField()); + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), + builder.getInt32ToEnumFieldMap()); builder.putInt32ToStringField(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); - assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap()); + assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap()); builder.putInt32ToStringField(2, "2"); - assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap()); builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageField()); + builder.build().getInt32ToMessageFieldMap()); assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField()); + newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap()); builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap( @@ -285,7 +286,7 @@ public final class MapForProto2LiteTest extends TestCase { TestMap.MessageValue.getDefaultInstance(), 2, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + builder.getInt32ToMessageFieldMap()); } public void testGettersAndSetters() throws Exception { @@ -415,7 +416,7 @@ public final class MapForProto2LiteTest extends TestCase { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -476,14 +477,14 @@ public final class MapForProto2LiteTest extends TestCase { TestMap message = TestMap.parseFrom(data); // Entries with unknown enum values will be stored into UnknownFieldSet so // there is only one entry in the map. - assertEquals(1, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); + assertEquals(1, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); // Serializing and parsing should preserve the unknown entry. data = message.toByteString(); TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data); - assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size()); - assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue()); - assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue()); + assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size()); + assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()); } public void testIterationOrder() throws Exception { @@ -493,7 +494,7 @@ public final class MapForProto2LiteTest extends TestCase { assertEquals( Arrays.asList("1", "2", "3"), - new ArrayList(message.getStringToInt32Field().keySet())); + new ArrayList(message.getStringToInt32FieldMap().keySet())); } private static Map newMap(K key1, V value1) { @@ -513,10 +514,10 @@ public final class MapForProto2LiteTest extends TestCase { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } public void testContains() { diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java index bb706326c4..b995802b4f 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java @@ -119,12 +119,12 @@ public class MapForProto2Test extends TestCase { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMapOrBuilder message) { @@ -236,35 +236,35 @@ public class MapForProto2Test extends TestCase { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); - - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); - - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); - - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); - - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); - - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); + + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); + + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); + + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); + + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); + + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { @@ -563,7 +563,7 @@ public class MapForProto2Test extends TestCase { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -698,8 +698,8 @@ public class MapForProto2Test extends TestCase { builder.clearField(f("int32_to_int32_field")); builder.clearField(f("int32_to_message_field")); message = builder.build(); - assertEquals(0, message.getInt32ToInt32Field().size()); - assertEquals(0, message.getInt32ToMessageField().size()); + assertEquals(0, message.getInt32ToInt32FieldMap().size()); + assertEquals(0, message.getInt32ToMessageFieldMap().size()); // Test setField() setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); @@ -710,10 +710,10 @@ public class MapForProto2Test extends TestCase { 111, MessageValue.newBuilder().setValue(222).build(), 333, MessageValue.newBuilder().setValue(444).build())); message = builder.build(); - assertEquals(22, message.getInt32ToInt32Field().get(11).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(33).intValue()); - assertEquals(222, message.getInt32ToMessageField().get(111).getValue()); - assertEquals(444, message.getInt32ToMessageField().get(333).getValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue()); + assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue()); + assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue()); // Test addRepeatedField builder.addRepeatedField( @@ -726,8 +726,8 @@ public class MapForProto2Test extends TestCase { 555, MessageValue.newBuilder().setValue(666).build())); message = builder.build(); - assertEquals(66, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(666, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test addRepeatedField (overriding existing values) builder.addRepeatedField( @@ -740,8 +740,8 @@ public class MapForProto2Test extends TestCase { 555, MessageValue.newBuilder().setValue(555).build())); message = builder.build(); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(555, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test setRepeatedField for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { @@ -755,9 +755,9 @@ public class MapForProto2Test extends TestCase { builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); } message = builder.build(); - assertEquals(11, message.getInt32ToInt32Field().get(22).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(44).intValue()); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); } // See additional coverage in TextFormatTest.java. @@ -844,16 +844,16 @@ public class MapForProto2Test extends TestCase { TestMap message = TestMap.parseFrom(data); // Entries with unknown enum values will be stored into UnknownFieldSet so // there is only one entry in the map. - assertEquals(1, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); + assertEquals(1, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); // UnknownFieldSet should not be empty. assertFalse(message.getUnknownFields().asMap().isEmpty()); // Serializing and parsing should preserve the unknown entry. data = message.toByteString(); TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data); - assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size()); - assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue()); - assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue()); + assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size()); + assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()); } public void testRequiredMessage() throws Exception { @@ -885,7 +885,7 @@ public class MapForProto2Test extends TestCase { assertEquals( Arrays.asList("1", "2", "3"), - new ArrayList(message.getStringToInt32Field().keySet())); + new ArrayList(message.getStringToInt32FieldMap().keySet())); } public void testContains() { @@ -1172,9 +1172,9 @@ public class MapForProto2Test extends TestCase { setMapValuesUsingAccessors(builder); assertMapValuesSet(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } } diff --git a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java index d18fd13e0a..40bb7893b3 100644 --- a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java @@ -84,44 +84,44 @@ public final class MapLiteTest extends TestCase { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValues(TestMap.Builder builder) { @@ -159,35 +159,35 @@ public final class MapLiteTest extends TestCase { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { @@ -213,12 +213,12 @@ public final class MapLiteTest extends TestCase { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); builder.putInt32ToInt32Field(1, 2); - assertTrue(message.getInt32ToInt32Field().isEmpty()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertTrue(message.getInt32ToInt32FieldMap().isEmpty()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); message = builder.build(); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); } public void testGetMapIsImmutable() { @@ -266,30 +266,31 @@ public final class MapLiteTest extends TestCase { public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap()); builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO); assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField()); + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), + builder.getInt32ToEnumFieldMap()); builder.putInt32ToStringField(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); - assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap()); + assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap()); builder.putInt32ToStringField(2, "2"); - assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap()); builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageField()); + builder.build().getInt32ToMessageFieldMap()); assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField()); + newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap()); builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap( @@ -297,7 +298,7 @@ public final class MapLiteTest extends TestCase { TestMap.MessageValue.getDefaultInstance(), 2, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + builder.getInt32ToMessageFieldMap()); } public void testGettersAndSetters() throws Exception { @@ -342,12 +343,12 @@ public final class MapLiteTest extends TestCase { TestMap source = sourceBuilder.build(); TestMap.Builder destinationBuilder = TestMap.newBuilder(); - destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue()); + destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap()); TestMap destination = destinationBuilder.build(); - assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue()); - assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue()); - assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue()); + assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue()); + assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue()); assertEquals(3, destination.getInt32ToEnumFieldCount()); } @@ -459,7 +460,7 @@ public final class MapLiteTest extends TestCase { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -524,24 +525,24 @@ public final class MapLiteTest extends TestCase { .putInt32ToEnumFieldValue(2, 1000); // unknown value. TestMap message = builder.build(); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2)); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); builder.putAllInt32ToEnumFieldValue(newMap(2, 1000)); // unknown value. message = builder.build(); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2)); + assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); // Unknown enum values should be preserved after: // 1. Serialization and parsing. // 2. toBuild(). // 3. mergeFrom(). message = TestMap.parseFrom(message.toByteString()); - assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = message.toBuilder(); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = TestMap.newBuilder().mergeFrom(message); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); // hashCode()/equals() should take unknown enum values into account. builder.putAllInt32ToEnumFieldValue(newMap(2, 1001)); @@ -550,7 +551,7 @@ public final class MapLiteTest extends TestCase { assertFalse(message.equals(message2)); // Unknown values will be converted to UNRECOGNIZED so the resulted enum map // should be the same. - assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField()); + assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); } public void testIterationOrder() throws Exception { @@ -559,18 +560,18 @@ public final class MapLiteTest extends TestCase { TestMap message = builder.build(); assertEquals( - Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet())); + Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet())); } public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } public void testContains() { diff --git a/java/core/src/test/java/com/google/protobuf/MapTest.java b/java/core/src/test/java/com/google/protobuf/MapTest.java index 9f1ebaed69..f3458dd235 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java @@ -122,44 +122,44 @@ public class MapTest extends TestCase { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValuesUsingMutableMap(TestMap.Builder builder) { @@ -239,35 +239,35 @@ public class MapTest extends TestCase { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { @@ -468,11 +468,13 @@ public class MapTest extends TestCase { .build(); TestMap destination = - TestMap.newBuilder().putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue()).build(); + TestMap.newBuilder() + .putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap()) + .build(); - assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue()); - assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue()); - assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue()); + assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue()); + assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue()); assertEquals(3, destination.getInt32ToEnumFieldCount()); } @@ -583,7 +585,7 @@ public class MapTest extends TestCase { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -644,14 +646,14 @@ public class MapTest extends TestCase { TestOnChangeEventPropagation.Builder parent = TestOnChangeEventPropagation.newBuilder(); parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 2); TestOnChangeEventPropagation message = parent.build(); - assertEquals(2, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(2, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Make a change using nested builder. parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 3); // Should be able to observe the change. message = parent.build(); - assertEquals(3, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(3, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Make another change using mergeFrom() TestMap other = TestMap.newBuilder().putInt32ToInt32Field(1, 4).build(); @@ -659,14 +661,14 @@ public class MapTest extends TestCase { // Should be able to observe the change. message = parent.build(); - assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Make yet another change by clearing the nested builder. parent.getOptionalMessageBuilder().clear(); // Should be able to observe the change. message = parent.build(); - assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size()); + assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); } public void testNestedBuilderOnChangeEventPropagationReflection() { @@ -683,7 +685,7 @@ public class MapTest extends TestCase { // Should be able to observe the change. TestOnChangeEventPropagation message = parentBuilder.build(); - assertEquals(1, message.getOptionalMessage().getInt32ToInt32Field().size()); + assertEquals(1, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); // Change the entry value. entryBuilder.putInt32ToInt32Field(1, 4); @@ -692,7 +694,7 @@ public class MapTest extends TestCase { // Should be able to observe the change. message = parentBuilder.build(); - assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Clear the nested builder. testMapBuilder = parentBuilder.getOptionalMessageBuilder(); @@ -700,7 +702,7 @@ public class MapTest extends TestCase { // Should be able to observe the change. message = parentBuilder.build(); - assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size()); + assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); } // The following methods are used to test reflection API. @@ -789,8 +791,8 @@ public class MapTest extends TestCase { builder.clearField(f("int32_to_int32_field")); builder.clearField(f("int32_to_message_field")); message = builder.build(); - assertEquals(0, message.getInt32ToInt32Field().size()); - assertEquals(0, message.getInt32ToMessageField().size()); + assertEquals(0, message.getInt32ToInt32FieldMap().size()); + assertEquals(0, message.getInt32ToMessageFieldMap().size()); // Test setField() setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); @@ -801,10 +803,10 @@ public class MapTest extends TestCase { 111, MessageValue.newBuilder().setValue(222).build(), 333, MessageValue.newBuilder().setValue(444).build())); message = builder.build(); - assertEquals(22, message.getInt32ToInt32Field().get(11).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(33).intValue()); - assertEquals(222, message.getInt32ToMessageField().get(111).getValue()); - assertEquals(444, message.getInt32ToMessageField().get(333).getValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue()); + assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue()); + assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue()); // Test addRepeatedField builder.addRepeatedField( @@ -817,8 +819,8 @@ public class MapTest extends TestCase { 555, MessageValue.newBuilder().setValue(666).build())); message = builder.build(); - assertEquals(66, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(666, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test addRepeatedField (overriding existing values) builder.addRepeatedField( @@ -831,8 +833,8 @@ public class MapTest extends TestCase { 555, MessageValue.newBuilder().setValue(555).build())); message = builder.build(); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(555, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test setRepeatedField for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { @@ -846,9 +848,9 @@ public class MapTest extends TestCase { builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); } message = builder.build(); - assertEquals(11, message.getInt32ToInt32Field().get(22).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(44).intValue()); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); } // See additional coverage in TextFormatTest.java. @@ -937,21 +939,21 @@ public class MapTest extends TestCase { 2, 1000)); // unknown value. TestMap message = builder.build(); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2)); - assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); // Unknown enum values should be preserved after: // 1. Serialization and parsing. // 2. toBuild(). // 3. mergeFrom(). message = TestMap.parseFrom(message.toByteString()); - assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = message.toBuilder(); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = TestMap.newBuilder().mergeFrom(message); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); // hashCode()/equals() should take unknown enum values into account. builder.putAllInt32ToEnumFieldValue(newMap(2, 1001)); @@ -960,7 +962,7 @@ public class MapTest extends TestCase { assertFalse(message.equals(message2)); // Unknown values will be converted to UNRECOGNIZED so the resulted enum map // should be the same. - assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField()); + assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); } public void testUnknownEnumValuesInReflectionApi() throws Exception { @@ -991,7 +993,7 @@ public class MapTest extends TestCase { // Verify that enum values have been successfully updated. TestMap message = builder.build(); - for (Map.Entry entry : message.getInt32ToEnumFieldValue().entrySet()) { + for (Map.Entry entry : message.getInt32ToEnumFieldValueMap().entrySet()) { assertEquals(data.get(entry.getKey()) + 1, entry.getValue().intValue()); } } @@ -1002,18 +1004,18 @@ public class MapTest extends TestCase { TestMap message = builder.build(); assertEquals( - Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet())); + Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet())); } public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } public void testContains() { diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java index e229facace..915dddf392 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -30,6 +30,7 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED; import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED; @@ -866,6 +867,12 @@ public class TextFormatTest extends TestCase { assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\341\\210\\264")); assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4")); assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\xe1\\x88\\xb4")); + assertEquals("\u1234", TextFormat.unescapeText("\\u1234")); + assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\u1234")); + assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\U00001234")); + assertEquals( + new String(new int[] {0x10437}, 0, 1), TextFormat.unescapeText("\\xf0\\x90\\x90\\xb7")); + assertEquals(bytes(0xf0, 0x90, 0x90, 0xb7), TextFormat.unescapeBytes("\\U00010437")); // Handling of strings with unescaped Unicode characters > 255. final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; @@ -893,6 +900,87 @@ public class TextFormatTest extends TestCase { } catch (TextFormat.InvalidEscapeSequenceException e) { // success } + + try { + TextFormat.unescapeText("\\u"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' with too few hex chars"); + } + + try { + TextFormat.unescapeText("\\ud800"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\ud800\\u1234"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\udc00"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\ud801\\udc37"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\U1234"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U' with too few hex chars"); + } + + try { + TextFormat.unescapeText("\\U1234no more hex"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U' with too few hex chars"); + } + + try { + TextFormat.unescapeText("\\U00110000"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U00110000' is not a valid code point value"); + } + + try { + TextFormat.unescapeText("\\U0000d801\\U00000dc37"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U0000d801' refers to a surrogate code unit"); + } } public void testParseInteger() throws Exception { diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java index 4092b30683..352376e015 100644 --- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java +++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java @@ -137,11 +137,19 @@ final class FieldMaskTree { } /** - * Remove {@code path} from the tree. + * Removes {@code path} from the tree. * - *

When removing a field path from the tree, all sub-paths will be removed. That is, after - * removing "foo.bar" from the tree, "foo.bar.baz" will be removed. Likewise, if the field path to - * remove is a non-exist sub-path, nothing will be changed. + *

    + * When removing a field path from the tree: + *
  • All sub-paths will be removed. That is, after removing "foo.bar" from the tree, + * "foo.bar.baz" will be removed. + *
  • 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. + *
  • If the field path to remove is a non-exist sub-path, nothing will be changed. + *
*/ @CanIgnoreReturnValue FieldMaskTree removeFieldPath(String path) { @@ -149,23 +157,35 @@ final class FieldMaskTree { if (parts.isEmpty()) { return this; } - Node node = root; - for (int i = 0; i < parts.size(); i++) { - String key = parts.get(i); - if (!node.children.containsKey(key)) { - // Path does not exist. - return this; - } - if (i == parts.size() - 1) { - // Remove path. - node.children.remove(key); - return this; - } - node = node.children.get(key); - } + removeFieldPath(root, parts, 0); 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 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. */ @CanIgnoreReturnValue FieldMaskTree removeFromFieldMask(FieldMask mask) { @@ -187,10 +207,8 @@ final class FieldMaskTree { return FieldMask.newBuilder().addAllPaths(paths).build(); } - /** - * Gathers all field paths in a sub-tree. - */ - private void getFieldPaths(Node node, String path, List paths) { + /** Gathers all field paths in a sub-tree. */ + private static void getFieldPaths(Node node, String path, List paths) { if (node.children.isEmpty()) { paths.add(path); return; @@ -247,10 +265,8 @@ final class FieldMaskTree { merge(root, "", source, destination, options); } - /** - * Merges all fields specified by a sub-tree from {@code source} to {@code destination}. - */ - private void merge( + /** Merges all fields specified by a sub-tree from {@code source} to {@code destination}. */ + private static void merge( Node node, String path, Message source, diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java index 0c2f90c91e..c32d10a263 100644 --- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java +++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java @@ -276,7 +276,13 @@ public final class FieldMaskUtil { return maskTree.toFieldMask(); } - /** Subtracts {@code secondMask} and {@code otherMasks} from {@code firstMask}. */ + /** + * Subtracts {@code secondMask} and {@code otherMasks} from {@code firstMask}. + * + *

This method disregards proto structure. That is, if {@code firstMask} is "foo" and {@code + * secondMask} is "foo.bar", the response will always be "foo" without considering the internal + * proto structure of message "foo". + */ public static FieldMask subtract( FieldMask firstMask, FieldMask secondMask, FieldMask... otherMasks) { FieldMaskTree maskTree = new FieldMaskTree(firstMask).removeFromFieldMask(secondMask); diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index cc3f5f658f..4f2fe3fcfa 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -525,7 +525,6 @@ public class JsonFormat { return types.get(name); } - /* @Nullable */ Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException { return find(getTypeName(typeUrl)); } diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java index 7ec37d097b..c8297226f7 100644 --- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java @@ -77,25 +77,37 @@ public class FieldMaskTreeTest extends TestCase { public void testRemoveFieldPath() throws Exception { String initialTreeString = "bar.baz,bar.quz.bar,foo"; - FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); + FieldMaskTree tree; + // Empty path. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath(""); assertEquals(initialTreeString, tree.toString()); + // Non-exist sub-path of an existing leaf. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("foo.bar"); assertEquals(initialTreeString, tree.toString()); + // Non-exist path. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("bar.foo"); assertEquals(initialTreeString, tree.toString()); - // Match an existing leaf node. + + // Match an existing leaf node -> remove leaf node. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("foo"); assertEquals("bar.baz,bar.quz.bar", tree.toString()); - // Match sub-path of an existing leaf node. + + // Match sub-path of an existing leaf node -> recursive removal. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("bar.quz.bar"); - assertEquals("bar.baz,bar.quz", tree.toString()); - // Match a non-leaf node. + assertEquals("bar.baz,foo", tree.toString()); + + // Match a non-leaf node -> remove all children. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); tree.removeFieldPath("bar"); - assertThat(tree.toString()).isEmpty(); + assertEquals("foo", tree.toString()); } public void testRemoveFromFieldMask() throws Exception { diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java index 796020eaf2..28e43a7bf7 100644 --- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java @@ -239,7 +239,7 @@ public class FieldMaskUtilTest extends TestCase { FieldMask mask3 = FieldMaskUtil.fromString("bar.quz"); FieldMask mask4 = FieldMaskUtil.fromString("foo,bar.baz"); FieldMask result = FieldMaskUtil.subtract(mask1, mask2, mask3, mask4); - assertEquals("bar", FieldMaskUtil.toString(result)); + assertThat(FieldMaskUtil.toString(result)).isEmpty(); } public void testIntersection() throws Exception { diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index f9358e5221..46d3cc4c35 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -722,8 +722,8 @@ public class JsonFormatTest extends TestCase { mergeFromJson( "{\n" + " int32ToInt32Map: {1: 2},\n" + " stringToInt32Map: {hello: 3}\n" + "}", builder); TestMap message = builder.build(); - assertEquals(2, message.getInt32ToInt32Map().get(1).intValue()); - assertEquals(3, message.getStringToInt32Map().get("hello").intValue()); + assertEquals(2, message.getInt32ToInt32MapMap().get(1).intValue()); + assertEquals(3, message.getStringToInt32MapMap().get("hello").intValue()); } public void testWrappers() throws Exception { diff --git a/kokoro/linux/dockerfile/test/python27/Dockerfile b/kokoro/linux/dockerfile/test/python27/Dockerfile index e41e49a6e5..6b0eaf72c8 100644 --- a/kokoro/linux/dockerfile/test/python27/Dockerfile +++ b/kokoro/linux/dockerfile/test/python27/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python35/Dockerfile b/kokoro/linux/dockerfile/test/python35/Dockerfile index 3ea4c9e188..50ee184536 100644 --- a/kokoro/linux/dockerfile/test/python35/Dockerfile +++ b/kokoro/linux/dockerfile/test/python35/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python36/Dockerfile b/kokoro/linux/dockerfile/test/python36/Dockerfile index 436846065b..742503e5a4 100644 --- a/kokoro/linux/dockerfile/test/python36/Dockerfile +++ b/kokoro/linux/dockerfile/test/python36/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python37/Dockerfile b/kokoro/linux/dockerfile/test/python37/Dockerfile index c711eb86a5..ee108dd030 100644 --- a/kokoro/linux/dockerfile/test/python37/Dockerfile +++ b/kokoro/linux/dockerfile/test/python37/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python38/Dockerfile b/kokoro/linux/dockerfile/test/python38/Dockerfile index 48a7be5e05..56efc9d6bf 100644 --- a/kokoro/linux/dockerfile/test/python38/Dockerfile +++ b/kokoro/linux/dockerfile/test/python38/Dockerfile @@ -20,4 +20,12 @@ RUN apt-get update && apt-get install -y \ parallel \ time \ wget \ - && apt-get clean + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/python27/continuous.cfg b/kokoro/linux/python27/continuous.cfg index e2fc4136f0..dd98469a6f 100644 --- a/kokoro/linux/python27/continuous.cfg +++ b/kokoro/linux/python27/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python27/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27/presubmit.cfg b/kokoro/linux/python27/presubmit.cfg index e2fc4136f0..dd98469a6f 100644 --- a/kokoro/linux/python27/presubmit.cfg +++ b/kokoro/linux/python27/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python27/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27_cpp/continuous.cfg b/kokoro/linux/python27_cpp/continuous.cfg index b1b0e550ff..ace22d0077 100644 --- a/kokoro/linux/python27_cpp/continuous.cfg +++ b/kokoro/linux/python27_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python27_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27_cpp/presubmit.cfg b/kokoro/linux/python27_cpp/presubmit.cfg index b1b0e550ff..ace22d0077 100644 --- a/kokoro/linux/python27_cpp/presubmit.cfg +++ b/kokoro/linux/python27_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python27_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35/continuous.cfg b/kokoro/linux/python35/continuous.cfg index e2fc4136f0..2b3e12cbb0 100644 --- a/kokoro/linux/python35/continuous.cfg +++ b/kokoro/linux/python35/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python35/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35/presubmit.cfg b/kokoro/linux/python35/presubmit.cfg index e2fc4136f0..2b3e12cbb0 100644 --- a/kokoro/linux/python35/presubmit.cfg +++ b/kokoro/linux/python35/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python35/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35_cpp/continuous.cfg b/kokoro/linux/python35_cpp/continuous.cfg index b1b0e550ff..ad5cc8657a 100644 --- a/kokoro/linux/python35_cpp/continuous.cfg +++ b/kokoro/linux/python35_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python35_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35_cpp/presubmit.cfg b/kokoro/linux/python35_cpp/presubmit.cfg index b1b0e550ff..ad5cc8657a 100644 --- a/kokoro/linux/python35_cpp/presubmit.cfg +++ b/kokoro/linux/python35_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python35_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36/continuous.cfg b/kokoro/linux/python36/continuous.cfg index e2fc4136f0..ee7f4888f8 100644 --- a/kokoro/linux/python36/continuous.cfg +++ b/kokoro/linux/python36/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python36/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36/presubmit.cfg b/kokoro/linux/python36/presubmit.cfg index e2fc4136f0..ee7f4888f8 100644 --- a/kokoro/linux/python36/presubmit.cfg +++ b/kokoro/linux/python36/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python36/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36_cpp/continuous.cfg b/kokoro/linux/python36_cpp/continuous.cfg index b1b0e550ff..df9e714494 100644 --- a/kokoro/linux/python36_cpp/continuous.cfg +++ b/kokoro/linux/python36_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python36_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36_cpp/presubmit.cfg b/kokoro/linux/python36_cpp/presubmit.cfg index b1b0e550ff..df9e714494 100644 --- a/kokoro/linux/python36_cpp/presubmit.cfg +++ b/kokoro/linux/python36_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python36_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37/continuous.cfg b/kokoro/linux/python37/continuous.cfg index e2fc4136f0..9fa20c1975 100644 --- a/kokoro/linux/python37/continuous.cfg +++ b/kokoro/linux/python37/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python37/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37/presubmit.cfg b/kokoro/linux/python37/presubmit.cfg index e2fc4136f0..9fa20c1975 100644 --- a/kokoro/linux/python37/presubmit.cfg +++ b/kokoro/linux/python37/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python37/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37_cpp/continuous.cfg b/kokoro/linux/python37_cpp/continuous.cfg index b1b0e550ff..49c441ffe8 100644 --- a/kokoro/linux/python37_cpp/continuous.cfg +++ b/kokoro/linux/python37_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python37_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37_cpp/presubmit.cfg b/kokoro/linux/python37_cpp/presubmit.cfg index b1b0e550ff..49c441ffe8 100644 --- a/kokoro/linux/python37_cpp/presubmit.cfg +++ b/kokoro/linux/python37_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python37_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38/continuous.cfg b/kokoro/linux/python38/continuous.cfg index e2fc4136f0..76425d2f19 100644 --- a/kokoro/linux/python38/continuous.cfg +++ b/kokoro/linux/python38/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python38/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38/presubmit.cfg b/kokoro/linux/python38/presubmit.cfg index e2fc4136f0..76425d2f19 100644 --- a/kokoro/linux/python38/presubmit.cfg +++ b/kokoro/linux/python38/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python38/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38_cpp/continuous.cfg b/kokoro/linux/python38_cpp/continuous.cfg index b1b0e550ff..1e8888cc5d 100644 --- a/kokoro/linux/python38_cpp/continuous.cfg +++ b/kokoro/linux/python38_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python38_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38_cpp/presubmit.cfg b/kokoro/linux/python38_cpp/presubmit.cfg index b1b0e550ff..1e8888cc5d 100644 --- a/kokoro/linux/python38_cpp/presubmit.cfg +++ b/kokoro/linux/python38_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python38_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/macos/php5.6_mac/build.sh b/kokoro/macos/php5.6_mac/build.sh deleted file mode 100755 index 74878898fa..0000000000 --- a/kokoro/macos/php5.6_mac/build.sh +++ /dev/null @@ -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 diff --git a/kokoro/macos/php5.6_mac/continuous.cfg b/kokoro/macos/php5.6_mac/continuous.cfg deleted file mode 100644 index ff345e9fc4..0000000000 --- a/kokoro/macos/php5.6_mac/continuous.cfg +++ /dev/null @@ -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 diff --git a/kokoro/macos/php5.6_mac/presubmit.cfg b/kokoro/macos/php5.6_mac/presubmit.cfg deleted file mode 100644 index ff345e9fc4..0000000000 --- a/kokoro/macos/php5.6_mac/presubmit.cfg +++ /dev/null @@ -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 diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index b2a03063f5..7cd16699c7 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -356,14 +356,14 @@ static PROTO_RETURN_VAL Message_write_property( } upb_msg_set(intern->msg, f, msgval, arena); -#if PHP_VERSION_ID < 704000 +#if PHP_VERSION_ID < 70400 return; #else return val; #endif error: -#if PHP_VERSION_ID < 704000 +#if PHP_VERSION_ID < 70400 return; #else return &EG(error_zval); diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index 037fa90d93..e0d25c87c5 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -10,11 +10,11 @@ protobuf-opensource@google.com yes - 2020-08-14 + 2020-10-08 - 3.13.0 - 3.13.0 + 3.13.0.1 + 3.13.0.1 stable @@ -675,5 +675,19 @@ G A release. 3-Clause BSD License GA release. + + + 3.13.0.1 + 3.13.0.1 + + + stable + stable + + 2020-10-08 + + 3-Clause BSD License + GA release. + diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 3188fe7dcb..195e2a7971 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -56,7 +56,7 @@ const zval *get_generated_pool(); // 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 #if PHP_VERSION_ID < 80000 -#define PROTO_VAL zval +#define PROTO_VAL zval #define PROTO_STR zval #define PROTO_MSG_P(obj) (Message*)Z_OBJ_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) #endif -#define PHP_PROTOBUF_VERSION "3.13.0" +#define PHP_PROTOBUF_VERSION "3.13.0.1" // ptr -> PHP object cache. This is a weak map that caches lazily-created // wrapper objects around upb types: diff --git a/php/release.sh b/php/release.sh index ec9ec0eeb3..6b0baac78f 100755 --- a/php/release.sh +++ b/php/release.sh @@ -10,8 +10,8 @@ set -ex VERSION=$1 -git clone git@github.com:protocolbuffers/protobuf-php.git -git clone git@github.com:protocolbuffers/protobuf.git +git clone https://github.com/protocolbuffers/protobuf-php.git +git clone https://github.com/protocolbuffers/protobuf.git # Clean old files pushd protobuf-php diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index b7d73859fa..0301e9634d 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -809,7 +809,7 @@ bool CheckAndSetString( return false; } - string value_string(value, value_len); + std::string value_string(value, value_len); if (append) { reflection->AddString(message, descriptor, std::move(value_string)); } else if (index < 0) { diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py index 2a9a866420..c2bec1cc6b 100644 --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -883,7 +883,8 @@ class _Parser(object): (expanded_any_end_token,)) self._MergeField(tokenizer, expanded_any_sub_message) message.Pack(expanded_any_sub_message, - type_url_prefix=type_url_prefix) + type_url_prefix=type_url_prefix, + deterministic=True) return if tokenizer.TryConsume('['): diff --git a/python/protobuf_distutils/README.md b/python/protobuf_distutils/README.md index 2989b2ad54..63d12b5200 100644 --- a/python/protobuf_distutils/README.md +++ b/python/protobuf_distutils/README.md @@ -103,4 +103,19 @@ $ python -m pip install . By default, the protoc binary (the Protobuf compiler) is found by searching the environment path. To use a specific protoc binary, its - path can be specified. + path can be specified. Resolution of the `protoc` value is as follows: + 1. If the `--protoc=VALUE` flag is passed to `generate_py_protobufs`, + then `VALUE` will be used. + For example: + ```shell + $ python setup.py generate_py_protobufs --protoc=/path/to/protoc + ``` + 2. Otherwise, if a value was set in the `options`, it will be used. + (See "Example setup.py configuration," above.) + 3. Otherwise, if the `PROTOC` environment variable is set, it will be + used. For example: + For example: + ```shell + $ PROTOC=/path/to/protoc python setup.py generate_py_protobufs + ``` + 4. Otherwise, `$PATH` will be searched. diff --git a/python/tox.ini b/python/tox.ini index 999f8ceeb8..56be1258ae 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -14,7 +14,10 @@ setenv = commands = python setup.py -q build_py python: python setup.py -q build - cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension + # --warnings_as_errors disabled until we update the Python C extension. See: + # https://github.com/protocolbuffers/protobuf/issues/7930 + # cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension + cpp: python setup.py -q build --cpp_implementation --compile_static_extension python: python setup.py -q test -q cpp: python setup.py -q test -q --cpp_implementation python: python setup.py -q test_conformance diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h index 16a68ca687..e8f2cacf16 100644 --- a/src/google/protobuf/any.h +++ b/src/google/protobuf/any.h @@ -60,7 +60,8 @@ class PROTOBUF_EXPORT AnyMetadata { typedef ArenaStringPtr ValueType; public: // AnyMetadata does not take ownership of "type_url" and "value". - AnyMetadata(UrlType* type_url, ValueType* value); + constexpr AnyMetadata(UrlType* type_url, ValueType* value) + : type_url_(type_url), value_(value) {} // Packs a message using the default type URL prefix: "type.googleapis.com". // The resulted type URL will be "type.googleapis.com/". diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc index 7501969da5..ffb2692135 100644 --- a/src/google/protobuf/any_lite.cc +++ b/src/google/protobuf/any_lite.cc @@ -53,9 +53,6 @@ const char kAnyFullTypeName[] = "google.protobuf.Any"; const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/"; const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/"; -AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value) - : type_url_(type_url), value_(value) {} - void AnyMetadata::InternalPackFrom(const MessageLite& message, StringPiece type_url_prefix, StringPiece type_name) { diff --git a/src/google/protobuf/any_test.cc b/src/google/protobuf/any_test.cc index 0d8893f7b8..8aeab7602b 100644 --- a/src/google/protobuf/any_test.cc +++ b/src/google/protobuf/any_test.cc @@ -33,10 +33,18 @@ #include +// Must be included last. +#include + namespace google { namespace protobuf { namespace { +TEST(AnyMetadataTest, ConstInit) { + PROTOBUF_CONSTINIT static internal::AnyMetadata metadata(nullptr, nullptr); + (void)metadata; +} + TEST(AnyTest, TestPackAndUnpack) { protobuf_unittest::TestAny submessage; submessage.set_int32_value(12345); diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index fce59b2545..631a08e0ce 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -47,6 +47,10 @@ static const size_t kMaxCleanupListElements = 64; // 1kB on 64-bit. namespace google { namespace protobuf { + +PROTOBUF_EXPORT /*static*/ void* (*const ArenaOptions::kDefaultBlockAlloc)( + size_t) = &::operator new; + namespace internal { const size_t ArenaImpl::kBlockHeaderSize; @@ -54,7 +58,7 @@ const size_t ArenaImpl::kSerialArenaSize; const size_t ArenaImpl::kOptionsSize; -std::atomic ArenaImpl::lifecycle_id_generator_; +ArenaImpl::CacheAlignedLifecycleIdGenerator ArenaImpl::lifecycle_id_generator_; #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { static internal::ThreadLocalStorage* thread_cache_ = @@ -63,12 +67,13 @@ ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { } #elif defined(PROTOBUF_USE_DLLS) ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { - static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = {-1, NULL}; + static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = { + 0, static_cast(-1), nullptr}; return thread_cache_; } #else -PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, - NULL}; +PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = { + 0, static_cast(-1), nullptr}; #endif void ArenaFree(void* object, size_t size) { @@ -122,9 +127,26 @@ ArenaImpl::ArenaImpl(const ArenaOptions& options) { } void ArenaImpl::Init(bool record_allocs) { + ThreadCache& tc = thread_cache(); + auto id = tc.next_lifecycle_id; + constexpr uint64 kInc = ThreadCache::kPerThreadIds * 2; + if (PROTOBUF_PREDICT_FALSE((id & (kInc - 1)) == 0)) { + if (sizeof(lifecycle_id_generator_.id) == 4) { + // 2^32 is dangerous low to guarantee uniqueness. If we start dolling out + // unique id's in ranges of kInc it's unacceptably low. In this case + // we increment by 1. The additional range of kPerThreadIds that are used + // per thread effectively pushes the overflow time from weeks to years + // of continuous running. + id = lifecycle_id_generator_.id.fetch_add(1, std::memory_order_relaxed) * + kInc; + } else { + id = + lifecycle_id_generator_.id.fetch_add(kInc, std::memory_order_relaxed); + } + } + tc.next_lifecycle_id = id + 2; // We store "record_allocs" in the low bit of lifecycle_id_. - auto id = lifecycle_id_generator_.fetch_add(1, std::memory_order_relaxed); - lifecycle_id_ = (id << 1) | (record_allocs ? 1 : 0); + lifecycle_id_ = id | (record_allocs ? 1 : 0); hint_.store(nullptr, std::memory_order_relaxed); threads_.store(nullptr, std::memory_order_relaxed); space_allocated_.store(0, std::memory_order_relaxed); diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 7c5c7d00bd..8ab4fc8e1b 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -142,10 +142,12 @@ struct ArenaOptions { max_block_size(kDefaultMaxBlockSize), initial_block(NULL), initial_block_size(0), - block_alloc(&::operator new), + block_alloc(kDefaultBlockAlloc), block_dealloc(&internal::ArenaFree), make_metrics_collector(nullptr) {} + PROTOBUF_EXPORT static void* (*const kDefaultBlockAlloc)(size_t); + private: // If make_metrics_collector is not nullptr, it will be called at Arena init // time. It may return a pointer to a collector instance that will be notified diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index 56ef7e1a55..ec86daba20 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h @@ -58,7 +58,7 @@ inline size_t AlignUpTo8(size_t n) { return (n + 7) & static_cast(-8); } -using LifecycleId = int64_t; +using LifecycleIdAtomic = uint64_t; void PROTOBUF_EXPORT ArenaFree(void* object, size_t size); @@ -328,20 +328,43 @@ class PROTOBUF_EXPORT ArenaImpl { ArenaMetricsCollector* metrics_collector; }; - struct ThreadCache { +#ifdef _MSC_VER +#pragma warning(disable:4324) +#endif + struct alignas(64) ThreadCache { #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) // If we are using the ThreadLocalStorage class to store the ThreadCache, // then the ThreadCache's default constructor has to be responsible for // initializing it. - ThreadCache() : last_lifecycle_id_seen(-1), last_serial_arena(NULL) {} + ThreadCache() + : next_lifecycle_id(0), + last_lifecycle_id_seen(-1), + last_serial_arena(NULL) {} #endif + // Number of per-thread lifecycle IDs to reserve. Must be power of two. + // To reduce contention on a global atomic, each thread reserves a batch of + // IDs. The following number is caluculated based on a stress test with + // ~6500 threads all frequently allocating a new arena. + static constexpr size_t kPerThreadIds = 256; + // Next lifecycle ID available to this thread. We need to reserve a new + // batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`. + uint64 next_lifecycle_id; // The ThreadCache is considered valid as long as this matches the // lifecycle_id of the arena being used. - LifecycleId last_lifecycle_id_seen; + uint64 last_lifecycle_id_seen; SerialArena* last_serial_arena; }; - static std::atomic 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 id; + }; + static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_; #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) // Android ndk does not support __thread keyword so we use a custom thread // local storage class we implemented. @@ -430,7 +453,7 @@ class PROTOBUF_EXPORT ArenaImpl { // Unique for each arena. Changes on Reset(). // Least-significant-bit is 1 iff allocations should be recorded. - LifecycleId lifecycle_id_; + uint64 lifecycle_id_; Options* options_ = nullptr; diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index e23459f7c2..60307b2763 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -87,22 +87,27 @@ class PROTOBUF_EXPORT LazyString { template class TaggedPtr { public: + TaggedPtr() = default; + explicit constexpr TaggedPtr(const std::string* ptr) + : ptr_(const_cast(ptr)) {} + void SetTagged(T* p) { Set(p); - ptr_ |= 1; + ptr_ = reinterpret_cast(as_int() | 1); } - void Set(T* p) { ptr_ = reinterpret_cast(p); } - T* Get() const { return reinterpret_cast(ptr_ & -2); } - bool IsTagged() const { return ptr_ & 1; } + void Set(T* p) { ptr_ = p; } + T* Get() const { return reinterpret_cast(as_int() & -2); } + bool IsTagged() const { return as_int() & 1; } // Returned value is only safe to dereference if IsTagged() == false. // It is safe to compare. - T* UnsafeGet() const { return reinterpret_cast(ptr_); } + T* UnsafeGet() const { return static_cast(ptr_); } - bool IsNull() { return ptr_ == 0; } + bool IsNull() { return ptr_ == nullptr; } private: - uintptr_t ptr_; + uintptr_t as_int() const { return reinterpret_cast(ptr_); } + void* ptr_; }; static_assert(std::is_trivial>::value, @@ -165,9 +170,9 @@ static_assert(std::is_trivial>::value, // single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also // requires the String tag to be 0 so we can avoid the mask before comparing.) struct PROTOBUF_EXPORT ArenaStringPtr { - // No default constructor or destructor -- we have to be POD because we go - // into a union when used in a oneof. Message code calls UnsafeReset() to zero - // the pointer when necessary instead. + ArenaStringPtr() = default; + explicit constexpr ArenaStringPtr(const std::string* default_value) + : tagged_ptr_(default_value) {} // Some methods below are overloaded on a `default_value` and on tags. // The tagged overloads help reduce code size in the callers in generated diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc index 07e7c650dd..321b45140f 100644 --- a/src/google/protobuf/arenastring_unittest.cc +++ b/src/google/protobuf/arenastring_unittest.cc @@ -45,6 +45,9 @@ #include +// Must be included last. +#include + namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index f5d88e5022..1987e08268 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -123,7 +124,7 @@ class CommandLineInterfaceTest : public testing::Test { void SwitchToTempDirectory() { File::ChangeWorkingDirectory(temp_directory_); } -#else // !PROTOBUF_OPENSOURCE +#else // !PROTOBUF_OPENSOURCE // TODO(teboring): Figure out how to change and get working directory in // google3. #endif // !PROTOBUF_OPENSOURCE @@ -681,6 +682,9 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs_UnusedImport_DescriptorSetIn) { FileDescriptorProto::descriptor()->file(); descriptor_file->CopyTo(file_descriptor_set.add_file()); + FileDescriptorProto& any_proto = *file_descriptor_set.add_file(); + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + const FileDescriptor* custom_file = protobuf_unittest::AggregateMessage::descriptor()->file(); FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index 5b2f276697..2d11f907bc 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -164,10 +164,6 @@ class FieldGenerator { return false; } - // Generate code that allocates the fields's default instance. - virtual void GenerateDefaultInstanceAllocator( - io::Printer* /*printer*/) const {} - // Generate lines to serialize this field directly to the array "target", // which are placed within the message's SerializeWithCachedSizesToArray() // method. This must also advance "target" past the written bytes. diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 1e3d2dad54..875beec9f6 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -941,7 +941,6 @@ void FileGenerator::GenerateInitForSCC(const SCC* scc, if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) { continue; } - message_generators_[i]->GenerateFieldDefaultInstances(printer); format( "{\n" " void* ptr = &$1$;\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index c6ab9ac5f9..7c17e456d0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -1895,13 +1895,6 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { return num_field_metadata; } -void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) { - // Construct the default instances for all fields that need one. - for (auto field : FieldRange(descriptor_)) { - field_generators_.get(field).GenerateDefaultInstanceAllocator(printer); - } -} - void MessageGenerator::GenerateClassMethods(io::Printer* printer) { Formatter format(printer, variables_); if (IsMapEntryMessage(descriptor_)) { diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index 0bc32b46c0..933386fbd5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -82,9 +82,6 @@ class MessageGenerator { // Source file stuff. - // Generates code that creates default instances for fields. - void GenerateFieldDefaultInstances(io::Printer* printer); - // Generate all non-inline methods for this class. void GenerateClassMethods(io::Printer* printer); diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index 2fc7aadff6..bb378b897c 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -390,6 +390,7 @@ void FileGenerator::Generate(io::Printer* printer) { printer->Print("}\n"); } + void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( io::Printer* printer) { printer->Print( diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h index bb3e4a5765..9f1f719237 100644 --- a/src/google/protobuf/compiler/java/java_file.h +++ b/src/google/protobuf/compiler/java/java_file.h @@ -78,6 +78,7 @@ class FileGenerator { void Generate(io::Printer* printer); + // If we aren't putting everything into one file, this will write all the // files other than the outer file (i.e. one for each message, enum, and // service type). diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc index d998f166a3..bc13dd8733 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.cc +++ b/src/google/protobuf/compiler/java/java_name_resolver.cc @@ -160,7 +160,14 @@ std::string ClassNameResolver::GetFileImmutableClassName( std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file, bool immutable) { - if (immutable) { + return GetFileClassName(file, immutable, false); +} + +std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file, + bool immutable, bool kotlin) { + if (kotlin) { + return GetFileImmutableClassName(file) + "Kt"; + } else if (immutable) { return GetFileImmutableClassName(file); } else { return "Mutable" + GetFileImmutableClassName(file); @@ -200,9 +207,14 @@ std::string ClassNameResolver::GetDescriptorClassName( std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, + bool immutable, bool kotlin) { std::string result = FileJavaPackage(descriptor, immutable); if (!result.empty()) result += '.'; - result += GetFileClassName(descriptor, immutable); + result += GetFileClassName(descriptor, immutable, kotlin); return result; } @@ -211,50 +223,79 @@ std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, std::string ClassNameResolver::GetClassFullName( const std::string& name_without_package, const FileDescriptor* file, bool immutable, bool is_own_file) { + return GetClassFullName(name_without_package, file, immutable, is_own_file, + false); +} + +std::string ClassNameResolver::GetClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable, bool is_own_file, bool kotlin) { std::string result; if (is_own_file) { result = FileJavaPackage(file, immutable); } else { - result = GetClassName(file, immutable); + result = GetClassName(file, immutable, kotlin); } if (!result.empty()) { result += '.'; } result += name_without_package; + if (kotlin) result += "Kt"; return result; } std::string ClassNameResolver::GetClassName(const Descriptor* descriptor, bool immutable) { - return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), - descriptor->file(), immutable, - MultipleJavaFiles(descriptor->file(), immutable)); + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const Descriptor* descriptor, + bool immutable, bool kotlin) { + return GetClassFullName( + ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), + immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin); } std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor, bool immutable) { - return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), - descriptor->file(), immutable, - MultipleJavaFiles(descriptor->file(), immutable)); + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor, + bool immutable, bool kotlin) { + return GetClassFullName( + ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), + immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin); } std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor, bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor, + bool immutable, bool kotlin) { return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), immutable, - IsOwnFile(descriptor, immutable)); + IsOwnFile(descriptor, immutable), kotlin); } // Get the Java Class style full name of a message. std::string ClassNameResolver::GetJavaClassFullName( const std::string& name_without_package, const FileDescriptor* file, bool immutable) { + return GetJavaClassFullName(name_without_package, file, immutable, false); +} + +std::string ClassNameResolver::GetJavaClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable, bool kotlin) { std::string result; if (MultipleJavaFiles(file, immutable)) { result = FileJavaPackage(file, immutable); if (!result.empty()) result += '.'; } else { - result = GetClassName(file, immutable); + result = GetClassName(file, immutable, kotlin); if (!result.empty()) result += '$'; } result += StringReplace(name_without_package, ".", "$", true); @@ -263,7 +304,12 @@ std::string ClassNameResolver::GetJavaClassFullName( std::string ClassNameResolver::GetExtensionIdentifierName( const FieldDescriptor* descriptor, bool immutable) { - return GetClassName(descriptor->containing_type(), immutable) + "." + + return GetExtensionIdentifierName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetExtensionIdentifierName( + const FieldDescriptor* descriptor, bool immutable, bool kotlin) { + return GetClassName(descriptor->containing_type(), immutable, kotlin) + "." + descriptor->name(); } diff --git a/src/google/protobuf/compiler/java/java_name_resolver.h b/src/google/protobuf/compiler/java/java_name_resolver.h index b92570c600..8461df9009 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.h +++ b/src/google/protobuf/compiler/java/java_name_resolver.h @@ -60,6 +60,8 @@ class ClassNameResolver { // Gets the unqualified outer class name for the file. std::string GetFileClassName(const FileDescriptor* file, bool immutable); + std::string GetFileClassName(const FileDescriptor* file, bool immutable, + bool kotlin); // Gets the unqualified immutable outer class name of a file. std::string GetFileImmutableClassName(const FileDescriptor* file); // Gets the unqualified default immutable outer class name of a file @@ -80,9 +82,17 @@ class ClassNameResolver { // Gets the fully-qualified class name corresponding to the given descriptor. std::string GetClassName(const Descriptor* descriptor, bool immutable); + std::string GetClassName(const Descriptor* descriptor, bool immutable, + bool kotlin); std::string GetClassName(const EnumDescriptor* descriptor, bool immutable); + std::string GetClassName(const EnumDescriptor* descriptor, bool immutable, + bool kotlin); std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable); + std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable, + bool kotlin); std::string GetClassName(const FileDescriptor* descriptor, bool immutable); + std::string GetClassName(const FileDescriptor* descriptor, bool immutable, + bool kotlin); template std::string GetImmutableClassName(const DescriptorType* descriptor) { @@ -96,6 +106,8 @@ class ClassNameResolver { // Gets the fully qualified name of an extension identifier. std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor, bool immutable); + std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor, + bool immutable, bool kotlin); // Gets the fully qualified name for generated classes in Java convention. // Nested classes will be separated using '$' instead of '.' @@ -109,9 +121,15 @@ class ClassNameResolver { std::string GetClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable, bool is_own_file); + std::string GetClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable, + bool is_own_file, bool kotlin); // Get the Java Class style full name of a message. std::string GetJavaClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable); + std::string GetJavaClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable, + bool kotlin); // Caches the result to provide better performance. std::map file_immutable_outer_class_names_; diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index a702ca9495..895b47dee6 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -65,6 +65,7 @@ int ProtobufMain(int argc, char* argv[]) { "Generate Java source file."); + // Proto2 Python python::Generator py_generator; cli.RegisterGenerator("--python_out", "--python_opt", &py_generator, diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index 4a3a228e89..cbb24a50a5 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -2276,6 +2277,11 @@ TEST_F(ParseDescriptorDebugTest, TestCustomOptions) { FileDescriptorProto import_proto; import->CopyTo(&import_proto); ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); + + FileDescriptorProto any_import; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_import); + ASSERT_TRUE(pool_.BuildFile(any_import) != nullptr); + const FileDescriptor* actual = pool_.BuildFile(parsed); ASSERT_TRUE(actual != NULL); parsed.Clear(); diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index d1d0828b58..179df8f5dd 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -254,14 +255,14 @@ std::string ToCamelCase(const std::string& input, bool lower_first) { std::string result; result.reserve(input.size()); - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { + for (char character : input) { + if (character == '_') { capitalize_next = true; } else if (capitalize_next) { - result.push_back(ToUpper(input[i])); + result.push_back(ToUpper(character)); capitalize_next = false; } else { - result.push_back(input[i]); + result.push_back(character); } } @@ -278,14 +279,14 @@ std::string ToJsonName(const std::string& input) { std::string result; result.reserve(input.size()); - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { + for (char character : input) { + if (character == '_') { capitalize_next = true; } else if (capitalize_next) { - result.push_back(ToUpper(input[i])); + result.push_back(ToUpper(character)); capitalize_next = false; } else { - result.push_back(input[i]); + result.push_back(character); } } @@ -297,14 +298,14 @@ std::string EnumValueToPascalCase(const std::string& input) { std::string result; result.reserve(input.size()); - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { + for (char character : input) { + if (character == '_') { next_upper = true; } else { if (next_upper) { - result.push_back(ToUpper(input[i])); + result.push_back(ToUpper(character)); } else { - result.push_back(ToLower(input[i])); + result.push_back(ToLower(character)); } next_upper = false; } @@ -318,9 +319,9 @@ class PrefixRemover { public: PrefixRemover(StringPiece prefix) { // Strip underscores and lower-case the prefix. - for (int i = 0; i < prefix.size(); i++) { - if (prefix[i] != '_') { - prefix_ += ascii_tolower(prefix[i]); + for (char character : prefix) { + if (character != '_') { + prefix_ += ascii_tolower(character); } } } @@ -471,16 +472,15 @@ std::set* NewAllowedProto3Extendee() { const char* kOptionNames[] = { "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions", "EnumValueOptions", "ServiceOptions", "MethodOptions", "OneofOptions"}; - for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) { + for (const char* option_name : kOptionNames) { // descriptor.proto has a different package name in opensource. We allow // both so the opensource protocol compiler can also compile internal // proto3 files with custom options. See: b/27567912 allowed_proto3_extendees->insert(std::string("google.protobuf.") + - kOptionNames[i]); + option_name); // Split the word to trick the opensource processing scripts so they // will keep the original package name. - allowed_proto3_extendees->insert(std::string("proto") + "2." + - kOptionNames[i]); + allowed_proto3_extendees->insert(std::string("proto") + "2." + option_name); } return allowed_proto3_extendees; } @@ -1571,8 +1571,7 @@ void DescriptorPool::FindAllExtensions( std::vector numbers; if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), &numbers)) { - for (int i = 0; i < numbers.size(); ++i) { - int number = numbers[i]; + for (int number : numbers) { if (tables_->FindExtension(extendee, number) == nullptr) { TryFindExtensionInFallbackDatabase(extendee, number); } @@ -2279,34 +2278,34 @@ bool RetrieveOptionsAssumingRightPool( const Reflection* reflection = options.GetReflection(); std::vector fields; reflection->ListFields(options, &fields); - for (int i = 0; i < fields.size(); i++) { + for (const FieldDescriptor* field : fields) { int count = 1; bool repeated = false; - if (fields[i]->is_repeated()) { - count = reflection->FieldSize(options, fields[i]); + if (field->is_repeated()) { + count = reflection->FieldSize(options, field); repeated = true; } for (int j = 0; j < count; j++) { std::string fieldval; - if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { std::string tmp; TextFormat::Printer printer; printer.SetInitialIndentLevel(depth + 1); - printer.PrintFieldValueToString(options, fields[i], repeated ? j : -1, + printer.PrintFieldValueToString(options, field, repeated ? j : -1, &tmp); fieldval.append("{\n"); fieldval.append(tmp); fieldval.append(depth * 2, ' '); fieldval.append("}"); } else { - TextFormat::PrintFieldValueToString(options, fields[i], - repeated ? j : -1, &fieldval); + TextFormat::PrintFieldValueToString(options, field, repeated ? j : -1, + &fieldval); } std::string name; - if (fields[i]->is_extension()) { - name = "(." + fields[i]->full_name() + ")"; + if (field->is_extension()) { + name = "(." + field->full_name() + ")"; } else { - name = fields[i]->name(); + name = field->name(); } option_entries->push_back(name + " = " + fieldval); } @@ -2363,9 +2362,8 @@ bool FormatLineOptions(int depth, const Message& options, std::string prefix(depth * 2, ' '); std::vector all_options; if (RetrieveOptions(depth, options, pool, &all_options)) { - for (int i = 0; i < all_options.size(); i++) { - strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, - all_options[i]); + for (const std::string& option : all_options) { + strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, option); } } return !all_options.empty(); @@ -2395,8 +2393,9 @@ class SourceLocationCommentPrinter { void AddPreComment(std::string* output) { if (have_source_loc_) { // Detached leading comments. - for (int i = 0; i < source_loc_.leading_detached_comments.size(); ++i) { - *output += FormatComment(source_loc_.leading_detached_comments[i]); + for (const std::string& leading_detached_comment : + source_loc_.leading_detached_comments) { + *output += FormatComment(leading_detached_comment); *output += "\n"; } // Attached leading comments. @@ -2418,8 +2417,7 @@ class SourceLocationCommentPrinter { StripWhitespace(&stripped_comment); std::vector lines = Split(stripped_comment, "\n"); std::string output; - for (int i = 0; i < lines.size(); ++i) { - const std::string& line = lines[i]; + for (const std::string& line : lines) { strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line); } return output; @@ -3866,13 +3864,13 @@ Symbol DescriptorBuilder::LookupSymbol( static bool ValidateQualifiedName(StringPiece name) { bool last_was_period = false; - for (int i = 0; i < name.size(); i++) { + for (char character : name) { // I don't trust isalnum() due to locales. :( - if (('a' <= name[i] && name[i] <= 'z') || - ('A' <= name[i] && name[i] <= 'Z') || - ('0' <= name[i] && name[i] <= '9') || (name[i] == '_')) { + if (('a' <= character && character <= 'z') || + ('A' <= character && character <= 'Z') || + ('0' <= character && character <= '9') || (character == '_')) { last_was_period = false; - } else if (name[i] == '.') { + } else if (character == '.') { if (last_was_period) return false; last_was_period = true; } else { @@ -4096,11 +4094,11 @@ void DescriptorBuilder::ValidateSymbolName(const std::string& name, AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, "Missing name."); } else { - for (int i = 0; i < name.size(); i++) { + for (char character : name) { // I don't trust isalnum() due to locales. :( - if ((name[i] < 'a' || 'z' < name[i]) && - (name[i] < 'A' || 'Z' < name[i]) && - (name[i] < '0' || '9' < name[i]) && (name[i] != '_')) { + if ((character < 'a' || 'z' < character) && + (character < 'A' || 'Z' < character) && + (character < '0' || '9' < character) && (character != '_')) { AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, "\"" + name + "\" is not a valid identifier."); } @@ -5945,12 +5943,12 @@ void DescriptorBuilder::ValidateProto3(FileDescriptor* file, static std::string ToLowercaseWithoutUnderscores(const std::string& name) { std::string result; - for (int i = 0; i < name.size(); ++i) { - if (name[i] != '_') { - if (name[i] >= 'A' && name[i] <= 'Z') { - result.push_back(name[i] - 'A' + 'a'); + for (char character : name) { + if (character != '_') { + if (character >= 'A' && character <= 'Z') { + result.push_back(character - 'A' + 'a'); } else { - result.push_back(name[i]); + result.push_back(character); } } } @@ -7067,6 +7065,18 @@ class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder public: DescriptorBuilder* builder_; + const Descriptor* FindAnyType(const Message& message, + const std::string& prefix, + const std::string& name) const override { + if (prefix != internal::kTypeGoogleApisComPrefix && + prefix != internal::kTypeGoogleProdComPrefix) { + return nullptr; + } + assert_mutex_held(builder_->pool_); + Symbol result = builder_->FindSymbol(name); + return result.type == Symbol::MESSAGE ? result.descriptor : nullptr; + } + const FieldDescriptor* FindExtension(Message* message, const std::string& name) const override { assert_mutex_held(builder_->pool_); diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index 2707ed4b58..92f2732033 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc @@ -552,11 +552,9 @@ class EncodedDescriptorDatabase::DescriptorIndex { bool EncodedDescriptorDatabase::Add(const void* encoded_file_descriptor, int size) { - google::protobuf::Arena arena; - auto* file = google::protobuf::Arena::CreateMessage(&arena); - if (file->ParseFromArray(encoded_file_descriptor, size)) { - return index_->AddFile(*file, - std::make_pair(encoded_file_descriptor, size)); + FileDescriptorProto file; + if (file.ParseFromArray(encoded_file_descriptor, size)) { + return index_->AddFile(file, std::make_pair(encoded_file_descriptor, size)); } else { GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to " "EncodedDescriptorDatabase::Add()."; @@ -933,8 +931,8 @@ bool DescriptorPoolDatabase::FindAllExtensionNumbers( std::vector extensions; pool_.FindAllExtensions(extendee, &extensions); - for (int i = 0; i < extensions.size(); ++i) { - output->push_back(extensions[i]->number()); + for (const FieldDescriptor* extension : extensions) { + output->push_back(extension->number()); } return true; @@ -954,8 +952,8 @@ MergedDescriptorDatabase::~MergedDescriptorDatabase() {} bool MergedDescriptorDatabase::FindFileByName(const std::string& filename, FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindFileByName(filename, output)) { + for (DescriptorDatabase* source : sources_) { + if (source->FindFileByName(filename, output)) { return true; } } @@ -1012,8 +1010,8 @@ bool MergedDescriptorDatabase::FindAllExtensionNumbers( std::vector results; bool success = false; - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) { + for (DescriptorDatabase* source : sources_) { + if (source->FindAllExtensionNumbers(extendee_type, &results)) { std::copy(results.begin(), results.end(), std::insert_iterator >(merged_results, merged_results.begin())); diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 278b07f9f2..331a0c5b6f 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -287,9 +288,8 @@ class MockErrorCollector : public DescriptorPool::ErrorCollector { break; } - strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", - filename, element_name, location_name, - message); + strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", filename, + element_name, location_name, message); } }; @@ -3148,6 +3148,11 @@ TEST(CustomOptions, OptionsFromOtherFile) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + // We have to import the Any dependency. + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3206,6 +3211,10 @@ TEST(CustomOptions, MessageOptionThreeFieldsSet) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3283,6 +3292,10 @@ TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3363,6 +3376,10 @@ TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3463,6 +3480,10 @@ TEST(CustomOptions, AggregateOptions) { message_set_extension) .s()); + protobuf_unittest::AggregateMessageSetElement any_payload; + ASSERT_TRUE(file_options.any().UnpackTo(&any_payload)); + EXPECT_EQ("EmbeddedMessageSetElement", any_payload.s()); + // Simple tests for all the other types of annotations EXPECT_EQ("MessageAnnotation", msg->options().GetExtension(protobuf_unittest::msgopt).s()); @@ -3485,6 +3506,10 @@ TEST(CustomOptions, UnusedImportError) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -7182,8 +7207,8 @@ class SourceLocationTest : public testing::Test { static std::string PrintSourceLocation(const SourceLocation& loc) { return strings::Substitute("$0:$1-$2:$3", 1 + loc.start_line, - 1 + loc.start_column, 1 + loc.end_line, - 1 + loc.end_column); + 1 + loc.start_column, 1 + loc.end_line, + 1 + loc.end_column); } private: diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 0dcabb0f47..bfa1c42a88 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -192,14 +192,6 @@ ExtensionSet::ExtensionSet(Arena* arena) ? NULL : Arena::CreateArray(arena_, flat_capacity_)} {} -ExtensionSet::ExtensionSet() - : arena_(NULL), - flat_capacity_(0), - flat_size_(0), - map_{flat_capacity_ == 0 - ? NULL - : Arena::CreateArray(arena_, flat_capacity_)} {} - ExtensionSet::~ExtensionSet() { // Deletes all allocated extensions. if (arena_ == NULL) { diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index b30a9608af..b3a6e3a07b 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -173,7 +173,7 @@ class MessageSetFieldSkipper; // off to the ExtensionSet for parsing. Etc. class PROTOBUF_EXPORT ExtensionSet { public: - ExtensionSet(); + constexpr ExtensionSet(); explicit ExtensionSet(Arena* arena); ~ExtensionSet(); @@ -850,6 +850,9 @@ class PROTOBUF_EXPORT ExtensionSet { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); }; +constexpr ExtensionSet::ExtensionSet() + : arena_(nullptr), flat_capacity_(0), flat_size_(0), map_{nullptr} {} + // These are just for convenience... inline void ExtensionSet::SetString(int number, FieldType type, std::string value, diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index 3e6ecefe01..2c299c15ca 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -46,13 +46,15 @@ #include #include #include - #include #include #include #include #include +// Must be included last. +#include + namespace google { namespace protobuf { @@ -1324,6 +1326,11 @@ TEST(ExtensionSetTest, BoolExtension) { EXPECT_TRUE(msg.GetExtension(protobuf_unittest::optional_bool_extension)); } +TEST(ExtensionSetTest, ConstInit) { + PROTOBUF_CONSTINIT static ExtensionSet set{}; + EXPECT_EQ(set.NumExtensions(), 0); +} + } // namespace } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 3ff9315277..e8b19c862b 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -1065,6 +1065,7 @@ void Reflection::ListFieldsMayFailOnStripped( output->push_back(field); } } else if (has_bits && has_bits_indices[i] != -1) { + CheckInvalidAccess(schema_, field); // Equivalent to: HasBit(message, field) if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) { output->push_back(field); diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index aaeadc78ca..f1f6f88332 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -68,16 +68,25 @@ void DestroyString(const void* s) { static_cast(s)->~basic_string(); } -ExplicitlyConstructed fixed_address_empty_string; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT EmptyString + fixed_address_empty_string; // NOLINT +PROTOBUF_CONSTINIT std::atomic init_protobuf_defaults_state{false}; static bool InitProtobufDefaultsImpl() { - fixed_address_empty_string.DefaultConstruct(); - OnShutdownDestroyString(fixed_address_empty_string.get_mutable()); + ::new (static_cast(&fixed_address_empty_string.value)) std::string(); + OnShutdownDestroyString(&fixed_address_empty_string.value); + + // Verify that we can indeed get the address during constant evaluation. + PROTOBUF_CONSTINIT static const std::string& fixed_address_empty_string_test = + GetEmptyStringAlreadyInited(); + (void)fixed_address_empty_string_test; + + init_protobuf_defaults_state.store(true, std::memory_order_release); return true; } -void InitProtobufDefaults() { +void InitProtobufDefaultsSlow() { static bool is_inited = InitProtobufDefaultsImpl(); (void)is_inited; } diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 7cae4e1266..bae0c1f760 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -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 init_protobuf_defaults_state; +PROTOBUF_EXPORT void InitProtobufDefaultsSlow(); +PROTOBUF_EXPORT inline void InitProtobufDefaults() { + if (PROTOBUF_PREDICT_FALSE( + !init_protobuf_defaults_state.load(std::memory_order_acquire))) { + InitProtobufDefaultsSlow(); + } +} // This used by proto1 PROTOBUF_EXPORT inline const std::string& GetEmptyString() { diff --git a/src/google/protobuf/has_bits.h b/src/google/protobuf/has_bits.h index 540cac282f..1144b9f461 100644 --- a/src/google/protobuf/has_bits.h +++ b/src/google/protobuf/has_bits.h @@ -47,7 +47,7 @@ namespace internal { template class HasBits { public: - HasBits() PROTOBUF_ALWAYS_INLINE { Clear(); } + constexpr HasBits() PROTOBUF_ALWAYS_INLINE : has_bits_{} {} void Clear() PROTOBUF_ALWAYS_INLINE { memset(has_bits_, 0, sizeof(has_bits_)); diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h index ec028eb5cd..bfa6a813b3 100644 --- a/src/google/protobuf/implicit_weak_message.h +++ b/src/google/protobuf/implicit_weak_message.h @@ -129,7 +129,7 @@ class ImplicitWeakTypeHandler { template struct WeakRepeatedPtrField { using TypeHandler = internal::ImplicitWeakTypeHandler; - WeakRepeatedPtrField() : weak() {} + constexpr WeakRepeatedPtrField() : weak() {} explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {} ~WeakRepeatedPtrField() { weak.template Destroy(); } diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 29c370c24c..390455e8d8 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -105,8 +105,8 @@ class MapAllocator { using size_type = size_t; using difference_type = ptrdiff_t; - MapAllocator() : arena_(nullptr) {} - explicit MapAllocator(Arena* arena) : arena_(arena) {} + constexpr MapAllocator() : arena_(nullptr) {} + explicit constexpr MapAllocator(Arena* arena) : arena_(arena) {} template MapAllocator(const MapAllocator& allocator) // NOLINT(runtime/explicit) : arena_(allocator.arena()) {} @@ -382,7 +382,7 @@ class Map { using size_type = size_t; using hasher = typename internal::TransparentSupport::hash; - Map() : elements_(nullptr) {} + constexpr Map() : elements_(nullptr) {} explicit Map(Arena* arena) : elements_(arena) {} Map(const Map& other) : Map() { insert(other.begin(), other.end()); } @@ -450,11 +450,11 @@ class Map { // otherwise. This avoids unnecessary copies of string keys, for example. class InnerMap : private hasher { public: - explicit InnerMap(Arena* arena) + explicit constexpr InnerMap(Arena* arena) : hasher(), num_elements_(0), num_buckets_(internal::kGlobalEmptyTableSize), - seed_(Seed()), + seed_(0), index_of_first_non_null_(num_buckets_), table_(const_cast(internal::kGlobalEmptyTable)), alloc_(arena) {} @@ -919,6 +919,7 @@ class Map { // Just overwrite with a new one. No need to transfer or free anything. num_buckets_ = index_of_first_non_null_ = kMinTableSize; table_ = CreateEmptyTable(num_buckets_); + seed_ = Seed(); return; } diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 180ff0e70a..9e35795f9b 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -93,7 +93,7 @@ template { public: - MapEntry() : _internal_metadata_(NULL) {} + constexpr MapEntry() : _internal_metadata_() {} explicit MapEntry(Arena* arena) : MapEntryImpl(arena), diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 92cb4ac4d1..1caf59dfed 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -182,17 +182,16 @@ class MapEntryImpl : public Base { static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType; static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType; - MapEntryImpl() { - KeyTypeHandler::Initialize(&key_, NULL); - ValueTypeHandler::Initialize(&value_, NULL); - _has_bits_[0] = 0; - } + constexpr MapEntryImpl() + : key_(KeyTypeHandler::Constinit()), + value_(ValueTypeHandler::Constinit()), + _has_bits_{} {} - explicit MapEntryImpl(Arena* arena) : Base(arena) { - KeyTypeHandler::Initialize(&key_, arena); - ValueTypeHandler::Initialize(&value_, arena); - _has_bits_[0] = 0; - } + explicit MapEntryImpl(Arena* arena) + : Base(arena), + key_(KeyTypeHandler::Constinit()), + value_(ValueTypeHandler::Constinit()), + _has_bits_{} {} ~MapEntryImpl() { if (Base::GetArena() != NULL) return; @@ -523,7 +522,7 @@ class MapEntryLite : public MapEntryImpl SuperType; - MapEntryLite() {} + constexpr MapEntryLite() {} explicit MapEntryLite(Arena* arena) : SuperType(arena) {} ~MapEntryLite() { MessageLite::_internal_metadata_.Delete(); } void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); } diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index f4e034cd3d..9fbd06ade9 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -324,6 +324,16 @@ class PROTOBUF_EXPORT MapFieldBase { public: MapFieldBase() : arena_(NULL), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + // Except in MSVC, where we can't have a constinit mutex. + explicit PROTOBUF_MAYBE_CONSTEXPR MapFieldBase(ConstantInitialized) + : arena_(nullptr), + repeated_field_(nullptr), + mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED), + state_(STATE_MODIFIED_MAP) {} explicit MapFieldBase(Arena* arena) : arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) { // Mutex's destructor needs to be called explicitly to release resources @@ -466,6 +476,12 @@ template class TypeDefinedMapFieldBase : public MapFieldBase { public: TypeDefinedMapFieldBase() {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + explicit constexpr TypeDefinedMapFieldBase(ConstantInitialized tag) + : MapFieldBase(tag) {} explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {} ~TypeDefinedMapFieldBase() override {} void MapBegin(MapIterator* map_iter) const override; @@ -521,6 +537,12 @@ class MapField : public TypeDefinedMapFieldBase { typedef Map MapType; MapField() {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + explicit constexpr MapField(ConstantInitialized tag) + : TypeDefinedMapFieldBase(tag), impl_() {} explicit MapField(Arena* arena) : TypeDefinedMapFieldBase(arena), impl_(arena) {} diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h index a47b87710a..665cb0eebe 100644 --- a/src/google/protobuf/map_field_lite.h +++ b/src/google/protobuf/map_field_lite.h @@ -63,7 +63,7 @@ class MapFieldLite { typedef Map MapType; typedef EntryType EntryTypeTrait; - MapFieldLite() {} + constexpr MapFieldLite() {} explicit MapFieldLite(Arena* arena) : map_(arena) {} diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index 39544a3d24..f6274c0da3 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -45,6 +45,9 @@ #include #include +// Must be included last. +#include + namespace google { namespace protobuf { @@ -478,6 +481,22 @@ TEST_P(MapFieldStateTest, MutableMapField) { } } +class MyMapField + : public MapField { + public: + constexpr MyMapField() + : MyMapField::MapField(internal::ConstantInitialized{}) {} +}; + +TEST(MapFieldTest, ConstInit) { + // This tests that `MapField` and all its base classes can be constant + // initialized. + PROTOBUF_CONSTINIT static MyMapField field; // NOLINT + EXPECT_EQ(field.size(), 0); +} + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index f2a5b93b8b..9c53b510f4 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -80,6 +80,7 @@ #include +// Must be included last. #include namespace google { @@ -1180,6 +1181,11 @@ TEST_F(MapImplTest, TransparentLookupForString) { TestTransparent(std::cref(abc), std::cref(lkj)); } +TEST_F(MapImplTest, ConstInit) { + PROTOBUF_CONSTINIT static Map map; // NOLINT + EXPECT_TRUE(map.empty()); +} + // Map Field Reflection Test ======================================== static int Func(int i, int j) { return i * j; } @@ -2047,6 +2053,39 @@ TEST_F(MapFieldReflectionTest, UninitializedEntry) { EXPECT_FALSE(message.IsInitialized()); } +class MyMapEntry + : public internal::MapEntry { + 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 { + public: + constexpr MyMapEntryLite() {} + explicit MyMapEntryLite(Arena*) { std::abort(); } + static bool ValidateKey(void*) { return true; } + static bool ValidateValue(void*) { return true; } +}; + +TEST(MapEntryTest, ConstInit) { + // This verifies that `MapEntry`, `MapEntryLite` and `MapEntryImpl` can be + // constant initialized. + PROTOBUF_CONSTINIT static MyMapEntry entry{}; + EXPECT_NE(entry.SpaceUsed(), 0); + + PROTOBUF_CONSTINIT static MyMapEntryLite entry_lite{}; // NOLINT + EXPECT_TRUE(entry_lite.IsInitialized()); +} + // Generated Message Test =========================================== TEST(GeneratedMapFieldTest, Accessors) { diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index 9c1a5940e6..8b8fd14c2d 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -157,7 +157,7 @@ class MapTypeHandler { static inline void DeleteNoArena(const Type* x); static inline void Merge(const Type& from, Type** to, Arena* arena); static inline void Clear(Type** value, Arena* arena); - static inline void Initialize(Type** x, Arena* arena); + static constexpr TypeOnMemory Constinit(); static inline Type* EnsureMutable(Type** value, Arena* arena); // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding @@ -207,7 +207,7 @@ class MapTypeHandler { const TypeOnMemory& value); \ static inline bool IsInitialized(const TypeOnMemory& value); \ static void DeleteNoArena(TypeOnMemory& value); \ - static inline void Initialize(TypeOnMemory* value, Arena* arena); \ + static constexpr TypeOnMemory Constinit(); \ static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \ Arena* arena); \ }; @@ -522,9 +522,9 @@ void MapTypeHandler::DeleteNoArena( } template -inline void MapTypeHandler::Initialize( - Type** x, Arena* /* arena */) { - *x = NULL; +constexpr auto MapTypeHandler::Constinit() + -> TypeOnMemory { + return nullptr; } template @@ -583,10 +583,10 @@ inline bool MapTypeHandler::IsInitialized( value.DestroyNoArena(&internal::GetEmptyStringAlreadyInited()); \ } \ template \ - inline void \ - MapTypeHandler::Initialize( \ - TypeOnMemory* value, Arena* /* arena */) { \ - value->UnsafeSetDefault(&internal::GetEmptyStringAlreadyInited()); \ + constexpr auto \ + MapTypeHandler::Constinit() \ + ->TypeOnMemory { \ + return TypeOnMemory(&internal::GetEmptyStringAlreadyInited()); \ } \ template \ inline typename MapTypeHandler::DeleteNoArena(TypeOnMemory& /* x */) {} \ template \ - inline void \ - MapTypeHandler::Initialize( \ - TypeOnMemory* value, Arena* /* arena */) { \ - *value = 0; \ + constexpr auto \ + MapTypeHandler::Constinit() \ + ->TypeOnMemory { \ + return 0; \ } \ template \ inline typename MapTypeHandlerSpaceUsedLong(*this); } -size_t Message::GetInvariantPerBuild(size_t salt) { +uint64 Message::GetInvariantPerBuild(uint64 salt) { return salt; } diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 8f5fef1220..4e7ac9d062 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -231,7 +231,7 @@ bool CreateUnknownEnumValues(const FieldDescriptor* field); // the internal library are allowed to create subclasses. class PROTOBUF_EXPORT Message : public MessageLite { public: - inline Message() {} + constexpr Message() = default; // Basic Operations ------------------------------------------------ @@ -367,7 +367,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { protected: - static size_t GetInvariantPerBuild(size_t salt); + static uint64 GetInvariantPerBuild(uint64 salt); private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 1cce5d9b08..a76c16e5a4 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -74,6 +74,12 @@ class ZeroCopyOutputStream; } // namespace io namespace internal { +// Tag type used to invoke the constinit constructor overload of some classes. +// Such constructors are internal implementation details of the library. +struct ConstantInitialized { + explicit ConstantInitialized() = default; +}; + // See parse_context.h for explanation class ParseContext; @@ -145,14 +151,27 @@ class ExplicitlyConstructed { } union_; }; +PROTOBUF_DISABLE_MSVC_UNION_WARNING +// We need a publicly accessible `value` object to allow constexpr +// support in C++11. +// A constexpr accessor does not work portably. +union EmptyString { + constexpr EmptyString() : dummy{} {} + ~EmptyString() {} + + // We need a dummy object for constant initialization. + std::false_type dummy; + std::string value; +}; +PROTOBUF_ENABLE_MSVC_UNION_WARNING + // Default empty string object. Don't use this directly. Instead, call // GetEmptyString() to get the reference. -PROTOBUF_EXPORT extern ExplicitlyConstructed - fixed_address_empty_string; +PROTOBUF_EXPORT extern EmptyString fixed_address_empty_string; -PROTOBUF_EXPORT inline const std::string& GetEmptyStringAlreadyInited() { - return fixed_address_empty_string.get(); +PROTOBUF_EXPORT constexpr const std::string& GetEmptyStringAlreadyInited() { + return fixed_address_empty_string.value; } PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& str); @@ -187,7 +206,7 @@ PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& str); // the internal library are allowed to create subclasses. class PROTOBUF_EXPORT MessageLite { public: - inline MessageLite() {} + constexpr MessageLite() = default; virtual ~MessageLite() = default; // Basic Operations ------------------------------------------------ diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h index 781a1f54e7..ec5f923890 100644 --- a/src/google/protobuf/metadata_lite.h +++ b/src/google/protobuf/metadata_lite.h @@ -58,7 +58,7 @@ namespace internal { // pointer. class InternalMetadata { public: - InternalMetadata() : ptr_(nullptr) {} + constexpr InternalMetadata() : ptr_(nullptr) {} explicit InternalMetadata(Arena* arena) : ptr_(arena) {} template diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index d879a863b0..8b39d69896 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -139,6 +139,21 @@ #ifdef PROTOBUF_FINAL #error PROTOBUF_FINAL was previously defined #endif +#ifdef PROTOBUF_DISABLE_MSVC_UNION_WARNING +#error PROTOBUF_DISABLE_MSVC_UNION_WARNING was previously defined +#endif +#ifdef PROTOBUF_ENABLE_MSVC_UNION_WARNING +#error PROTOBUF_ENABLE_MSVC_UNION_WARNING was previously defined +#endif +#ifdef PROTOBUF_CONSTINIT +#error PROTOBUF_CONSTINIT was previously defined +#endif +#ifdef PROTOBUF_MAYBE_CONSTEXPR +#error PROTOBUF_MAYBE_CONSTEXPR was previously defined +#endif +#ifdef PROTOBUF_ATTRIBUTE_NO_DESTROY +#error PROTOBUF_ATTRIBUTE_NO_DESTROY was previously defined +#endif #define PROTOBUF_NAMESPACE "google::protobuf" @@ -428,6 +443,10 @@ #undef min #pragma push_macro("max") #undef max +#pragma push_macro("NEAR") +#undef NEAR +#pragma push_macro("NO_DATA") +#undef NO_DATA #pragma push_macro("REASON_UNKNOWN") #undef REASON_UNKNOWN #pragma push_macro("SERVICE_DISABLED") @@ -443,10 +462,6 @@ #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) // Don't let Objective-C Macros interfere with proto identifiers with the same // name. -#pragma push_macro("YES") -#undef YES -#pragma push_macro("NO") -#undef NO #pragma push_macro("DEBUG") #undef DEBUG #pragma push_macro("TRUE") @@ -533,3 +548,59 @@ // This experiment is purely for the purpose of gathering data. All code guarded // by this flag is supposed to be removed after this experiment. // #define PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT + +#if defined(__cpp_constinit) +#define PROTOBUF_CONSTINIT constinit +#elif defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::require_constant_initialization) +#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]] +#endif +#endif +#ifndef PROTOBUF_CONSTINIT +#define PROTOBUF_CONSTINIT +#endif + +// Some constructors can't be constexpr under MSVC, but given that MSVC will not +// do constant initialization of globals anyway we can omit `constexpr` from +// them. These constructors are marked with PROTOBUF_MAYBE_CONSTEXPR +#if defined(_MSC_VER) +#define PROTOBUF_MAYBE_CONSTEXPR +#else +#define PROTOBUF_MAYBE_CONSTEXPR constexpr +#endif + +#if _MSC_VER +#define PROTOBUF_DISABLE_MSVC_UNION_WARNING \ + __pragma(warning(push)) \ + __pragma(warning(disable : 4582)) \ + __pragma(warning(disable : 4583)) + +#define PROTOBUF_ENABLE_MSVC_UNION_WARNING \ + __pragma(warning(pop)) +#else +#define PROTOBUF_DISABLE_MSVC_UNION_WARNING +#define PROTOBUF_ENABLE_MSVC_UNION_WARNING +#endif + +#if defined(__cpp_constinit) +#define PROTOBUF_CONSTINIT constinit +#elif defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::require_constant_initialization) +#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]] +#endif +#endif +#ifndef PROTOBUF_CONSTINIT +#define PROTOBUF_CONSTINIT +#endif + +// Some globals with an empty non-trivial destructor are annotated with +// no_destroy for performance reasons. It reduces the cost of these globals in +// non-opt mode and under sanitizers. +#if defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::no_destroy) +#define PROTOBUF_ATTRIBUTE_NO_DESTROY [[clang::no_destroy]] +#endif +#endif +#if !defined(PROTOBUF_ATTRIBUTE_NO_DESTROY) +#define PROTOBUF_ATTRIBUTE_NO_DESTROY +#endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index fd080a4875..d1414285e4 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -72,6 +72,11 @@ #undef PROTOBUF_FINAL #undef PROTOBUF_THREAD_LOCAL #undef PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT +#undef PROTOBUF_DISABLE_MSVC_UNION_WARNING +#undef PROTOBUF_ENABLE_MSVC_UNION_WARNING +#undef PROTOBUF_CONSTINIT +#undef PROTOBUF_MAYBE_CONSTEXPR +#undef PROTOBUF_ATTRIBUTE_NO_DESTROY // Restore macro that may have been #undef'd in port_def.inc. #ifdef _MSC_VER @@ -88,6 +93,8 @@ #pragma pop_macro("OPTIONAL") #pragma pop_macro("min") #pragma pop_macro("max") +#pragma pop_macro("NEAR") +#pragma pop_macro("NO_DATA") #pragma pop_macro("NO_ERROR") #pragma pop_macro("REASON_UNKNOWN") #pragma pop_macro("SERVICE_DISABLED") @@ -97,8 +104,6 @@ #endif #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) -#pragma pop_macro("YES") -#pragma pop_macro("NO") #pragma pop_macro("DEBUG") #pragma pop_macro("TRUE") #pragma pop_macro("FALSE") diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc index c913ea0d19..29fc5dbaaf 100644 --- a/src/google/protobuf/reflection_ops.cc +++ b/src/google/protobuf/reflection_ops.cc @@ -85,9 +85,7 @@ void ReflectionOps::Merge(const Message& from, Message* to) { std::vector fields; from_reflection->ListFieldsOmitStripped(from, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - + for (const FieldDescriptor* field : fields) { if (field->is_repeated()) { // Use map reflection if both are in map status and have the // same map type to avoid sync with repeated field. @@ -180,8 +178,8 @@ void ReflectionOps::Clear(Message* message) { std::vector fields; reflection->ListFieldsOmitStripped(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - reflection->ClearField(message, fields[i]); + for (const FieldDescriptor* field : fields) { + reflection->ClearField(message, field); } reflection->MutableUnknownFields(message)->Clear(); @@ -270,8 +268,7 @@ bool ReflectionOps::IsInitialized(const Message& message) { // Should be safe to skip stripped fields because required fields are not // stripped. reflection->ListFieldsOmitStripped(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; + for (const FieldDescriptor* field : fields) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (field->is_map()) { @@ -329,8 +326,7 @@ void ReflectionOps::DiscardUnknownFields(Message* message) { // messages present. std::vector fields; reflection->ListFields(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; + for (const FieldDescriptor* field : fields) { // Skip over non-message fields. if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { continue; @@ -401,8 +397,7 @@ void ReflectionOps::FindInitializationErrors(const Message& message, // Check sub-messages. std::vector fields; reflection->ListFieldsOmitStripped(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; + for (const FieldDescriptor* field : fields) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (field->is_repeated()) { diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index c1c4774685..26d5847331 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -169,7 +169,7 @@ class RepeatedField final { "We only support types that have an alignment smaller than Arena"); public: - RepeatedField(); + constexpr RepeatedField(); explicit RepeatedField(Arena* arena); RepeatedField(const RepeatedField& other); template @@ -577,7 +577,7 @@ struct IsMovable // }; class PROTOBUF_EXPORT RepeatedPtrFieldBase { protected: - RepeatedPtrFieldBase(); + constexpr RepeatedPtrFieldBase(); explicit RepeatedPtrFieldBase(Arena* arena); ~RepeatedPtrFieldBase() { #ifndef NDEBUG @@ -920,7 +920,7 @@ class StringTypeHandler { template class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { public: - RepeatedPtrField(); + constexpr RepeatedPtrField(); explicit RepeatedPtrField(Arena* arena); RepeatedPtrField(const RepeatedPtrField& other); @@ -1180,7 +1180,7 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { // implementation ==================================================== template -inline RepeatedField::RepeatedField() +constexpr RepeatedField::RepeatedField() : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {} template @@ -1647,7 +1647,7 @@ struct ElementCopier { namespace internal { -inline RepeatedPtrFieldBase::RepeatedPtrFieldBase() +constexpr RepeatedPtrFieldBase::RepeatedPtrFieldBase() : arena_(NULL), current_size_(0), total_size_(0), rep_(NULL) {} inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(Arena* arena) @@ -2090,7 +2090,8 @@ class RepeatedPtrField::TypeHandler : public internal::StringTypeHandler {}; template -inline RepeatedPtrField::RepeatedPtrField() : RepeatedPtrFieldBase() {} +constexpr RepeatedPtrField::RepeatedPtrField() + : RepeatedPtrFieldBase() {} template inline RepeatedPtrField::RepeatedPtrField(Arena* arena) diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 8de9504dc0..4072f47b6c 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -65,6 +65,11 @@ namespace { using ::protobuf_unittest::TestAllTypes; using ::testing::ElementsAre; +TEST(RepeatedField, ConstInit) { + PROTOBUF_CONSTINIT static RepeatedField field{}; // NOLINT + EXPECT_TRUE(field.empty()); +} + // Test operations on a small RepeatedField. TEST(RepeatedField, Small) { RepeatedField field; @@ -827,6 +832,11 @@ TEST(RepeatedField, TestSAddFromSelf) { // RepeatedPtrField tests. These pretty much just mirror the RepeatedField // tests above. +TEST(RepeatedPtrField, ConstInit) { + PROTOBUF_CONSTINIT static RepeatedPtrField field{}; // NOLINT + EXPECT_TRUE(field.empty()); +} + TEST(RepeatedPtrField, Small) { RepeatedPtrField field; diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h index 0193301a22..c7a48dea54 100644 --- a/src/google/protobuf/stubs/bytestream.h +++ b/src/google/protobuf/stubs/bytestream.h @@ -256,11 +256,11 @@ class PROTOBUF_EXPORT GrowingArrayByteSink : public strings::ByteSink { // class PROTOBUF_EXPORT StringByteSink : public ByteSink { public: - explicit StringByteSink(string* dest) : dest_(dest) {} + explicit StringByteSink(std::string* dest) : dest_(dest) {} virtual void Append(const char* data, size_t n) override; private: - string* dest_; + std::string* dest_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringByteSink); }; diff --git a/src/google/protobuf/stubs/bytestream_unittest.cc b/src/google/protobuf/stubs/bytestream_unittest.cc index 06f114abc7..cb11825ef7 100644 --- a/src/google/protobuf/stubs/bytestream_unittest.cc +++ b/src/google/protobuf/stubs/bytestream_unittest.cc @@ -64,7 +64,7 @@ class MockByteSource : public ByteSource { TEST(ByteSourceTest, CopyTo) { StringPiece data("Hello world!"); MockByteSource source(data, 3); - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, data.size()); @@ -75,7 +75,7 @@ TEST(ByteSourceTest, CopySubstringTo) { StringPiece data("Hello world!"); MockByteSource source(data, 3); source.Skip(1); - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, data.size() - 2); @@ -92,7 +92,7 @@ TEST(ByteSourceTest, LimitByteSource) { EXPECT_EQ(5, limit_source.Available()); { - string str; + std::string str; StringByteSink sink(&str); limit_source.CopyTo(&sink, limit_source.Available()); EXPECT_EQ("ello ", str); @@ -101,7 +101,7 @@ TEST(ByteSourceTest, LimitByteSource) { } { - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, source.Available()); EXPECT_EQ("world!", str); @@ -112,7 +112,7 @@ TEST(ByteSourceTest, LimitByteSource) { TEST(ByteSourceTest, CopyToStringByteSink) { StringPiece data("Hello world!"); MockByteSource source(data, 3); - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, data.size()); EXPECT_EQ(data, str); @@ -121,7 +121,7 @@ TEST(ByteSourceTest, CopyToStringByteSink) { // Verify that ByteSink is subclassable and Flush() overridable. class FlushingByteSink : public StringByteSink { public: - explicit FlushingByteSink(string* dest) : StringByteSink(dest) {} + explicit FlushingByteSink(std::string* dest) : StringByteSink(dest) {} virtual void Flush() { Append("z", 1); } private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FlushingByteSink); @@ -134,7 +134,7 @@ void WriteAndFlush(ByteSink* s) { } TEST(ByteSinkTest, Flush) { - string str; + std::string str; FlushingByteSink f_sink(&str); WriteAndFlush(&f_sink); EXPECT_STREQ("abcz", str.c_str()); diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h index b7a3a82910..43d546d199 100644 --- a/src/google/protobuf/stubs/callback.h +++ b/src/google/protobuf/stubs/callback.h @@ -62,12 +62,12 @@ namespace protobuf { // Note that NewCallback() is a bit touchy regarding argument types. Generally, // the values you provide for the parameter bindings must exactly match the // types accepted by the callback function. For example: -// void Foo(string s); +// void Foo(std::string s); // NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string -// NewCallback(&Foo, string("foo")); // WORKS +// NewCallback(&Foo, std::string("foo")); // WORKS // Also note that the arguments cannot be references: -// void Foo(const string& s); -// string my_str; +// void Foo(const std::string& s); +// std::string my_str; // NewCallback(&Foo, my_str); // WON'T WORK: Can't use references. // However, correctly-typed pointers will work just fine. class PROTOBUF_EXPORT Closure { diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index 30802b1bb4..bc150f56a9 100644 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc @@ -96,7 +96,7 @@ void VerifyVersion(int headerVersion, } } -string VersionString(int version) { +std::string VersionString(int version) { int major = version / 1000000; int minor = (version / 1000) % 1000; int micro = version % 1000; @@ -127,7 +127,7 @@ namespace internal { #if defined(__ANDROID__) inline void DefaultLogHandler(LogLevel level, const char* filename, int line, - const string& message) { + const std::string& message) { if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { return; } @@ -162,7 +162,7 @@ inline void DefaultLogHandler(LogLevel level, const char* filename, int line, #else void DefaultLogHandler(LogLevel level, const char* filename, int line, - const string& message) { + const std::string& message) { if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { return; } @@ -177,14 +177,14 @@ void DefaultLogHandler(LogLevel level, const char* filename, int line, #endif void NullLogHandler(LogLevel /* level */, const char* /* filename */, - int /* line */, const string& /* message */) { + int /* line */, const std::string& /* message */) { // Nothing. } static LogHandler* log_handler_ = &DefaultLogHandler; static std::atomic log_silencer_count_ = ATOMIC_VAR_INIT(0); -LogMessage& LogMessage::operator<<(const string& value) { +LogMessage& LogMessage::operator<<(const std::string& value) { message_ += value; return *this; } diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc index 5852458922..c55e452505 100644 --- a/src/google/protobuf/stubs/common_unittest.cc +++ b/src/google/protobuf/stubs/common_unittest.cc @@ -53,7 +53,7 @@ TEST(VersionTest, VersionMatchesConfig) { // Verify that the version string specified in config.h matches the one // in common.h. The config.h version is a string which may have a suffix // like "beta" or "rc1", so we remove that. - string version = PACKAGE_VERSION; + std::string version = PACKAGE_VERSION; int pos = 0; while (pos < version.size() && (ascii_isdigit(version[pos]) || version[pos] == '.')) { @@ -77,10 +77,10 @@ TEST(CommonTest, IntMinMaxConstants) { EXPECT_EQ(0, kuint64max + 1); } -std::vector captured_messages_; +std::vector captured_messages_; void CaptureLog(LogLevel level, const char* filename, int line, - const string& message) { + const std::string& message) { captured_messages_.push_back( strings::Substitute("$0 $1:$2: $3", implicit_cast(level), filename, line, message)); @@ -93,7 +93,7 @@ TEST(LoggingTest, DefaultLogging) { GOOGLE_LOG(WARNING) << "A warning."; GOOGLE_LOG(ERROR ) << "An error."; - string text = GetCapturedTestStderr(); + std::string text = GetCapturedTestStderr(); EXPECT_EQ( "[libprotobuf INFO " __FILE__ ":" + SimpleItoa(line + 1) + "] A message.\n" "[libprotobuf WARNING " __FILE__ ":" + SimpleItoa(line + 2) + "] A warning.\n" @@ -111,7 +111,7 @@ TEST(LoggingTest, NullLogging) { EXPECT_TRUE(SetLogHandler(old_handler) == nullptr); - string text = GetCapturedTestStderr(); + std::string text = GetCapturedTestStderr(); EXPECT_EQ("", text); } @@ -167,10 +167,10 @@ class ClosureTest : public testing::Test { static void SetA123Function() { current_instance_->a_ = 123; } void SetAMethod(int a) { a_ = a; } - void SetCMethod(string c) { c_ = c; } + void SetCMethod(std::string c) { c_ = c; } static void SetAFunction(int a) { current_instance_->a_ = a; } - static void SetCFunction(string c) { current_instance_->c_ = c; } + static void SetCFunction(std::string c) { current_instance_->c_ = c; } void SetABMethod(int a, const char* b) { a_ = a; b_ = b; } static void SetABFunction(int a, const char* b) { @@ -192,7 +192,7 @@ class ClosureTest : public testing::Test { int a_; const char* b_; - string c_; + std::string c_; Closure* permanent_closure_; static ClosureTest* current_instance_; @@ -231,15 +231,15 @@ TEST_F(ClosureTest, TestClosureMethod1) { } TEST_F(ClosureTest, TestClosureFunction1String) { - Closure* closure = NewCallback(&SetCFunction, string("test")); + Closure* closure = NewCallback(&SetCFunction, std::string("test")); EXPECT_NE("test", c_); closure->Run(); EXPECT_EQ("test", c_); } TEST_F(ClosureTest, TestClosureMethod1String) { - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetCMethod, string("test")); + Closure* closure = NewCallback(current_instance_, &ClosureTest::SetCMethod, + std::string("test")); EXPECT_NE("test", c_); closure->Run(); EXPECT_EQ("test", c_); diff --git a/src/google/protobuf/stubs/status.cc b/src/google/protobuf/stubs/status.cc index 2bfbe0b42b..03b37c365b 100644 --- a/src/google/protobuf/stubs/status.cc +++ b/src/google/protobuf/stubs/status.cc @@ -38,7 +38,7 @@ namespace google { namespace protobuf { namespace util { namespace error { -inline string CodeEnumToString(error::Code code) { +inline std::string CodeEnumToString(error::Code code) { switch (code) { case OK: return "OK"; @@ -111,7 +111,7 @@ bool Status::operator==(const Status& x) const { error_message_ == x.error_message_; } -string Status::ToString() const { +std::string Status::ToString() const { if (error_code_ == error::OK) { return "OK"; } else { diff --git a/src/google/protobuf/stubs/status.h b/src/google/protobuf/stubs/status.h index 04ecc633bc..bededad541 100644 --- a/src/google/protobuf/stubs/status.h +++ b/src/google/protobuf/stubs/status.h @@ -106,11 +106,11 @@ class PROTOBUF_EXPORT Status { } // Return a combination of the error code name and message. - string ToString() const; + std::string ToString() const; private: error::Code error_code_; - string error_message_; + std::string error_message_; }; // Prints a human-readable representation of 'x' to 'os'. diff --git a/src/google/protobuf/stubs/status_test.cc b/src/google/protobuf/stubs/status_test.cc index 9a18778fba..8f4398c9c9 100644 --- a/src/google/protobuf/stubs/status_test.cc +++ b/src/google/protobuf/stubs/status_test.cc @@ -101,7 +101,7 @@ TEST(Status, AssignEmpty) { util::Status a(util::error::UNKNOWN, "message"); util::Status b; a = b; - ASSERT_EQ(string("OK"), a.ToString()); + ASSERT_EQ(std::string("OK"), a.ToString()); ASSERT_TRUE(b.ok()); ASSERT_TRUE(a.ok()); } diff --git a/src/google/protobuf/stubs/stl_util.h b/src/google/protobuf/stubs/stl_util.h index aa81eb6f72..d01f9ec944 100644 --- a/src/google/protobuf/stubs/stl_util.h +++ b/src/google/protobuf/stubs/stl_util.h @@ -44,7 +44,7 @@ namespace protobuf { // improve performance. However, since it's totally non-portable it has no // place in open source code. Feel free to fill this function in with your // own disgusting hack if you want the perf boost. -inline void STLStringResizeUninitialized(string* s, size_t new_size) { +inline void STLStringResizeUninitialized(std::string* s, size_t new_size) { s->resize(new_size); } @@ -60,7 +60,7 @@ inline void STLStringResizeUninitialized(string* s, size_t new_size) { // (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) // proposes this as the method. According to Matt Austern, this should // already work on all current implementations. -inline char* string_as_array(string* str) { +inline char* string_as_array(std::string* str) { // DO NOT USE const_cast(str->data())! See the unittest for why. return str->empty() ? nullptr : &*str->begin(); } diff --git a/src/google/protobuf/stubs/stringpiece_unittest.cc b/src/google/protobuf/stubs/stringpiece_unittest.cc index d9a32d03aa..846e1aed3d 100644 --- a/src/google/protobuf/stubs/stringpiece_unittest.cc +++ b/src/google/protobuf/stubs/stringpiece_unittest.cc @@ -87,7 +87,7 @@ TEST(StringPiece, Ctor) { #if defined(HAS_GLOBAL_STRING) { // ::string - string bonjour = "bonjour"; + std::string bonjour = "bonjour"; StringPiece s40(bonjour); EXPECT_TRUE(s40.data() == bonjour.data()); EXPECT_EQ(7, s40.length()); @@ -100,9 +100,9 @@ TEST(StringPiece, Ctor) { } TEST(StringPiece, STLComparator) { - string s1("foo"); - string s2("bar"); - string s3("baz"); + std::string s1("foo"); + std::string s2("bar"); + std::string s3("baz"); StringPiece p1(s1); StringPiece p2(s2); @@ -207,13 +207,13 @@ TEST(StringPiece, ComparisonOperators) { COMPARE(true, >, "b", "aa"); COMPARE(true, >, "bb", "aa"); - string x; + std::string x; for (int i = 0; i < 256; i++) { x += 'a'; - string y = x; + std::string y = x; COMPARE(true, ==, x, y); for (int j = 0; j < i; j++) { - string z = x; + std::string z = x; z[j] = 'b'; // Differs in position 'j' COMPARE(false, ==, x, z); COMPARE(true, <, x, z); @@ -240,7 +240,7 @@ TEST(StringPiece, STL1) { const StringPiece c("xyz"); const StringPiece d("foobar"); const StringPiece e; - string temp("123"); + std::string temp("123"); temp += '\0'; temp += "456"; const StringPiece f(temp); @@ -315,7 +315,7 @@ TEST(StringPiece, STL2) { EXPECT_TRUE(d.data() == nullptr); EXPECT_TRUE(d.begin() == d.end()); - EXPECT_EQ(StringPiece::npos, string::npos); + EXPECT_EQ(StringPiece::npos, std::string::npos); EXPECT_EQ(a.find(b), 0); EXPECT_EQ(a.find(b, 1), StringPiece::npos); @@ -336,15 +336,15 @@ TEST(StringPiece, STL2) { EXPECT_EQ(d.find(b, 4), StringPiece::npos); EXPECT_EQ(e.find(b, 7), StringPiece::npos); - size_t empty_search_pos = string().find(string()); + size_t empty_search_pos = std::string().find(std::string()); EXPECT_EQ(d.find(d), empty_search_pos); EXPECT_EQ(d.find(e), empty_search_pos); EXPECT_EQ(e.find(d), empty_search_pos); EXPECT_EQ(e.find(e), empty_search_pos); - EXPECT_EQ(d.find(d, 4), string().find(string(), 4)); - EXPECT_EQ(d.find(e, 4), string().find(string(), 4)); - EXPECT_EQ(e.find(d, 4), string().find(string(), 4)); - EXPECT_EQ(e.find(e, 4), string().find(string(), 4)); + EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4)); EXPECT_EQ(a.find('a'), 0); EXPECT_EQ(a.find('c'), 2); @@ -376,8 +376,8 @@ TEST(StringPiece, STL2) { EXPECT_EQ(a.rfind(c, 0), StringPiece::npos); EXPECT_EQ(b.rfind(c), StringPiece::npos); EXPECT_EQ(b.rfind(c, 0), StringPiece::npos); - EXPECT_EQ(a.rfind(d), a.as_string().rfind(string())); - EXPECT_EQ(a.rfind(e), a.as_string().rfind(string())); + EXPECT_EQ(a.rfind(d), a.as_string().rfind(std::string())); + EXPECT_EQ(a.rfind(e), a.as_string().rfind(std::string())); EXPECT_EQ(a.rfind(d, 12), 12); EXPECT_EQ(a.rfind(e, 17), 17); EXPECT_EQ(a.rfind(g), StringPiece::npos); @@ -386,14 +386,14 @@ TEST(StringPiece, STL2) { EXPECT_EQ(d.rfind(b, 4), StringPiece::npos); EXPECT_EQ(e.rfind(b, 7), StringPiece::npos); // empty string nonsense - EXPECT_EQ(d.rfind(d, 4), string().rfind(string())); - EXPECT_EQ(e.rfind(d, 7), string().rfind(string())); - EXPECT_EQ(d.rfind(e, 4), string().rfind(string())); - EXPECT_EQ(e.rfind(e, 7), string().rfind(string())); - EXPECT_EQ(d.rfind(d), string().rfind(string())); - EXPECT_EQ(e.rfind(d), string().rfind(string())); - EXPECT_EQ(d.rfind(e), string().rfind(string())); - EXPECT_EQ(e.rfind(e), string().rfind(string())); + EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(d), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(d), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(e), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(e), std::string().rfind(std::string())); EXPECT_EQ(g.rfind('o'), 8); EXPECT_EQ(g.rfind('q'), StringPiece::npos); @@ -566,7 +566,7 @@ TEST(StringPiece, STL2) { // empty string nonsense EXPECT_EQ(StringPiece(d, 0, 99), e); // Verify that they work taking an actual string, not just a StringPiece. - string a2 = a.as_string(); + std::string a2 = a.as_string(); EXPECT_EQ(StringPiece(a2, 0, 3), b); EXPECT_EQ(StringPiece(a2, 23), c); EXPECT_EQ(StringPiece(a2, 23, 3), c); @@ -577,12 +577,12 @@ TEST(StringPiece, STL2) { TEST(StringPiece, Custom) { StringPiece a("foobar"); - string s1("123"); + std::string s1("123"); s1 += '\0'; s1 += "456"; StringPiece b(s1); StringPiece e; - string s2; + std::string s2; // CopyToString a.CopyToString(&s2); @@ -666,16 +666,16 @@ TEST(StringPiece, Custom) { EXPECT_NE(c, a); // as_string - string s3(a.as_string().c_str(), 7); + std::string s3(a.as_string().c_str(), 7); EXPECT_EQ(c, s3); - string s4(e.as_string()); + std::string s4(e.as_string()); EXPECT_TRUE(s4.empty()); // ToString { - string s5(a.ToString().c_str(), 7); + std::string s5(a.ToString().c_str(), 7); EXPECT_EQ(c, s5); - string s6(e.ToString()); + std::string s6(e.ToString()); EXPECT_TRUE(s6.empty()); } @@ -747,12 +747,12 @@ TEST(StringPiece, Comparisons2) { } TEST(ComparisonOpsTest, StringCompareNotAmbiguous) { - EXPECT_EQ("hello", string("hello")); - EXPECT_LT("hello", string("world")); + EXPECT_EQ("hello", std::string("hello")); + EXPECT_LT("hello", std::string("world")); } TEST(ComparisonOpsTest, HeterogenousStringPieceEquals) { - EXPECT_EQ(StringPiece("hello"), string("hello")); + EXPECT_EQ(StringPiece("hello"), std::string("hello")); EXPECT_EQ("hello", StringPiece("hello")); } diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc index e6019fc664..2603164936 100644 --- a/src/google/protobuf/stubs/stringprintf.cc +++ b/src/google/protobuf/stubs/stringprintf.cc @@ -54,7 +54,7 @@ enum { IS_COMPILER_MSVC = 1 }; enum { IS_COMPILER_MSVC = 0 }; #endif -void StringAppendV(string* dst, const char* format, va_list ap) { +void StringAppendV(std::string* dst, const char* format, va_list ap) { // First try with a small fixed size buffer static const int kSpaceLength = 1024; char space[kSpaceLength]; @@ -105,17 +105,16 @@ void StringAppendV(string* dst, const char* format, va_list ap) { delete[] buf; } - -string StringPrintf(const char* format, ...) { +std::string StringPrintf(const char* format, ...) { va_list ap; va_start(ap, format); - string result; + std::string result; StringAppendV(&result, format, ap); va_end(ap); return result; } -const string& SStringPrintf(string* dst, const char* format, ...) { +const std::string& SStringPrintf(std::string* dst, const char* format, ...) { va_list ap; va_start(ap, format); dst->clear(); @@ -124,7 +123,7 @@ const string& SStringPrintf(string* dst, const char* format, ...) { return *dst; } -void StringAppendF(string* dst, const char* format, ...) { +void StringAppendF(std::string* dst, const char* format, ...) { va_list ap; va_start(ap, format); StringAppendV(dst, format, ap); @@ -139,7 +138,8 @@ const int kStringPrintfVectorMaxArgs = 32; // and we can fix the problem or protect against an attack. static const char string_printf_empty_block[256] = { '\0' }; -string StringPrintfVector(const char* format, const std::vector& v) { +std::string StringPrintfVector(const char* format, + const std::vector& v) { GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs) << "StringPrintfVector currently only supports up to " << kStringPrintfVectorMaxArgs << " arguments. " diff --git a/src/google/protobuf/stubs/stringprintf.h b/src/google/protobuf/stubs/stringprintf.h index 253d736a21..e3858be130 100644 --- a/src/google/protobuf/stubs/stringprintf.h +++ b/src/google/protobuf/stubs/stringprintf.h @@ -52,18 +52,20 @@ namespace google { namespace protobuf { // Return a C++ string -PROTOBUF_EXPORT extern string StringPrintf(const char* format, ...); +PROTOBUF_EXPORT extern std::string StringPrintf(const char* format, ...); // Store result into a supplied string and return it -PROTOBUF_EXPORT extern const string& SStringPrintf(string* dst, - const char* format, ...); +PROTOBUF_EXPORT extern const std::string& SStringPrintf(std::string* dst, + const char* format, + ...); // Append result to a supplied string -PROTOBUF_EXPORT extern void StringAppendF(string* dst, const char* format, ...); +PROTOBUF_EXPORT extern void StringAppendF(std::string* dst, const char* format, + ...); // Lower-level routine that takes a va_list and appends to a specified // string. All other routines are just convenience wrappers around it. -PROTOBUF_EXPORT extern void StringAppendV(string* dst, const char* format, +PROTOBUF_EXPORT extern void StringAppendV(std::string* dst, const char* format, va_list ap); // The max arguments supported by StringPrintfVector @@ -72,8 +74,8 @@ PROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs; // You can use this version when all your arguments are strings, but // you don't know how many arguments you'll have at compile time. // StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs -PROTOBUF_EXPORT extern string StringPrintfVector(const char* format, - const std::vector& v); +PROTOBUF_EXPORT extern std::string StringPrintfVector( + const char* format, const std::vector& v); } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/stubs/stringprintf_unittest.cc b/src/google/protobuf/stubs/stringprintf_unittest.cc index 7fcbf500eb..37172a9d97 100644 --- a/src/google/protobuf/stubs/stringprintf_unittest.cc +++ b/src/google/protobuf/stubs/stringprintf_unittest.cc @@ -49,7 +49,7 @@ TEST(StringPrintfTest, Empty) { // so we do not allow them in google3. EXPECT_EQ("", StringPrintf("")); #endif - EXPECT_EQ("", StringPrintf("%s", string().c_str())); + EXPECT_EQ("", StringPrintf("%s", std::string().c_str())); EXPECT_EQ("", StringPrintf("%s", "")); } @@ -61,26 +61,26 @@ TEST(StringPrintfTest, Misc) { } TEST(StringAppendFTest, Empty) { - string value("Hello"); + std::string value("Hello"); const char* empty = ""; StringAppendF(&value, "%s", empty); EXPECT_EQ("Hello", value); } TEST(StringAppendFTest, EmptyString) { - string value("Hello"); + std::string value("Hello"); StringAppendF(&value, "%s", ""); EXPECT_EQ("Hello", value); } TEST(StringAppendFTest, String) { - string value("Hello"); + std::string value("Hello"); StringAppendF(&value, " %s", "World"); EXPECT_EQ("Hello World", value); } TEST(StringAppendFTest, Int) { - string value("Hello"); + std::string value("Hello"); StringAppendF(&value, " %d", 123); EXPECT_EQ("Hello 123", value); } @@ -96,7 +96,7 @@ TEST(StringPrintfTest, Multibyte) { setlocale(LC_CTYPE, "en_US.utf8"); const char kInvalidCodePoint[] = "\375\067s"; - string value = StringPrintf("%.*s", 3, kInvalidCodePoint); + std::string value = StringPrintf("%.*s", 3, kInvalidCodePoint); // In some versions of glibc (e.g. eglibc-2.11.1, aka GRTEv2), snprintf // returns error given an invalid codepoint. Other versions @@ -122,7 +122,7 @@ TEST(StringPrintfTest, NoMultibyte) { // No multibyte handling, but the string contains funny chars. char* old_locale = setlocale(LC_CTYPE, nullptr); setlocale(LC_CTYPE, "POSIX"); - string value = StringPrintf("%.*s", 3, "\375\067s"); + std::string value = StringPrintf("%.*s", 3, "\375\067s"); setlocale(LC_CTYPE, old_locale); EXPECT_EQ("\375\067s", value); } @@ -132,7 +132,7 @@ TEST(StringPrintfTest, DontOverwriteErrno) { // something significantly larger than what people are normally // printing in their badly written PLOG() statements. errno = ECHILD; - string value = StringPrintf("Hello, %s!", "World"); + std::string value = StringPrintf("Hello, %s!", "World"); EXPECT_EQ(ECHILD, errno); } @@ -142,7 +142,7 @@ TEST(StringPrintfTest, LargeBuf) { char* buf = new char[n+1]; memset(buf, ' ', n); buf[n] = 0; - string value = StringPrintf("%s", buf); + std::string value = StringPrintf("%s", buf); EXPECT_EQ(buf, value); delete[] buf; } diff --git a/src/google/protobuf/stubs/structurally_valid_unittest.cc b/src/google/protobuf/stubs/structurally_valid_unittest.cc index eec07a87ab..ebd9c42306 100644 --- a/src/google/protobuf/stubs/structurally_valid_unittest.cc +++ b/src/google/protobuf/stubs/structurally_valid_unittest.cc @@ -43,7 +43,8 @@ TEST(StructurallyValidTest, ValidUTF8String) { // On GCC, this string can be written as: // "abcd 1234 - \u2014\u2013\u2212" // MSVC seems to interpret \u differently. - string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789"); + std::string valid_str( + "abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789"); EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(), valid_str.size())); // Additional check for pointer alignment @@ -54,7 +55,7 @@ TEST(StructurallyValidTest, ValidUTF8String) { } TEST(StructurallyValidTest, InvalidUTF8String) { - const string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789"); + const std::string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789"); EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(), invalid_str.size())); // Additional check for pointer alignment diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc index 27225942ac..2ecdb2bf72 100644 --- a/src/google/protobuf/stubs/strutil.cc +++ b/src/google/protobuf/stubs/strutil.cc @@ -84,7 +84,7 @@ inline bool isprint(char c) { // Replaces any occurrence of the character 'remove' (or the characters // in 'remove') with the character 'replacewith'. // ---------------------------------------------------------------------- -void ReplaceCharacters(string *s, const char *remove, char replacewith) { +void ReplaceCharacters(std::string *s, const char *remove, char replacewith) { const char *str_start = s->c_str(); const char *str = str_start; for (str = strpbrk(str, remove); @@ -94,7 +94,7 @@ void ReplaceCharacters(string *s, const char *remove, char replacewith) { } } -void StripWhitespace(string* str) { +void StripWhitespace(std::string *str) { int str_length = str->length(); // Strip off leading whitespace. @@ -118,7 +118,7 @@ void StripWhitespace(string* str) { --last; } if (last != (str_length - 1) && last >= 0) { - str->erase(last + 1, string::npos); + str->erase(last + 1, std::string::npos); } } @@ -129,19 +129,19 @@ void StripWhitespace(string* str) { // it only replaces the first instance of "old." // ---------------------------------------------------------------------- -void StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all, - string* res) { +void StringReplace(const std::string &s, const std::string &oldsub, + const std::string &newsub, bool replace_all, + std::string *res) { if (oldsub.empty()) { res->append(s); // if empty, append the given string. return; } - string::size_type start_pos = 0; - string::size_type pos; + std::string::size_type start_pos = 0; + std::string::size_type pos; do { pos = s.find(oldsub, start_pos); - if (pos == string::npos) { + if (pos == std::string::npos) { break; } res->append(s, start_pos, pos - start_pos); @@ -160,9 +160,9 @@ void StringReplace(const string& s, const string& oldsub, // happened or not. // ---------------------------------------------------------------------- -string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all) { - string ret; +std::string StringReplace(const std::string &s, const std::string &oldsub, + const std::string &newsub, bool replace_all) { + std::string ret; StringReplace(s, oldsub, newsub, replace_all, &ret); return ret; } @@ -195,11 +195,11 @@ static inline void SplitStringToIteratorUsing(StringPiece full, return; } - string::size_type begin_index, end_index; + std::string::size_type begin_index, end_index; begin_index = full.find_first_not_of(delim); - while (begin_index != string::npos) { + while (begin_index != std::string::npos) { end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { + if (end_index == std::string::npos) { *result++ = std::string(full.substr(begin_index)); return; } @@ -210,8 +210,8 @@ static inline void SplitStringToIteratorUsing(StringPiece full, } void SplitStringUsing(StringPiece full, const char *delim, - std::vector *result) { - std::back_insert_iterator< std::vector > it(*result); + std::vector *result) { + std::back_insert_iterator > it(*result); SplitStringToIteratorUsing(full, delim, it); } @@ -230,12 +230,12 @@ template static inline void SplitStringToIteratorAllowEmpty(StringPiece full, const char *delim, int pieces, ITR &result) { - string::size_type begin_index, end_index; + std::string::size_type begin_index, end_index; begin_index = 0; for (int i = 0; (i < pieces-1) || (pieces == 0); i++) { end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { + if (end_index == std::string::npos) { *result++ = std::string(full.substr(begin_index)); return; } @@ -247,8 +247,8 @@ static inline void SplitStringToIteratorAllowEmpty(StringPiece full, } void SplitStringAllowEmpty(StringPiece full, const char *delim, - std::vector *result) { - std::back_insert_iterator > it(*result); + std::vector *result) { + std::back_insert_iterator > it(*result); SplitStringToIteratorAllowEmpty(full, delim, 0, it); } @@ -259,10 +259,8 @@ void SplitStringAllowEmpty(StringPiece full, const char *delim, // // ---------------------------------------------------------------------- template -static void JoinStringsIterator(const ITERATOR& start, - const ITERATOR& end, - const char* delim, - string* result) { +static void JoinStringsIterator(const ITERATOR &start, const ITERATOR &end, + const char *delim, std::string *result) { GOOGLE_CHECK(result != nullptr); result->clear(); int delim_length = strlen(delim); @@ -286,9 +284,8 @@ static void JoinStringsIterator(const ITERATOR& start, } } -void JoinStrings(const std::vector& components, - const char* delim, - string * result) { +void JoinStrings(const std::vector &components, const char *delim, + std::string *result) { JoinStringsIterator(components.begin(), components.end(), delim, result); } @@ -314,8 +311,8 @@ int UnescapeCEscapeSequences(const char* source, char* dest) { return UnescapeCEscapeSequences(source, dest, nullptr); } -int UnescapeCEscapeSequences(const char* source, char* dest, - std::vector *errors) { +int UnescapeCEscapeSequences(const char *source, char *dest, + std::vector *errors) { GOOGLE_DCHECK(errors == nullptr) << "Error reporting not implemented."; char* d = dest; @@ -370,8 +367,10 @@ int UnescapeCEscapeSequences(const char* source, char* dest, while (isxdigit(p[1])) // arbitrarily many hex digits ch = (ch << 4) + hex_digit_to_int(*++p); if (ch > 0xFF) - LOG_STRING(ERROR, errors) << "Value of " << - "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits"; + LOG_STRING(ERROR, errors) + << "Value of " + << "\\" << std::string(hex_start, p + 1 - hex_start) + << " exceeds 8 bits"; *d++ = ch; break; } @@ -386,7 +385,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest, } else { LOG_STRING(ERROR, errors) << "\\u must be followed by 4 hex digits: \\" - << string(hex_start, p+1-hex_start); + << std::string(hex_start, p+1-hex_start); break; } } @@ -405,7 +404,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest, if (newrune > 0x10FFFF) { LOG_STRING(ERROR, errors) << "Value of \\" - << string(hex_start, p + 1 - hex_start) + << std::string(hex_start, p + 1 - hex_start) << " exceeds Unicode limit (0x10FFFF)"; break; } else { @@ -414,7 +413,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest, } else { LOG_STRING(ERROR, errors) << "\\U must be followed by 8 hex digits: \\" - << string(hex_start, p+1-hex_start); + << std::string(hex_start, p+1-hex_start); break; } } @@ -446,12 +445,12 @@ int UnescapeCEscapeSequences(const char* source, char* dest, // In the first and second calls, the length of dest is returned. In the // the third call, the new string is returned. // ---------------------------------------------------------------------- -int UnescapeCEscapeString(const string& src, string* dest) { +int UnescapeCEscapeString(const std::string &src, std::string *dest) { return UnescapeCEscapeString(src, dest, nullptr); } -int UnescapeCEscapeString(const string& src, string* dest, - std::vector *errors) { +int UnescapeCEscapeString(const std::string &src, std::string *dest, + std::vector *errors) { std::unique_ptr unescaped(new char[src.size() + 1]); int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors); GOOGLE_CHECK(dest); @@ -459,10 +458,10 @@ int UnescapeCEscapeString(const string& src, string* dest, return len; } -string UnescapeCEscapeString(const string& src) { +std::string UnescapeCEscapeString(const std::string &src) { std::unique_ptr unescaped(new char[src.size() + 1]); int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), nullptr); - return string(unescaped.get(), len); + return std::string(unescaped.get(), len); } // ---------------------------------------------------------------------- @@ -559,7 +558,7 @@ static inline size_t CEscapedLength(StringPiece src) { // the required space using a lookup table, and also does not do any special // handling for Hex or UTF-8 characters. // ---------------------------------------------------------------------- -void CEscapeAndAppend(StringPiece src, string* dest) { +void CEscapeAndAppend(StringPiece src, std::string *dest) { size_t escaped_len = CEscapedLength(src); if (escaped_len == src.size()) { dest->append(src.data(), src.size()); @@ -593,30 +592,30 @@ void CEscapeAndAppend(StringPiece src, string* dest) { } } -string CEscape(const string& src) { - string dest; +std::string CEscape(const std::string &src) { + std::string dest; CEscapeAndAppend(src, &dest); return dest; } namespace strings { -string Utf8SafeCEscape(const string& src) { +std::string Utf8SafeCEscape(const std::string &src) { const int dest_length = src.size() * 4 + 1; // Maximum possible expansion std::unique_ptr dest(new char[dest_length]); const int len = CEscapeInternal(src.data(), src.size(), dest.get(), dest_length, false, true); GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); + return std::string(dest.get(), len); } -string CHexEscape(const string& src) { +std::string CHexEscape(const std::string &src) { const int dest_length = src.size() * 4 + 1; // Maximum possible expansion std::unique_ptr dest(new char[dest_length]); const int len = CEscapeInternal(src.data(), src.size(), dest.get(), dest_length, true, false); GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); + return std::string(dest.get(), len); } } // namespace strings @@ -664,8 +663,8 @@ uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) { return static_cast(result); } -inline bool safe_parse_sign(string* text /*inout*/, - bool* negative_ptr /*output*/) { +inline bool safe_parse_sign(std::string *text /*inout*/, + bool *negative_ptr /*output*/) { const char* start = text->data(); const char* end = start + text->size(); @@ -692,9 +691,8 @@ inline bool safe_parse_sign(string* text /*inout*/, return true; } -template -bool safe_parse_positive_int( - string text, IntType* value_p) { +template +bool safe_parse_positive_int(std::string text, IntType *value_p) { int base = 10; IntType value = 0; const IntType vmax = std::numeric_limits::max(); @@ -726,9 +724,8 @@ bool safe_parse_positive_int( return true; } -template -bool safe_parse_negative_int( - const string& text, IntType* value_p) { +template +bool safe_parse_negative_int(const std::string &text, IntType *value_p) { int base = 10; IntType value = 0; const IntType vmin = std::numeric_limits::min(); @@ -767,8 +764,8 @@ bool safe_parse_negative_int( return true; } -template -bool safe_int_internal(string text, IntType* value_p) { +template +bool safe_int_internal(std::string text, IntType *value_p) { *value_p = 0; bool negative; if (!safe_parse_sign(&text, &negative)) { @@ -781,8 +778,8 @@ bool safe_int_internal(string text, IntType* value_p) { } } -template -bool safe_uint_internal(string text, IntType* value_p) { +template +bool safe_uint_internal(std::string text, IntType *value_p) { *value_p = 0; bool negative; if (!safe_parse_sign(&text, &negative) || negative) { @@ -1116,46 +1113,46 @@ char* FastInt64ToBufferLeft(int64 i, char* buffer) { // Return value: string // ---------------------------------------------------------------------- -string SimpleItoa(int i) { +std::string SimpleItoa(int i) { char buffer[kFastToBufferSize]; return (sizeof(i) == 4) ? FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer); } -string SimpleItoa(unsigned int i) { +std::string SimpleItoa(unsigned int i) { char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); + return std::string(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); } -string SimpleItoa(long i) { +std::string SimpleItoa(long i) { char buffer[kFastToBufferSize]; return (sizeof(i) == 4) ? FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer); } -string SimpleItoa(unsigned long i) { +std::string SimpleItoa(unsigned long i) { char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); + return std::string(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); } -string SimpleItoa(long long i) { +std::string SimpleItoa(long long i) { char buffer[kFastToBufferSize]; return (sizeof(i) == 4) ? FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer); } -string SimpleItoa(unsigned long long i) { +std::string SimpleItoa(unsigned long long i) { char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); + return std::string(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); } // ---------------------------------------------------------------------- @@ -1199,12 +1196,12 @@ string SimpleItoa(unsigned long long i) { // implementation. // ---------------------------------------------------------------------- -string SimpleDtoa(double value) { +std::string SimpleDtoa(double value) { char buffer[kDoubleToBufferSize]; return DoubleToBuffer(value, buffer); } -string SimpleFtoa(float value) { +std::string SimpleFtoa(float value) { char buffer[kFloatToBufferSize]; return FloatToBuffer(value, buffer); } @@ -1344,19 +1341,19 @@ bool safe_strtod(const char* str, double* value) { return *str != '\0' && *endptr == '\0'; } -bool safe_strto32(const string& str, int32* value) { +bool safe_strto32(const std::string &str, int32 *value) { return safe_int_internal(str, value); } -bool safe_strtou32(const string& str, uint32* value) { +bool safe_strtou32(const std::string &str, uint32 *value) { return safe_uint_internal(str, value); } -bool safe_strto64(const string& str, int64* value) { +bool safe_strto64(const std::string &str, int64 *value) { return safe_int_internal(str, value); } -bool safe_strtou64(const string& str, uint64* value) { +bool safe_strtou64(const std::string &str, uint64 *value) { return safe_uint_internal(str, value); } @@ -1472,8 +1469,8 @@ static char *Append4(char *out, const AlphaNum &x1, const AlphaNum &x2, return out; } -string StrCat(const AlphaNum &a, const AlphaNum &b) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b) { + std::string result; result.resize(a.size() + b.size()); char *const begin = &*result.begin(); char *out = Append2(begin, a, b); @@ -1481,8 +1478,8 @@ string StrCat(const AlphaNum &a, const AlphaNum &b) { return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { + std::string result; result.resize(a.size() + b.size() + c.size()); char *const begin = &*result.begin(); char *out = Append2(begin, a, b); @@ -1491,9 +1488,9 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size()); char *const begin = &*result.begin(); char *out = Append4(begin, a, b, c, d); @@ -1501,9 +1498,9 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size()); char *const begin = &*result.begin(); char *out = Append4(begin, a, b, c, d); @@ -1512,9 +1509,9 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size()); char *const begin = &*result.begin(); @@ -1524,10 +1521,10 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() + g.size()); char *const begin = &*result.begin(); @@ -1538,10 +1535,10 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g, const AlphaNum &h) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g, const AlphaNum &h) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() + g.size() + h.size()); char *const begin = &*result.begin(); @@ -1551,10 +1548,10 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() + g.size() + h.size() + i.size()); char *const begin = &*result.begin(); @@ -1573,27 +1570,27 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, GOOGLE_DCHECK_GT(uintptr_t((src).data() - (dest).data()), \ uintptr_t((dest).size())) -void StrAppend(string *result, const AlphaNum &a) { +void StrAppend(std::string *result, const AlphaNum &a) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); result->append(a.data(), a.size()); } -void StrAppend(string *result, const AlphaNum &a, const AlphaNum &b) { +void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); GOOGLE_DCHECK_NO_OVERLAP(*result, b); - string::size_type old_size = result->size(); + std::string::size_type old_size = result->size(); result->resize(old_size + a.size() + b.size()); char *const begin = &*result->begin(); char *out = Append2(begin + old_size, a, b); GOOGLE_DCHECK_EQ(out, begin + result->size()); } -void StrAppend(string *result, - const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { +void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b, + const AlphaNum &c) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); GOOGLE_DCHECK_NO_OVERLAP(*result, b); GOOGLE_DCHECK_NO_OVERLAP(*result, c); - string::size_type old_size = result->size(); + std::string::size_type old_size = result->size(); result->resize(old_size + a.size() + b.size() + c.size()); char *const begin = &*result->begin(); char *out = Append2(begin + old_size, a, b); @@ -1601,32 +1598,29 @@ void StrAppend(string *result, GOOGLE_DCHECK_EQ(out, begin + result->size()); } -void StrAppend(string *result, - const AlphaNum &a, const AlphaNum &b, +void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, const AlphaNum &d) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); GOOGLE_DCHECK_NO_OVERLAP(*result, b); GOOGLE_DCHECK_NO_OVERLAP(*result, c); GOOGLE_DCHECK_NO_OVERLAP(*result, d); - string::size_type old_size = result->size(); + std::string::size_type old_size = result->size(); result->resize(old_size + a.size() + b.size() + c.size() + d.size()); char *const begin = &*result->begin(); char *out = Append4(begin + old_size, a, b, c, d); GOOGLE_DCHECK_EQ(out, begin + result->size()); } -int GlobalReplaceSubstring(const string& substring, - const string& replacement, - string* s) { +int GlobalReplaceSubstring(const std::string &substring, + const std::string &replacement, std::string *s) { GOOGLE_CHECK(s != nullptr); if (s->empty() || substring.empty()) return 0; - string tmp; + std::string tmp; int num_replacements = 0; int pos = 0; for (int match_pos = s->find(substring.data(), pos, substring.length()); - match_pos != string::npos; - pos = match_pos + substring.length(), + match_pos != std::string::npos; pos = match_pos + substring.length(), match_pos = s->find(substring.data(), pos, substring.length())) { ++num_replacements; // Append the original content before the match. @@ -2057,8 +2051,8 @@ int WebSafeBase64Unescape(const char *src, int szsrc, char *dest, int szdest) { return Base64UnescapeInternal(src, szsrc, dest, szdest, kUnWebSafeBase64); } -static bool Base64UnescapeInternal(const char* src, int slen, string* dest, - const signed char* unbase64) { +static bool Base64UnescapeInternal(const char *src, int slen, std::string *dest, + const signed char *unbase64) { // Determine the size of the output string. Base64 encodes every 3 bytes into // 4 characters. any leftover chars are added directly for good measure. // This is documented in the base64 RFC: http://tools.ietf.org/html/rfc3548 @@ -2082,11 +2076,11 @@ static bool Base64UnescapeInternal(const char* src, int slen, string* dest, return true; } -bool Base64Unescape(StringPiece src, string* dest) { +bool Base64Unescape(StringPiece src, std::string *dest) { return Base64UnescapeInternal(src.data(), src.size(), dest, kUnBase64); } -bool WebSafeBase64Unescape(StringPiece src, string* dest) { +bool WebSafeBase64Unescape(StringPiece src, std::string *dest) { return Base64UnescapeInternal(src.data(), src.size(), dest, kUnWebSafeBase64); } @@ -2205,9 +2199,9 @@ int WebSafeBase64Escape(const unsigned char *src, int szsrc, char *dest, kWebSafeBase64Chars, do_padding); } -void Base64EscapeInternal(const unsigned char* src, int szsrc, - string* dest, bool do_padding, - const char* base64_chars) { +void Base64EscapeInternal(const unsigned char *src, int szsrc, + std::string *dest, bool do_padding, + const char *base64_chars) { const int calc_escaped_size = CalculateBase64EscapedLen(szsrc, do_padding); dest->resize(calc_escaped_size); @@ -2220,27 +2214,27 @@ void Base64EscapeInternal(const unsigned char* src, int szsrc, dest->erase(escaped_len); } -void Base64Escape(const unsigned char *src, int szsrc, - string* dest, bool do_padding) { +void Base64Escape(const unsigned char *src, int szsrc, std::string *dest, + bool do_padding) { Base64EscapeInternal(src, szsrc, dest, do_padding, kBase64Chars); } -void WebSafeBase64Escape(const unsigned char *src, int szsrc, - string *dest, bool do_padding) { +void WebSafeBase64Escape(const unsigned char *src, int szsrc, std::string *dest, + bool do_padding) { Base64EscapeInternal(src, szsrc, dest, do_padding, kWebSafeBase64Chars); } -void Base64Escape(StringPiece src, string* dest) { +void Base64Escape(StringPiece src, std::string *dest) { Base64Escape(reinterpret_cast(src.data()), src.size(), dest, true); } -void WebSafeBase64Escape(StringPiece src, string* dest) { +void WebSafeBase64Escape(StringPiece src, std::string *dest) { WebSafeBase64Escape(reinterpret_cast(src.data()), src.size(), dest, false); } -void WebSafeBase64EscapeWithPadding(StringPiece src, string* dest) { +void WebSafeBase64EscapeWithPadding(StringPiece src, std::string *dest) { WebSafeBase64Escape(reinterpret_cast(src.data()), src.size(), dest, true); } @@ -2336,19 +2330,19 @@ int UTF8FirstLetterNumBytes(const char* src, int len) { // (1) determines the presence of LF (first one is ok) // (2) if yes, removes any CR, else convert every CR to LF -void CleanStringLineEndings(const string &src, string *dst, +void CleanStringLineEndings(const std::string &src, std::string *dst, bool auto_end_last_line) { if (dst->empty()) { dst->append(src); CleanStringLineEndings(dst, auto_end_last_line); } else { - string tmp = src; + std::string tmp = src; CleanStringLineEndings(&tmp, auto_end_last_line); dst->append(tmp); } } -void CleanStringLineEndings(string *str, bool auto_end_last_line) { +void CleanStringLineEndings(std::string *str, bool auto_end_last_line) { ptrdiff_t output_pos = 0; bool r_seen = false; ptrdiff_t len = str->size(); @@ -2379,7 +2373,7 @@ void CleanStringLineEndings(string *str, bool auto_end_last_line) { continue; } } - string::const_reference in = p[input_pos]; + std::string::const_reference in = p[input_pos]; if (in == '\r') { if (r_seen) p[output_pos++] = '\n'; r_seen = true; diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h index c070a05fd4..8ce81f28c3 100644 --- a/src/google/protobuf/stubs/strutil.h +++ b/src/google/protobuf/stubs/strutil.h @@ -118,7 +118,8 @@ inline bool HasPrefixString(StringPiece str, StringPiece prefix) { memcmp(str.data(), prefix.data(), prefix.size()) == 0; } -inline string StripPrefixString(const string& str, const string& prefix) { +inline std::string StripPrefixString(const std::string& str, + const std::string& prefix) { if (HasPrefixString(str, prefix)) { return str.substr(prefix.size()); } else { @@ -140,7 +141,8 @@ inline bool HasSuffixString(StringPiece str, StringPiece suffix) { suffix.size()) == 0; } -inline string StripSuffixString(const string& str, const string& suffix) { +inline std::string StripSuffixString(const std::string& str, + const std::string& suffix) { if (HasSuffixString(str, suffix)) { return str.substr(0, str.size() - suffix.size()); } else { @@ -157,10 +159,10 @@ inline string StripSuffixString(const string& str, const string& suffix) { // StripWhitespace // Removes whitespaces from both ends of the given string. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void ReplaceCharacters(string* s, const char* remove, +PROTOBUF_EXPORT void ReplaceCharacters(std::string* s, const char* remove, char replacewith); -PROTOBUF_EXPORT void StripWhitespace(string* s); +PROTOBUF_EXPORT void StripWhitespace(std::string* s); // ---------------------------------------------------------------------- // LowerString() @@ -172,26 +174,26 @@ PROTOBUF_EXPORT void StripWhitespace(string* s); // strings. // ---------------------------------------------------------------------- -inline void LowerString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { +inline void LowerString(std::string* s) { + std::string::iterator end = s->end(); + for (std::string::iterator i = s->begin(); i != end; ++i) { // tolower() changes based on locale. We don't want this! if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A'; } } -inline void UpperString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { +inline void UpperString(std::string* s) { + std::string::iterator end = s->end(); + for (std::string::iterator i = s->begin(); i != end; ++i) { // toupper() changes based on locale. We don't want this! if ('a' <= *i && *i <= 'z') *i += 'A' - 'a'; } } -inline void ToUpper(string* s) { UpperString(s); } +inline void ToUpper(std::string* s) { UpperString(s); } -inline string ToUpper(const string& s) { - string out = s; +inline std::string ToUpper(const std::string& s) { + std::string out = s; UpperString(&out); return out; } @@ -204,8 +206,10 @@ inline string ToUpper(const string& s) { // happened or not. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all); +PROTOBUF_EXPORT std::string StringReplace(const std::string& s, + const std::string& oldsub, + const std::string& newsub, + bool replace_all); // ---------------------------------------------------------------------- // SplitStringUsing() @@ -214,7 +218,7 @@ PROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, // over all of them. // ---------------------------------------------------------------------- PROTOBUF_EXPORT void SplitStringUsing(StringPiece full, const char* delim, - std::vector* res); + std::vector* res); // Split a string using one or more byte delimiters, presented // as a nul-terminated c string. Append the components to 'result'. @@ -225,15 +229,15 @@ PROTOBUF_EXPORT void SplitStringUsing(StringPiece full, const char* delim, // If "full" is the empty string, yields an empty string as the only value. // ---------------------------------------------------------------------- PROTOBUF_EXPORT void SplitStringAllowEmpty(StringPiece full, const char* delim, - std::vector* result); + std::vector* result); // ---------------------------------------------------------------------- // Split() // Split a string using a character delimiter. // ---------------------------------------------------------------------- -inline std::vector Split(StringPiece full, const char* delim, - bool skip_empty = true) { - std::vector result; +inline std::vector Split(StringPiece full, const char* delim, + bool skip_empty = true) { + std::vector result; if (skip_empty) { SplitStringUsing(full, delim, &result); } else { @@ -250,12 +254,12 @@ inline std::vector Split(StringPiece full, const char* delim, // another takes a pointer to the target string. In the latter case the // target string is cleared and overwritten. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void JoinStrings(const std::vector& components, - const char* delim, string* result); +PROTOBUF_EXPORT void JoinStrings(const std::vector& components, + const char* delim, std::string* result); -inline string JoinStrings(const std::vector& components, - const char* delim) { - string result; +inline std::string JoinStrings(const std::vector& components, + const char* delim) { + std::string result; JoinStrings(components, delim, &result); return result; } @@ -293,7 +297,7 @@ inline string JoinStrings(const std::vector& components, PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest); PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, - std::vector* errors); + std::vector* errors); // ---------------------------------------------------------------------- // UnescapeCEscapeString() @@ -310,10 +314,12 @@ PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, // the third call, the new string is returned. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest); -PROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest, - std::vector* errors); -PROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); +PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src, + std::string* dest); +PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src, + std::string* dest, + std::vector* errors); +PROTOBUF_EXPORT std::string UnescapeCEscapeString(const std::string& src); // ---------------------------------------------------------------------- // CEscape() @@ -322,21 +328,21 @@ PROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); // // Escaped chars: \n, \r, \t, ", ', \, and !isprint(). // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string CEscape(const string& src); +PROTOBUF_EXPORT std::string CEscape(const std::string& src); // ---------------------------------------------------------------------- // CEscapeAndAppend() // Escapes 'src' using C-style escape sequences, and appends the escaped // string to 'dest'. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, string* dest); +PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, std::string* dest); namespace strings { // Like CEscape() but does not escape bytes with the upper bit set. -PROTOBUF_EXPORT string Utf8SafeCEscape(const string& src); +PROTOBUF_EXPORT std::string Utf8SafeCEscape(const std::string& src); // Like CEscape() but uses hex (\x) escapes instead of octals. -PROTOBUF_EXPORT string CHexEscape(const string& src); +PROTOBUF_EXPORT std::string CHexEscape(const std::string& src); } // namespace strings // ---------------------------------------------------------------------- @@ -393,31 +399,31 @@ inline uint64 strtou64(const char *nptr, char **endptr, int base) { // ---------------------------------------------------------------------- PROTOBUF_EXPORT bool safe_strtob(StringPiece str, bool* value); -PROTOBUF_EXPORT bool safe_strto32(const string& str, int32* value); -PROTOBUF_EXPORT bool safe_strtou32(const string& str, uint32* value); +PROTOBUF_EXPORT bool safe_strto32(const std::string& str, int32* value); +PROTOBUF_EXPORT bool safe_strtou32(const std::string& str, uint32* value); inline bool safe_strto32(const char* str, int32* value) { - return safe_strto32(string(str), value); + return safe_strto32(std::string(str), value); } inline bool safe_strto32(StringPiece str, int32* value) { return safe_strto32(str.ToString(), value); } inline bool safe_strtou32(const char* str, uint32* value) { - return safe_strtou32(string(str), value); + return safe_strtou32(std::string(str), value); } inline bool safe_strtou32(StringPiece str, uint32* value) { return safe_strtou32(str.ToString(), value); } -PROTOBUF_EXPORT bool safe_strto64(const string& str, int64* value); -PROTOBUF_EXPORT bool safe_strtou64(const string& str, uint64* value); +PROTOBUF_EXPORT bool safe_strto64(const std::string& str, int64* value); +PROTOBUF_EXPORT bool safe_strtou64(const std::string& str, uint64* value); inline bool safe_strto64(const char* str, int64* value) { - return safe_strto64(string(str), value); + return safe_strto64(std::string(str), value); } inline bool safe_strto64(StringPiece str, int64* value) { return safe_strto64(str.ToString(), value); } inline bool safe_strtou64(const char* str, uint64* value) { - return safe_strtou64(string(str), value); + return safe_strtou64(std::string(str), value); } inline bool safe_strtou64(StringPiece str, uint64* value) { return safe_strtou64(str.ToString(), value); @@ -425,10 +431,10 @@ inline bool safe_strtou64(StringPiece str, uint64* value) { PROTOBUF_EXPORT bool safe_strtof(const char* str, float* value); PROTOBUF_EXPORT bool safe_strtod(const char* str, double* value); -inline bool safe_strtof(const string& str, float* value) { +inline bool safe_strtof(const std::string& str, float* value) { return safe_strtof(str.c_str(), value); } -inline bool safe_strtod(const string& str, double* value) { +inline bool safe_strtod(const std::string& str, double* value) { return safe_strtod(str.c_str(), value); } inline bool safe_strtof(StringPiece str, float* value) { @@ -521,9 +527,7 @@ inline char* FastUInt64ToBuffer(uint64 i, char* buffer) { return buffer; } -inline string SimpleBtoa(bool value) { - return value ? "true" : "false"; -} +inline std::string SimpleBtoa(bool value) { return value ? "true" : "false"; } // ---------------------------------------------------------------------- // SimpleItoa() @@ -531,12 +535,12 @@ inline string SimpleBtoa(bool value) { // // Return value: string // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string SimpleItoa(int i); -PROTOBUF_EXPORT string SimpleItoa(unsigned int i); -PROTOBUF_EXPORT string SimpleItoa(long i); -PROTOBUF_EXPORT string SimpleItoa(unsigned long i); -PROTOBUF_EXPORT string SimpleItoa(long long i); -PROTOBUF_EXPORT string SimpleItoa(unsigned long long i); +PROTOBUF_EXPORT std::string SimpleItoa(int i); +PROTOBUF_EXPORT std::string SimpleItoa(unsigned int i); +PROTOBUF_EXPORT std::string SimpleItoa(long i); +PROTOBUF_EXPORT std::string SimpleItoa(unsigned long i); +PROTOBUF_EXPORT std::string SimpleItoa(long long i); +PROTOBUF_EXPORT std::string SimpleItoa(unsigned long long i); // ---------------------------------------------------------------------- // SimpleDtoa() @@ -557,8 +561,8 @@ PROTOBUF_EXPORT string SimpleItoa(unsigned long long i); // // Return value: string // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string SimpleDtoa(double value); -PROTOBUF_EXPORT string SimpleFtoa(float value); +PROTOBUF_EXPORT std::string SimpleDtoa(double value); +PROTOBUF_EXPORT std::string SimpleFtoa(float value); PROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer); PROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer); @@ -654,7 +658,7 @@ struct PROTOBUF_EXPORT AlphaNum { // TODO: Add a string_ref constructor, eventually // AlphaNum(const StringPiece &pc) : piece(pc) {} - AlphaNum(const string& str) + AlphaNum(const std::string& str) : piece_data_(str.data()), piece_size_(str.size()) {} AlphaNum(StringPiece str) @@ -702,32 +706,34 @@ using strings::AlphaNum; // be a reference into str. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f, - const AlphaNum& g); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f, - const AlphaNum& g, const AlphaNum& h); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f, - const AlphaNum& g, const AlphaNum& h, - const AlphaNum& i); - -inline string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); } +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h, + const AlphaNum& i); + +inline std::string StrCat(const AlphaNum& a) { + return std::string(a.data(), a.size()); +} // ---------------------------------------------------------------------- // StrAppend() @@ -750,12 +756,12 @@ inline string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); } // worked around as consecutive calls to StrAppend are quite efficient. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a); -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a); +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b); -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, const AlphaNum& c); -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d); @@ -765,8 +771,8 @@ PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, // the C-string "delim" as a separator between components. // ---------------------------------------------------------------------- template -void Join(Iterator start, Iterator end, - const char* delim, string* result) { +void Join(Iterator start, Iterator end, const char* delim, + std::string* result) { for (Iterator it = start; it != end; ++it) { if (it != start) { result->append(delim); @@ -776,9 +782,8 @@ void Join(Iterator start, Iterator end, } template -string Join(const Range& components, - const char* delim) { - string result; +std::string Join(const Range& components, const char* delim) { + std::string result; Join(components.begin(), components.end(), delim, &result); return result; } @@ -787,7 +792,7 @@ string Join(const Range& components, // ToHex() // Return a lower-case hex string representation of the given integer. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string ToHex(uint64 num); +PROTOBUF_EXPORT std::string ToHex(uint64 num); // ---------------------------------------------------------------------- // GlobalReplaceSubstring() @@ -796,9 +801,9 @@ PROTOBUF_EXPORT string ToHex(uint64 num); // // NOTE: The string pieces must not overlap s. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT int GlobalReplaceSubstring(const string& substring, - const string& replacement, - string* s); +PROTOBUF_EXPORT int GlobalReplaceSubstring(const std::string& substring, + const std::string& replacement, + std::string* s); // ---------------------------------------------------------------------- // Base64Unescape() @@ -806,7 +811,7 @@ PROTOBUF_EXPORT int GlobalReplaceSubstring(const string& substring, // writes it to "dest". If src contains invalid characters, dest is cleared // and the function returns false. Returns true on success. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, string* dest); +PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, std::string* dest); // ---------------------------------------------------------------------- // WebSafeBase64Unescape() @@ -821,7 +826,7 @@ PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, string* dest); // ---------------------------------------------------------------------- PROTOBUF_EXPORT int WebSafeBase64Unescape(const char* src, int slen, char* dest, int szdest); -PROTOBUF_EXPORT bool WebSafeBase64Unescape(StringPiece src, string* dest); +PROTOBUF_EXPORT bool WebSafeBase64Unescape(StringPiece src, std::string* dest); // Return the length to use for the output buffer given to the base64 escape // routines. Make sure to use the same value for do_padding in both. @@ -849,17 +854,17 @@ PROTOBUF_EXPORT int WebSafeBase64Escape(const unsigned char* src, int slen, char* dest, int szdest, bool do_padding); // Encode src into dest with padding. -PROTOBUF_EXPORT void Base64Escape(StringPiece src, string* dest); +PROTOBUF_EXPORT void Base64Escape(StringPiece src, std::string* dest); // Encode src into dest web-safely without padding. -PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, string* dest); +PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, std::string* dest); // Encode src into dest web-safely with padding. PROTOBUF_EXPORT void WebSafeBase64EscapeWithPadding(StringPiece src, - string* dest); + std::string* dest); PROTOBUF_EXPORT void Base64Escape(const unsigned char* src, int szsrc, - string* dest, bool do_padding); + std::string* dest, bool do_padding); PROTOBUF_EXPORT void WebSafeBase64Escape(const unsigned char* src, int szsrc, - string* dest, bool do_padding); + std::string* dest, bool do_padding); inline bool IsValidCodePoint(uint32 code_point) { return code_point < 0xD800 || @@ -915,11 +920,12 @@ PROTOBUF_EXPORT int UTF8FirstLetterNumBytes(const char* src, int len); // // (1) determines the presence of LF (first one is ok) // (2) if yes, removes any CR, else convert every CR to LF -PROTOBUF_EXPORT void CleanStringLineEndings(const string& src, string* dst, +PROTOBUF_EXPORT void CleanStringLineEndings(const std::string& src, + std::string* dst, bool auto_end_last_line); // Same as above, but transforms the argument in place. -PROTOBUF_EXPORT void CleanStringLineEndings(string* str, +PROTOBUF_EXPORT void CleanStringLineEndings(std::string* str, bool auto_end_last_line); namespace strings { diff --git a/src/google/protobuf/stubs/strutil_unittest.cc b/src/google/protobuf/stubs/strutil_unittest.cc index 141d263a40..fc9a63f3f2 100644 --- a/src/google/protobuf/stubs/strutil_unittest.cc +++ b/src/google/protobuf/stubs/strutil_unittest.cc @@ -52,7 +52,7 @@ TEST(StringUtilityTest, ImmuneToLocales) { // Remember the old locale. char* old_locale_cstr = setlocale(LC_NUMERIC, nullptr); ASSERT_TRUE(old_locale_cstr != nullptr); - string old_locale = old_locale_cstr; + std::string old_locale = old_locale_cstr; // Set the locale to "C". ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != nullptr); @@ -442,7 +442,7 @@ TEST(Base64, EscapeAndUnescape) { char decode_buffer[100]; int decode_length; int cypher_length; - string decode_str; + std::string decode_str; const unsigned char* unsigned_plaintext = reinterpret_cast(base64_tests[i].plaintext); @@ -491,13 +491,13 @@ TEST(Base64, EscapeAndUnescape) { EXPECT_EQ(plaintext, decode_str); // Let's try with a pre-populated string. - string encoded("this junk should be ignored"); - Base64Escape(string(base64_tests[i].plaintext, - base64_tests[i].plain_length), - &encoded); - EXPECT_EQ(encoded, string(encode_buffer, cypher_length)); + std::string encoded("this junk should be ignored"); + Base64Escape( + std::string(base64_tests[i].plaintext, base64_tests[i].plain_length), + &encoded); + EXPECT_EQ(encoded, std::string(encode_buffer, cypher_length)); - string decoded("this junk should be ignored"); + std::string decoded("this junk should be ignored"); EXPECT_TRUE(Base64Unescape( StringPiece(encode_buffer, cypher_length), &decoded)); EXPECT_EQ(decoded.size(), base64_tests[i].plain_length); @@ -514,7 +514,7 @@ TEST(Base64, EscapeAndUnescape) { // Try chopping off the equals sign(s) entirely. The decoder // should still be okay with this. - string decoded2("this junk should also be ignored"); + std::string decoded2("this junk should also be ignored"); *first_equals = '\0'; EXPECT_TRUE(Base64Unescape( StringPiece(encode_buffer, first_equals - encode_buffer), &decoded2)); @@ -730,7 +730,7 @@ TEST(Base64, EscapeAndUnescape) { EXPECT_STREQ(encode_buffer, websafe); // Let's try the (other) string version of the encoder - string plain(base64_tests[i].plaintext, base64_tests[i].plain_length); + std::string plain(base64_tests[i].plaintext, base64_tests[i].plain_length); encoded = "this junk should be ignored"; WebSafeBase64Escape(plain, &encoded); EXPECT_EQ(encoded.size(), cypher_length); @@ -798,7 +798,7 @@ TEST(Base64, EscapeAndUnescape) { // Verify the behavior when decoding bad data { const char* bad_data = "ab-/"; - string buf; + std::string buf; EXPECT_FALSE(Base64Unescape(StringPiece(bad_data), &buf)); EXPECT_TRUE(!WebSafeBase64Unescape(bad_data, &buf)); EXPECT_TRUE(buf.empty()); @@ -819,7 +819,7 @@ TEST(StrCat, Ints) { const size_t size = 10; const intptr_t intptr = -12; const uintptr_t uintptr = 13; - string answer; + std::string answer; answer = StrCat(s, us); EXPECT_EQ(answer, "-12"); answer = StrCat(i, ui); @@ -836,12 +836,13 @@ TEST(StrCat, Ints) { EXPECT_EQ(answer, "130"); } -class ReplaceChars : public ::testing::TestWithParam< - std::tuple> {}; +class ReplaceChars + : public ::testing::TestWithParam< + std::tuple> {}; TEST_P(ReplaceChars, ReplacesAllOccurencesOfAnyCharInReplaceWithAReplaceChar) { - string expected = std::get<0>(GetParam()); - string string_to_replace_in = std::get<1>(GetParam()); + std::string expected = std::get<0>(GetParam()); + std::string string_to_replace_in = std::get<1>(GetParam()); const char* what_to_replace = std::get<2>(GetParam()); char replacement = std::get<3>(GetParam()); ReplaceCharacters(&string_to_replace_in, what_to_replace, replacement); @@ -864,11 +865,12 @@ INSTANTIATE_TEST_CASE_P( std::make_tuple("qvvvvvng v T", "queueing a T", "aeiou", 'v'))); // replace all voewls -class StripWs : public ::testing::TestWithParam> {}; +class StripWs + : public ::testing::TestWithParam> {}; TEST_P(StripWs, AlwaysStripsLeadingAndTrailingWhitespace) { - string expected = std::get<0>(GetParam()); - string string_to_strip = std::get<1>(GetParam()); + std::string expected = std::get<0>(GetParam()); + std::string string_to_strip = std::get<1>(GetParam()); StripWhitespace(&string_to_strip); ASSERT_EQ(expected, string_to_strip); } diff --git a/src/google/protobuf/stubs/substitute.cc b/src/google/protobuf/stubs/substitute.cc index a36f2f026c..92107416eb 100644 --- a/src/google/protobuf/stubs/substitute.cc +++ b/src/google/protobuf/stubs/substitute.cc @@ -52,26 +52,24 @@ static int CountSubstituteArgs(const SubstituteArg* const* args_array) { return count; } -string Substitute( - const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { - string result; +std::string Substitute(const char* format, const SubstituteArg& arg0, + const SubstituteArg& arg1, const SubstituteArg& arg2, + const SubstituteArg& arg3, const SubstituteArg& arg4, + const SubstituteArg& arg5, const SubstituteArg& arg6, + const SubstituteArg& arg7, const SubstituteArg& arg8, + const SubstituteArg& arg9) { + std::string result; SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); return result; } -void SubstituteAndAppend( - string* output, const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { +void SubstituteAndAppend(std::string* output, const char* format, + const SubstituteArg& arg0, const SubstituteArg& arg1, + const SubstituteArg& arg2, const SubstituteArg& arg3, + const SubstituteArg& arg4, const SubstituteArg& arg5, + const SubstituteArg& arg6, const SubstituteArg& arg7, + const SubstituteArg& arg8, const SubstituteArg& arg9) { const SubstituteArg* const args_array[] = { &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, nullptr }; diff --git a/src/google/protobuf/stubs/substitute.h b/src/google/protobuf/stubs/substitute.h index 267dead236..d4e72e1c51 100644 --- a/src/google/protobuf/stubs/substitute.h +++ b/src/google/protobuf/stubs/substitute.h @@ -90,8 +90,8 @@ class SubstituteArg { public: inline SubstituteArg(const char* value) : text_(value), size_(strlen(text_)) {} - inline SubstituteArg(const string& value) - : text_(value.data()), size_(value.size()) {} + inline SubstituteArg(const std::string& value) + : text_(value.data()), size_(value.size()) {} // Indicates that no argument was given. inline explicit SubstituteArg() @@ -139,21 +139,21 @@ class SubstituteArg { } // namespace internal -PROTOBUF_EXPORT string -Substitute(const char* format, - const internal::SubstituteArg& arg0 = internal::SubstituteArg(), - const internal::SubstituteArg& arg1 = internal::SubstituteArg(), - const internal::SubstituteArg& arg2 = internal::SubstituteArg(), - const internal::SubstituteArg& arg3 = internal::SubstituteArg(), - const internal::SubstituteArg& arg4 = internal::SubstituteArg(), - const internal::SubstituteArg& arg5 = internal::SubstituteArg(), - const internal::SubstituteArg& arg6 = internal::SubstituteArg(), - const internal::SubstituteArg& arg7 = internal::SubstituteArg(), - const internal::SubstituteArg& arg8 = internal::SubstituteArg(), - const internal::SubstituteArg& arg9 = internal::SubstituteArg()); +PROTOBUF_EXPORT std::string Substitute( + const char* format, + const internal::SubstituteArg& arg0 = internal::SubstituteArg(), + const internal::SubstituteArg& arg1 = internal::SubstituteArg(), + const internal::SubstituteArg& arg2 = internal::SubstituteArg(), + const internal::SubstituteArg& arg3 = internal::SubstituteArg(), + const internal::SubstituteArg& arg4 = internal::SubstituteArg(), + const internal::SubstituteArg& arg5 = internal::SubstituteArg(), + const internal::SubstituteArg& arg6 = internal::SubstituteArg(), + const internal::SubstituteArg& arg7 = internal::SubstituteArg(), + const internal::SubstituteArg& arg8 = internal::SubstituteArg(), + const internal::SubstituteArg& arg9 = internal::SubstituteArg()); PROTOBUF_EXPORT void SubstituteAndAppend( - string* output, const char* format, + std::string* output, const char* format, const internal::SubstituteArg& arg0 = internal::SubstituteArg(), const internal::SubstituteArg& arg1 = internal::SubstituteArg(), const internal::SubstituteArg& arg2 = internal::SubstituteArg(), diff --git a/src/google/protobuf/stubs/time.cc b/src/google/protobuf/stubs/time.cc index 64f3ceb9f6..922be76d1b 100644 --- a/src/google/protobuf/stubs/time.cc +++ b/src/google/protobuf/stubs/time.cc @@ -130,7 +130,7 @@ int64 SecondsSinceCommonEra(const DateTime& time) { // Format nanoseconds with either 3, 6, or 9 digits depending on the required // precision to represent the exact value. -string FormatNanos(int32 nanos) { +std::string FormatNanos(int32 nanos) { if (nanos % kNanosPerMillisecond == 0) { return StringPrintf("%03d", nanos / kNanosPerMillisecond); } else if (nanos % kNanosPerMicrosecond == 0) { @@ -268,21 +268,21 @@ void GetCurrentTime(int64* seconds, int32* nanos) { *nanos = 0; } -string FormatTime(int64 seconds, int32 nanos) { +std::string FormatTime(int64 seconds, int32 nanos) { DateTime time; if (nanos < 0 || nanos > 999999999 || !SecondsToDateTime(seconds, &time)) { return "InvalidTime"; } - string result = StringPrintf("%04d-%02d-%02dT%02d:%02d:%02d", - time.year, time.month, time.day, - time.hour, time.minute, time.second); + std::string result = + StringPrintf("%04d-%02d-%02dT%02d:%02d:%02d", time.year, time.month, + time.day, time.hour, time.minute, time.second); if (nanos != 0) { result += "." + FormatNanos(nanos); } return result + "Z"; } -bool ParseTime(const string& value, int64* seconds, int32* nanos) { +bool ParseTime(const std::string& value, int64* seconds, int32* nanos) { DateTime time; const char* data = value.c_str(); // We only accept: diff --git a/src/google/protobuf/stubs/time.h b/src/google/protobuf/stubs/time.h index b52f3f9632..b06117689e 100644 --- a/src/google/protobuf/stubs/time.h +++ b/src/google/protobuf/stubs/time.h @@ -65,10 +65,10 @@ void PROTOBUF_EXPORT GetCurrentTime(int64* seconds, int32* nanos); // value. // // Note that "nanos" must in the range of [0, 999999999]. -string PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos); +std::string PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos); // Parses a time string. This method accepts RFC3339 date/time string with UTC // offset. For example, "2015-05-20T13:29:35.120-08:00". -bool PROTOBUF_EXPORT ParseTime(const string& value, int64* seconds, +bool PROTOBUF_EXPORT ParseTime(const std::string& value, int64* seconds, int32* nanos); } // namespace internal diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc index 7d3708e3d6..7b628879c6 100644 --- a/src/google/protobuf/testing/file.cc +++ b/src/google/protobuf/testing/file.cc @@ -66,11 +66,12 @@ using google::protobuf::io::win32::mkdir; using google::protobuf::io::win32::stat; #endif -bool File::Exists(const string& name) { +bool File::Exists(const std::string& name) { return access(name.c_str(), F_OK) == 0; } -bool File::ReadFileToString(const string& name, string* output, bool text_mode) { +bool File::ReadFileToString(const std::string& name, std::string* output, + bool text_mode) { char buffer[1024]; FILE* file = fopen(name.c_str(), text_mode ? "rt" : "rb"); if (file == NULL) return false; @@ -86,11 +87,12 @@ bool File::ReadFileToString(const string& name, string* output, bool text_mode) return error == 0; } -void File::ReadFileToStringOrDie(const string& name, string* output) { +void File::ReadFileToStringOrDie(const std::string& name, std::string* output) { GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name; } -bool File::WriteStringToFile(const string& contents, const string& name) { +bool File::WriteStringToFile(const std::string& contents, + const std::string& name) { FILE* file = fopen(name.c_str(), "wb"); if (file == NULL) { GOOGLE_LOG(ERROR) << "fopen(" << name << ", \"wb\"): " << strerror(errno); @@ -109,7 +111,8 @@ bool File::WriteStringToFile(const string& contents, const string& name) { return true; } -void File::WriteStringToFileOrDie(const string& contents, const string& name) { +void File::WriteStringToFileOrDie(const std::string& contents, + const std::string& name) { FILE* file = fopen(name.c_str(), "wb"); GOOGLE_CHECK(file != NULL) << "fopen(" << name << ", \"wb\"): " << strerror(errno); @@ -120,21 +123,21 @@ void File::WriteStringToFileOrDie(const string& contents, const string& name) { << "fclose(" << name << "): " << strerror(errno); } -bool File::CreateDir(const string& name, int mode) { +bool File::CreateDir(const std::string& name, int mode) { if (!name.empty()) { GOOGLE_CHECK_OK(name[name.size() - 1] != '.'); } return mkdir(name.c_str(), mode) == 0; } -bool File::RecursivelyCreateDir(const string& path, int mode) { +bool File::RecursivelyCreateDir(const std::string& path, int mode) { if (CreateDir(path, mode)) return true; if (Exists(path)) return false; // Try creating the parent. - string::size_type slashpos = path.find_last_of('/'); - if (slashpos == string::npos) { + std::string::size_type slashpos = path.find_last_of('/'); + if (slashpos == std::string::npos) { // No parent given. return false; } @@ -143,8 +146,8 @@ bool File::RecursivelyCreateDir(const string& path, int mode) { CreateDir(path, mode); } -void File::DeleteRecursively(const string& name, - void* dummy1, void* dummy2) { +void File::DeleteRecursively(const std::string& name, void* dummy1, + void* dummy2) { if (name.empty()) return; // We don't care too much about error checking here since this is only used @@ -162,9 +165,9 @@ void File::DeleteRecursively(const string& name, } do { - string entry_name = find_data.cFileName; + std::string entry_name = find_data.cFileName; if (entry_name != "." && entry_name != "..") { - string path = name + "/" + entry_name; + std::string path = name + "/" + entry_name; if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { DeleteRecursively(path, NULL, NULL); RemoveDirectoryA(path.c_str()); @@ -188,7 +191,7 @@ void File::DeleteRecursively(const string& name, while (true) { struct dirent* entry = readdir(dir); if (entry == NULL) break; - string entry_name = entry->d_name; + std::string entry_name = entry->d_name; if (entry_name != "." && entry_name != "..") { DeleteRecursively(name + "/" + entry_name, NULL, NULL); } @@ -204,7 +207,7 @@ void File::DeleteRecursively(const string& name, #endif } -bool File::ChangeWorkingDirectory(const string& new_working_directory) { +bool File::ChangeWorkingDirectory(const std::string& new_working_directory) { return chdir(new_working_directory.c_str()) == 0; } diff --git a/src/google/protobuf/testing/file.h b/src/google/protobuf/testing/file.h index 45989967c9..f18f685865 100644 --- a/src/google/protobuf/testing/file.h +++ b/src/google/protobuf/testing/file.h @@ -46,52 +46,54 @@ const int DEFAULT_FILE_MODE = 0777; class File { public: // Check if the file exists. - static bool Exists(const string& name); + static bool Exists(const std::string& name); // Read an entire file to a string. Return true if successful, false // otherwise. - static bool ReadFileToString(const string& name, string* output, bool text_mode = false); + static bool ReadFileToString(const std::string& name, std::string* output, + bool text_mode = false); // Same as above, but crash on failure. - static void ReadFileToStringOrDie(const string& name, string* output); + static void ReadFileToStringOrDie(const std::string& name, + std::string* output); // Create a file and write a string to it. - static bool WriteStringToFile(const string& contents, - const string& name); + static bool WriteStringToFile(const std::string& contents, + const std::string& name); // Same as above, but crash on failure. - static void WriteStringToFileOrDie(const string& contents, - const string& name); + static void WriteStringToFileOrDie(const std::string& contents, + const std::string& name); // Create a directory. - static bool CreateDir(const string& name, int mode); + static bool CreateDir(const std::string& name, int mode); // Create a directory and all parent directories if necessary. - static bool RecursivelyCreateDir(const string& path, int mode); + static bool RecursivelyCreateDir(const std::string& path, int mode); // If "name" is a file, we delete it. If it is a directory, we // call DeleteRecursively() for each file or directory (other than // dot and double-dot) within it, and then delete the directory itself. // The "dummy" parameters have a meaning in the original version of this // method but they are not used anywhere in protocol buffers. - static void DeleteRecursively(const string& name, - void* dummy1, void* dummy2); + static void DeleteRecursively(const std::string& name, void* dummy1, + void* dummy2); // Change working directory to given directory. - static bool ChangeWorkingDirectory(const string& new_working_directory); + static bool ChangeWorkingDirectory(const std::string& new_working_directory); - static bool GetContents( - const string& name, string* output, bool /*is_default*/) { + static bool GetContents(const std::string& name, std::string* output, + bool /*is_default*/) { return ReadFileToString(name, output); } - static bool GetContentsAsText( - const string& name, string* output, bool /*is_default*/) { + static bool GetContentsAsText(const std::string& name, std::string* output, + bool /*is_default*/) { return ReadFileToString(name, output, true); } - static bool SetContents( - const string& name, const string& contents, bool /*is_default*/) { + static bool SetContents(const std::string& name, const std::string& contents, + bool /*is_default*/) { return WriteStringToFile(contents, name); } diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc index 1856971cb8..88343f9347 100644 --- a/src/google/protobuf/testing/googletest.cc +++ b/src/google/protobuf/testing/googletest.cc @@ -70,7 +70,7 @@ using google::protobuf::io::win32::open; #endif #endif -string TestSourceDir() { +std::string TestSourceDir() { #ifndef GOOGLE_THIRD_PARTY_PROTOBUF #ifdef GOOGLE_PROTOBUF_TEST_SOURCE_PATH return GOOGLE_PROTOBUF_TEST_SOURCE_PATH; @@ -84,7 +84,7 @@ string TestSourceDir() { #endif // _MSC_VER // Look for the "src" directory. - string prefix = "."; + std::string prefix = "."; // Keep looking further up the directory tree until we find // src/.../descriptor.cc. It is important to look for a particular file, @@ -107,12 +107,12 @@ string TestSourceDir() { namespace { -string GetTemporaryDirectoryName() { +std::string GetTemporaryDirectoryName() { // Tests run under Bazel "should not" use /tmp. Bazel sets this environment // variable for tests to use instead. char *from_environment = getenv("TEST_TMPDIR"); if (from_environment != NULL && from_environment[0] != '\0') { - return string(from_environment) + "/protobuf_tmpdir"; + return std::string(from_environment) + "/protobuf_tmpdir"; } // tmpnam() is generally not considered safe but we're only using it for @@ -121,7 +121,7 @@ string GetTemporaryDirectoryName() { char b[L_tmpnam + 1]; // HPUX multithread return 0 if s is 0 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - string result = tmpnam(b); + std::string result = tmpnam(b); #pragma GCC diagnostic pop #ifdef _WIN32 // Avoid a trailing dot by changing it to an underscore. On Win32 the names of @@ -166,7 +166,7 @@ class TempDirDeleter { } } - string GetTempDir() { + std::string GetTempDir() { if (name_.empty()) { name_ = GetTemporaryDirectoryName(); GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno); @@ -179,21 +179,19 @@ class TempDirDeleter { } private: - string name_; + std::string name_; }; TempDirDeleter temp_dir_deleter_; } // namespace -string TestTempDir() { - return temp_dir_deleter_.GetTempDir(); -} +std::string TestTempDir() { return temp_dir_deleter_.GetTempDir(); } // TODO(kenton): Share duplicated code below. Too busy/lazy for now. -static string stdout_capture_filename_; -static string stderr_capture_filename_; +static std::string stdout_capture_filename_; +static std::string stderr_capture_filename_; static int original_stdout_ = -1; static int original_stderr_ = -1; @@ -227,14 +225,14 @@ void CaptureTestStderr() { close(fd); } -string GetCapturedTestStdout() { +std::string GetCapturedTestStdout() { GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing."; close(1); dup2(original_stdout_, 1); original_stdout_ = -1; - string result; + std::string result; File::ReadFileToStringOrDie(stdout_capture_filename_, &result); remove(stdout_capture_filename_.c_str()); @@ -242,14 +240,14 @@ string GetCapturedTestStdout() { return result; } -string GetCapturedTestStderr() { +std::string GetCapturedTestStderr() { GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing."; close(2); dup2(original_stderr_, 2); original_stderr_ = -1; - string result; + std::string result; File::ReadFileToStringOrDie(stderr_capture_filename_, &result); remove(stderr_capture_filename_.c_str()); @@ -270,14 +268,14 @@ ScopedMemoryLog::~ScopedMemoryLog() { active_log_ = NULL; } -const std::vector& ScopedMemoryLog::GetMessages(LogLevel level) { +const std::vector& ScopedMemoryLog::GetMessages(LogLevel level) { GOOGLE_CHECK(level == ERROR || level == WARNING); return messages_[level]; } -void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, - int line, const string& message) { +void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, int line, + const std::string& message) { GOOGLE_CHECK(active_log_ != NULL); if (level == ERROR || level == WARNING) { active_log_->messages_[level].push_back(message); diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h index 4e0cb83a85..6a0c694e71 100644 --- a/src/google/protobuf/testing/googletest.h +++ b/src/google/protobuf/testing/googletest.h @@ -49,19 +49,19 @@ namespace google { namespace protobuf { // When running unittests, get the directory containing the source code. -string TestSourceDir(); +std::string TestSourceDir(); // When running unittests, get a directory where temporary files may be // placed. -string TestTempDir(); +std::string TestTempDir(); // Capture all text written to stdout or stderr. void CaptureTestStdout(); void CaptureTestStderr(); // Stop capturing stdout or stderr and return the text captured. -string GetCapturedTestStdout(); -string GetCapturedTestStderr(); +std::string GetCapturedTestStdout(); +std::string GetCapturedTestStderr(); // For use with ScopedMemoryLog::GetMessages(). Inside Google the LogLevel // constants don't have the LOGLEVEL_ prefix, so the code that used @@ -84,14 +84,14 @@ class ScopedMemoryLog { virtual ~ScopedMemoryLog(); // Fetches all messages with the given severity level. - const std::vector& GetMessages(LogLevel error); + const std::vector& GetMessages(LogLevel error); private: - std::map > messages_; + std::map > messages_; LogHandler* old_handler_; static void HandleLog(LogLevel level, const char* filename, int line, - const string& message); + const std::string& message); static ScopedMemoryLog* active_log_; diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 323b0e0999..f47d4e8d01 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -2052,8 +2052,8 @@ void TextFormat::Printer::Print(const Message& message, if (print_message_fields_in_index_order_) { std::sort(fields.begin(), fields.end(), FieldIndexSorter()); } - for (int i = 0; i < fields.size(); i++) { - PrintField(message, reflection, fields[i], generator); + for (const FieldDescriptor* field : fields) { + PrintField(message, reflection, field, generator); } if (!hide_unknown_fields_) { PrintUnknownFields(reflection->GetUnknownFields(message), generator, @@ -2312,8 +2312,8 @@ void TextFormat::Printer::PrintField(const Message& message, } if (need_release) { - for (int j = 0; j < sorted_map_field.size(); ++j) { - delete sorted_map_field[j]; + for (const Message* message_to_delete : sorted_map_field) { + delete message_to_delete; } } } diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto index 50bb996002..f774c766e3 100644 --- a/src/google/protobuf/unittest_custom_options.proto +++ b/src/google/protobuf/unittest_custom_options.proto @@ -45,6 +45,7 @@ option py_generic_services = true; // A custom file option (defined below). option (file_opt1) = 9876543210; +import "google/protobuf/any.proto"; import "google/protobuf/descriptor.proto"; // We don't put this in a package within proto2 because we need to make sure @@ -329,6 +330,9 @@ message Aggregate { // An embedded message set optional AggregateMessageSet mset = 5; + + // An any + optional google.protobuf.Any any = 6; } // Allow Aggregate to be used as an option at all possible locations @@ -376,6 +380,12 @@ option (fileopt) = { s: 'EmbeddedMessageSetElement' } } + + any { + [type.googleapis.com/protobuf_unittest.AggregateMessageSetElement] { + s: 'EmbeddedMessageSetElement' + } + } }; message AggregateMessage { diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc index 451209c797..f40a577cb2 100644 --- a/src/google/protobuf/unknown_field_set.cc +++ b/src/google/protobuf/unknown_field_set.cc @@ -108,8 +108,7 @@ size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const { size_t total_size = sizeof(fields_) + sizeof(UnknownField) * fields_.size(); - for (int i = 0; i < fields_.size(); i++) { - const UnknownField& field = (fields_)[i]; + for (const UnknownField& field : fields_) { switch (field.type()) { case UnknownField::TYPE_LENGTH_DELIMITED: total_size += sizeof(*field.data_.length_delimited_.string_value) + diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc index 240db516a4..24a71425ca 100644 --- a/src/google/protobuf/util/internal/proto_writer.cc +++ b/src/google/protobuf/util/internal/proto_writer.cc @@ -69,6 +69,7 @@ ProtoWriter::ProtoWriter(TypeResolver* type_resolver, ignore_unknown_enum_values_(false), use_lower_camel_for_enums_(false), case_insensitive_enum_parsing_(true), + use_json_name_in_missing_fields_(false), element_(nullptr), size_insert_(), output_(output), @@ -90,6 +91,7 @@ ProtoWriter::ProtoWriter(const TypeInfo* typeinfo, ignore_unknown_enum_values_(false), use_lower_camel_for_enums_(false), case_insensitive_enum_parsing_(true), + use_json_name_in_missing_fields_(false), element_(nullptr), size_insert_(), output_(output), @@ -618,26 +620,12 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( // Pushing a ProtoElement and then pop it off at the end for 2 purposes: // error location reporting and required field accounting. // - // For proto3, since there is no required field tracking, we only need to push - // ProtoElement for error cases. + // For proto3, since there is no required field tracking, we only need to + // push ProtoElement for error cases. if (!element_->proto3()) { element_.reset(new ProtoElement(element_.release(), &field, type, false)); } - if (field.kind() == google::protobuf::Field::TYPE_UNKNOWN || - field.kind() == google::protobuf::Field::TYPE_MESSAGE) { - // Push a ProtoElement for location reporting purposes. - if (element_->proto3()) { - element_.reset(new ProtoElement(element_.release(), &field, type, false)); - } - InvalidValue(field.type_url().empty() - ? google::protobuf::Field_Kind_Name(field.kind()) - : field.type_url(), - data.ValueAsStringOrDefault("")); - element_.reset(element()->pop()); - return this; - } - switch (field.kind()) { case google::protobuf::Field::TYPE_INT32: { status = WriteInt32(field.number(), data, stream_.get()); @@ -706,9 +694,9 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( case_insensitive_enum_parsing_, ignore_unknown_enum_values_); break; } - default: // TYPE_GROUP or TYPE_MESSAGE + default: // TYPE_GROUP, TYPE_MESSAGE, TYPE_UNKNOWN. status = util::Status(util::error::INVALID_ARGUMENT, - data.ToString().value()); + data.ValueAsStringOrDefault("")); } if (!status.ok()) { @@ -716,7 +704,9 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( if (element_->proto3()) { element_.reset(new ProtoElement(element_.release(), &field, type, false)); } - InvalidValue(google::protobuf::Field_Kind_Name(field.kind()), + InvalidValue(field.type_url().empty() + ? google::protobuf::Field_Kind_Name(field.kind()) + : field.type_url(), status.message()); element_.reset(element()->pop()); return this; diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index 564050f4f6..211b7bcbf8 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -1000,7 +1000,10 @@ TEST_P(ProtoStreamObjectWriterTest, Proto3Message expected; EXPECT_CALL( listener_, - InvalidValue(_, StringPiece("TYPE_ENUM"), + InvalidValue(_, + StringPiece( + "type.googleapis.com/" + "proto_util_converter.testing.Proto3Message.NestedEnum"), StringPiece("\"someunknownvalueyouwillneverknow\""))) .With(Args<0>(HasObjectLocation("enum_value"))); ow_->StartObject("") diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 1388e9d33a..12cbf945ef 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -112,8 +112,8 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator : message_differencer_(message_differencer), key_field_paths_(key_field_paths) { GOOGLE_CHECK(!key_field_paths_.empty()); - for (int i = 0; i < key_field_paths_.size(); ++i) { - GOOGLE_CHECK(!key_field_paths_[i].empty()); + for (const auto& path : key_field_paths_) { + GOOGLE_CHECK(!path.empty()); } } MultipleFieldsMapKeyComparator(MessageDifferencer* message_differencer, @@ -125,9 +125,8 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator } bool IsMatch(const Message& message1, const Message& message2, const std::vector& parent_fields) const override { - for (int i = 0; i < key_field_paths_.size(); ++i) { - if (!IsMatchInternal(message1, message2, parent_fields, - key_field_paths_[i], 0)) { + for (const auto& path : key_field_paths_) { + if (!IsMatchInternal(message1, message2, parent_fields, path, 0)) { return false; } } @@ -276,11 +275,11 @@ MessageDifferencer::MessageDifferencer() MatchIndicesPostProcessorForSmartList) {} MessageDifferencer::~MessageDifferencer() { - for (int i = 0; i < owned_key_comparators_.size(); ++i) { - delete owned_key_comparators_[i]; + for (MapKeyComparator* comparator : owned_key_comparators_) { + delete comparator; } - for (int i = 0; i < ignore_criteria_.size(); ++i) { - delete ignore_criteria_[i]; + for (IgnoreCriteria* criteria : ignore_criteria_) { + delete criteria; } } @@ -380,9 +379,9 @@ void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey( const FieldDescriptor* field, const std::vector& key_fields) { std::vector > key_field_paths; - for (int i = 0; i < key_fields.size(); ++i) { + for (const FieldDescriptor* key_filed : key_fields) { std::vector key_field_path; - key_field_path.push_back(key_fields[i]); + key_field_path.push_back(key_filed); key_field_paths.push_back(key_field_path); } TreatAsMapWithMultipleFieldPathsAsKey(field, key_field_paths); @@ -395,9 +394,7 @@ void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey( << "Field must be repeated: " << field->full_name(); GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type()) << "Field has to be message type. Field name is: " << field->full_name(); - for (int i = 0; i < key_field_paths.size(); ++i) { - const std::vector& key_field_path = - key_field_paths[i]; + for (const auto& key_field_path : key_field_paths) { for (int j = 0; j < key_field_path.size(); ++j) { const FieldDescriptor* parent_field = j == 0 ? field : key_field_path[j - 1]; @@ -1236,10 +1233,11 @@ bool MessageDifferencer::CompareFieldValueUsingParentFields( bool MessageDifferencer::CheckPathChanged( const std::vector& field_path) { - for (int i = 0; i < field_path.size(); ++i) { + for (const SpecificField& specific_field : field_path) { // Don't check indexes for map entries -- maps are unordered. - if (field_path[i].field != NULL && field_path[i].field->is_map()) continue; - if (field_path[i].index != field_path[i].new_index) return true; + if (specific_field.field != nullptr && specific_field.field->is_map()) + continue; + if (specific_field.index != specific_field.new_index) return true; } return false; } @@ -1286,9 +1284,8 @@ bool MessageDifferencer::IsIgnored( if (ignored_fields_.find(field) != ignored_fields_.end()) { return true; } - for (int i = 0; i < ignore_criteria_.size(); ++i) { - if (ignore_criteria_[i]->IsIgnored(message1, message2, field, - parent_fields)) { + for (IgnoreCriteria* criteria : ignore_criteria_) { + if (criteria->IsIgnored(message1, message2, field, parent_fields)) { return true; } } @@ -1299,9 +1296,9 @@ bool MessageDifferencer::IsUnknownFieldIgnored( const Message& message1, const Message& message2, const SpecificField& field, const std::vector& parent_fields) { - for (int i = 0; i < ignore_criteria_.size(); ++i) { - if (ignore_criteria_[i]->IsUnknownFieldIgnored(message1, message2, field, - parent_fields)) { + for (IgnoreCriteria* criteria : ignore_criteria_) { + if (criteria->IsUnknownFieldIgnored(message1, message2, field, + parent_fields)) { return true; } } diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index 2f40d21eca..2f5908ee1f 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -1462,8 +1462,8 @@ size_t WireFormat::ByteSize(const Message& message) { message_reflection->ListFields(message, &fields); } - for (int i = 0; i < fields.size(); i++) { - our_size += FieldByteSize(fields[i], message); + for (const FieldDescriptor* field : fields) { + our_size += FieldByteSize(field, message); } if (descriptor->options().message_set_wire_format()) { diff --git a/tests.sh b/tests.sh index 8b499d0a3e..5113e4a731 100755 --- a/tests.sh +++ b/tests.sh @@ -316,7 +316,7 @@ build_python() { else envlist=py\{27,36\}-python fi - tox -e $envlist + python -m tox -e $envlist cd .. } @@ -324,7 +324,7 @@ build_python_version() { internal_build_cpp cd python envlist=$1 - tox -e $envlist + python -m tox -e $envlist cd .. } @@ -467,45 +467,6 @@ use_php_zts() { internal_build_cpp } -build_php5.5() { - use_php 5.5 - - pushd php - rm -rf vendor - composer update - composer test - popd - (cd conformance && make test_php) -} - -build_php5.6() { - use_php 5.6 - pushd php - rm -rf vendor - composer update - composer test - popd - (cd conformance && make test_php) -} - -build_php5.6_mac() { - # Install PHP - curl -s https://php-osx.liip.ch/install.sh | bash -s 5.6 - PHP_FOLDER=`find /usr/local -type d -name "php5-5.6*"` # The folder name may change upon time - test ! -z "$PHP_FOLDER" - export PATH="$PHP_FOLDER/bin:$PATH" - - internal_build_cpp - - # Run pure-PHP tests only. - pushd php - rm -rf vendor - composer update - composer test - popd - (cd conformance && make test_php) -} - build_php7.0() { use_php 7.0 pushd php @@ -747,8 +708,6 @@ build_php8.0_all() { } build_php_all_32() { - build_php5.5 - build_php5.6 build_php7.0 build_php7.1 build_php7.4 @@ -803,8 +762,6 @@ Usage: $0 { cpp | ruby27 | jruby | ruby_all | - php5.5 | - php5.6 | php7.0 | php7.0_c | php_compatibility |